$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r58171 - in trunk/libs/spirit: example/karma test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2009-12-05 20:17:46
Author: hkaiser
Date: 2009-12-05 20:17:45 EST (Sat, 05 Dec 2009)
New Revision: 58171
URL: http://svn.boost.org/trac/boost/changeset/58171
Log:
Spirit: added new karma example
Added:
   trunk/libs/spirit/example/karma/simple_columns_directive.cpp   (contents, props changed)
   trunk/libs/spirit/example/karma/simple_columns_directive.hpp   (contents, props changed)
Text files modified: 
   trunk/libs/spirit/example/karma/Jamfile  |     1 +                                       
   trunk/libs/spirit/test/karma/columns.cpp |     4 +++-                                    
   2 files changed, 4 insertions(+), 1 deletions(-)
Modified: trunk/libs/spirit/example/karma/Jamfile
==============================================================================
--- trunk/libs/spirit/example/karma/Jamfile	(original)
+++ trunk/libs/spirit/example/karma/Jamfile	2009-12-05 20:17:45 EST (Sat, 05 Dec 2009)
@@ -29,4 +29,5 @@
 exe karma_reference : reference.cpp ;
 exe karma_reorder_struct : reorder_struct.cpp ;
 exe karma_escaped_string : escaped_string.cpp ;
+exe simple_columns_directive : simple_columns_directive.cpp ;
 
Added: trunk/libs/spirit/example/karma/simple_columns_directive.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/karma/simple_columns_directive.cpp	2009-12-05 20:17:45 EST (Sat, 05 Dec 2009)
@@ -0,0 +1,49 @@
+//  Copyright (c) 2001-2009 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  The purpose of this example is to show how a simple custom generator
+//  directive can be written. We develop a custom generator allowing to wrap 
+//  the generated output after each 5th column.
+//
+//  For more information see: http://boost-spirit.com/home/?page_id=659 
+
+#include <boost/spirit/include/karma_generate_attr.hpp>
+#include <boost/spirit/include/karma_char.hpp>
+#include <boost/spirit/include/karma_operator.hpp>
+#include <boost/spirit/include/karma_numeric.hpp>
+
+#include <string>
+#include "simple_columns_directive.hpp"
+
+namespace karma = boost::spirit::karma;
+
+int main()
+{
+    using custom_generator::columns;
+
+    std::vector<int> v;
+    for (int i = 0; i < 17; ++i)
+        v.push_back(i);
+
+    std::string generated;
+    std::back_insert_iterator<std::string> sink(generated);
+
+    bool result = karma::generate_delimited(
+        sink, columns[*karma::int_], karma::space, v);
+    if (result) 
+    {
+        std::cout << "-------------------------------- \n";
+        std::cout << "Generation succeeded\n";
+        std::cout << "generated output: " << "\n" << generated << "\n";
+        std::cout << "-------------------------------- \n";
+    }
+    else 
+    {
+        std::cout << "-------------------------------- \n";
+        std::cout << "Generation failed\n";
+        std::cout << "-------------------------------- \n";
+    }
+    return 0;
+}
Added: trunk/libs/spirit/example/karma/simple_columns_directive.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/karma/simple_columns_directive.hpp	2009-12-05 20:17:45 EST (Sat, 05 Dec 2009)
@@ -0,0 +1,133 @@
+//  Copyright (c) 2001-2009 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(COLUMNS_DEC_05_2009_0716PM)
+#define COLUMNS_DEC_05_2009_0716PM
+
+#include <boost/spirit/include/karma_generate.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// definition the place holder 
+namespace custom_generator 
+{ 
+    BOOST_SPIRIT_TERMINAL(columns);
+} 
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation the enabler
+namespace boost { namespace spirit 
+{ 
+    // We want custom_generator::columns to be usable as a directive only, 
+    // and only for generator expressions (karma::domain).
+    template <>
+    struct use_directive<karma::domain, custom_generator::tag::columns> 
+      : mpl::true_ {}; 
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+// implementation of the generator
+namespace custom_generator
+{ 
+    // special delimiter wrapping the original one while additionally emitting
+    // the column delimiter after each 5th invocation
+    template <typename Delimiter>
+    struct columns_delimiter 
+    {
+        columns_delimiter(Delimiter const& delim)
+          : delimiter(delim), count(0) {}
+
+        // This function is called during the actual delimiter output 
+        template <typename OutputIterator, typename Context
+          , typename Delimiter_, typename Attribute>
+        bool generate(OutputIterator& sink, Context&, Delimiter_ const&
+          , Attribute const&) const
+        {
+            // first invoke the wrapped delimiter
+            if (!karma::delimit_out(sink, delimiter))
+                return false;
+
+            // now we count the number of invocations and emit the column 
+            // delimiter after each 5th column
+            if ((++count % 5) == 0) 
+                *sink++ = '\n';
+            return true;
+        }
+
+        // Generate a final column delimiter if the last invocation didn't 
+        // emit one
+        template <typename OutputIterator>
+        bool final_delimit_out(OutputIterator& sink) const
+        {
+            if (count % 5)
+                *sink++ = '\n';
+            return true;
+        }
+
+        Delimiter const& delimiter;   // wrapped delimiter
+        mutable unsigned int count;   // invocation counter
+    };
+
+    // That's the actual columns generator
+    template <typename Subject>
+    struct simple_columns_generator
+      : boost::spirit::karma::unary_generator<
+            simple_columns_generator<Subject> >
+    {
+        // Define required output iterator properties
+        typedef typename Subject::properties properties;
+
+        // Define the attribute type exposed by this parser component
+        template <typename Context, typename Iterator>
+        struct attribute 
+          : boost::spirit::traits::attribute_of<Subject, Context, Iterator> 
+        {};
+
+        simple_columns_generator(Subject const& s)
+          : subject(s)
+        {}
+
+        // This function is called during the actual output generation process.
+        // It dispatches to the embedded generator while supplying a new 
+        // delimiter to use, wrapping the outer delimiter.
+        template <typename OutputIterator, typename Context
+          , typename Delimiter, typename Attribute>
+        bool generate(OutputIterator& sink, Context& ctx
+          , Delimiter const& delimiter, Attribute const& attr) const
+        {
+            columns_delimiter<Delimiter> d(delimiter);
+            return subject.generate(sink, ctx, d, attr) && d.final_delimit_out(sink);
+        }
+
+        // This function is called during error handling to create
+        // a human readable string for the error context.
+        template <typename Context>
+        boost::spirit::info what(Context& ctx) const
+        {
+            return boost::spirit::info("columns", subject.what(ctx));
+        }
+
+        Subject subject;
+    };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// instantiation of the generator
+namespace boost { namespace spirit { namespace karma
+{
+    // This is the factory function object invoked in order to create 
+    // an instance of our iter_pos_parser.
+    template <typename Subject, typename Modifiers>
+    struct make_directive<custom_generator::tag::columns, Subject, Modifiers>
+    {
+        typedef custom_generator::simple_columns_generator<Subject> result_type;
+
+        result_type operator()(unused_type, Subject const& s, unused_type) const
+        {
+            return result_type(s);
+        }
+    };
+}}}
+
+#endif
Modified: trunk/libs/spirit/test/karma/columns.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/columns.cpp	(original)
+++ trunk/libs/spirit/test/karma/columns.cpp	2009-12-05 20:17:45 EST (Sat, 05 Dec 2009)
@@ -6,12 +6,14 @@
 #include <boost/config/warning_disable.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
-#include <boost/mpl/print.hpp>
 #include <boost/spirit/include/karma_char.hpp>
 #include <boost/spirit/include/karma_generate.hpp>
 #include <boost/spirit/include/karma_numeric.hpp>
 #include <boost/spirit/include/karma_directive.hpp>
 
+#include <boost/spirit/include/karma_nonterminal.hpp>
+#include <boost/spirit/include/karma_action.hpp>
+
 #include <boost/spirit/include/phoenix_core.hpp>
 
 #include "test.hpp"