Boost logo

Boost-Commit :

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"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk