Boost logo

Boost-Commit :

From: hartmut.kaiser_at_[hidden]
Date: 2008-08-26 20:15:37


Author: hkaiser
Date: 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
New Revision: 48398
URL: http://svn.boost.org/trac/boost/changeset/48398

Log:
Spirit.Karma: Added confix generator
Added:
   trunk/boost/spirit/home/karma/auxiliary/confix.hpp (contents, props changed)
   trunk/boost/spirit/home/support/auxiliary/confix.hpp (contents, props changed)
   trunk/libs/spirit/test/karma/confix.cpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/action/meta_grammar.hpp | 2
   trunk/boost/spirit/home/karma/auxiliary.hpp | 1
   trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp | 16 ++++++++++++
   trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp | 6 ++--
   trunk/boost/spirit/home/karma/numeric/real.hpp | 5 ++-
   trunk/boost/spirit/home/support/placeholders.hpp | 8 +++---
   trunk/libs/spirit/test/karma/test.hpp | 50 ++++++++++++++++++++--------------------
   7 files changed, 52 insertions(+), 36 deletions(-)

Modified: trunk/boost/spirit/home/karma/action/meta_grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/action/meta_grammar.hpp (original)
+++ trunk/boost/spirit/home/karma/action/meta_grammar.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -20,7 +20,7 @@
     // forwards
     ///////////////////////////////////////////////////////////////////////////
     struct action;
-
+
     struct main_meta_grammar;
 
     template <typename Expr, typename Enable>

Modified: trunk/boost/spirit/home/karma/auxiliary.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/auxiliary.hpp (original)
+++ trunk/boost/spirit/home/karma/auxiliary.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -7,6 +7,7 @@
 #define BOOST_SPIRIT_KARMA_AUXILIARY_MAR_26_2007_1225PM
 
 #include <boost/spirit/home/karma/auxiliary/none.hpp>
+#include <boost/spirit/home/karma/auxiliary/confix.hpp>
 #include <boost/spirit/home/karma/auxiliary/eps.hpp>
 #include <boost/spirit/home/karma/auxiliary/eol.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>

Added: trunk/boost/spirit/home/karma/auxiliary/confix.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/auxiliary/confix.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -0,0 +1,121 @@
+// Copyright (c) 2001-2008 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(BOOST_SPIRIT_KARMA_CONFIX_AUG_19_2008_1041AM)
+#define BOOST_SPIRIT_KARMA_CONFIX_AUG_19_2008_1041AM
+
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/delimit.hpp>
+#include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_of.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/auxiliary/confix.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // the director for a confix() generated generator
+ struct confix_director
+ {
+ template <typename Component, typename Context, typename Unused>
+ struct attribute
+ {
+ typedef typename
+ result_of::subject<Component>::type
+ subject_type;
+
+ typedef typename
+ traits::attribute_of<karma::domain, subject_type, Context>::type
+ type;
+ };
+
+ private:
+ ///////////////////////////////////////////////////////////////////////
+ template <typename OutputIterator, typename Context,
+ typename Delimiter, typename Expr>
+ static void
+ generate_helper(OutputIterator& sink, Context& ctx, Delimiter const& d,
+ Expr const& e)
+ {
+ BOOST_MPL_ASSERT_MSG(
+ (spirit::traits::is_component<karma::domain, Expr>::value),
+ expression_is_not_convertible_to_a_generator, (Context, Expr));
+
+ typedef
+ typename result_of::as_component<karma::domain, Expr>::type
+ expr;
+
+ expr eg = spirit::as_component(karma::domain(), e);
+ typedef typename expr::director director;
+ director::generate(eg, sink, ctx, d, unused);
+ }
+
+ template <typename Context, typename Expr>
+ static std::string what_helper(Expr const& e, Context& ctx)
+ {
+ typedef
+ typename result_of::as_component<karma::domain, Expr>::type
+ expr;
+
+ expr eg = spirit::as_component(karma::domain(), e);
+ typedef typename expr::director director;
+ return director::what(eg, ctx);
+ }
+
+ public:
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Component, typename OutputIterator,
+ typename Context, typename Delimiter, typename Parameter>
+ static bool
+ generate(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& d, Parameter const& param)
+ {
+ // generate the prefix
+ generate_helper(sink, ctx, d,
+ spirit::detail::confix_extractor::prefix(
+ proto::arg_c<0>(spirit::argument1(component))));
+
+ // generate the embedded items
+ typedef typename
+ spirit::result_of::subject<Component>::type::director
+ director;
+ bool result = director::generate(spirit::subject(component), sink,
+ ctx, d, param);
+
+ // append the suffix
+ generate_helper(sink, ctx, d,
+ spirit::detail::confix_extractor::suffix(
+ proto::arg_c<0>(spirit::argument1(component))));
+
+ return result;
+ }
+
+ template <typename Component, typename Context>
+ static std::string what(Component const& component, Context const& ctx)
+ {
+ std::string result = "confix(";
+
+ result += what_helper(spirit::detail::confix_extractor::prefix(
+ proto::arg_c<0>(spirit::argument1(component))), ctx);
+ result += ", ";
+
+ result += what_helper(spirit::detail::confix_extractor::suffix(
+ proto::arg_c<0>(spirit::argument1(component))), ctx);
+ result += ")[";
+
+ typedef typename
+ spirit::result_of::subject<Component>::type::director
+ director;
+ result += director::what(spirit::subject(component), ctx);
+ result += "]";
+
+ return result;
+ }
+ };
+
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp (original)
+++ trunk/boost/spirit/home/karma/auxiliary/meta_grammar.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -22,13 +22,16 @@
     ///////////////////////////////////////////////////////////////////////////
     // forwards
     ///////////////////////////////////////////////////////////////////////////
+ struct main_meta_grammar;
+
     struct none;
     struct eps_generator;
     struct eol_generator;
     struct semantic_predicate;
     struct lazy_generator;
     struct functor_director;
-
+ struct confix_director;
+
     template <typename Expr, typename Enable>
     struct is_valid_expr;
 
@@ -42,20 +45,31 @@
     // none, and lazy
     struct auxiliary_meta_grammar
       : proto::or_<
+ // none
             meta_grammar::empty_terminal_rule<
                 karma::domain, tag::none, none>,
+ // eps
             meta_grammar::empty_terminal_rule<
                 karma::domain, tag::eps, eps_generator>,
+ // eol
             meta_grammar::empty_terminal_rule<
                 karma::domain, tag::eol, eol_generator>,
+ // eps(...)
             meta_grammar::function1_rule<
                 karma::domain, tag::eps, semantic_predicate>,
+ // lazy(...)
             meta_grammar::function1_rule<
                 karma::domain, tag::lazy, lazy_generator>,
+ // functor generators
             meta_grammar::terminal_rule<
                 karma::domain,
                 functor_holder<proto::_, proto::_>,
                 functor_director
+ >,
+ // confix("...", "...")[...]
+ meta_grammar::subscript_rule<
+ karma::domain, tag::confix<proto::_, proto::_>,
+ confix_director, main_meta_grammar
>
>
     {

Modified: trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/detail/center_alignment_generate.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -35,17 +35,17 @@
         BOOST_MPL_ASSERT_MSG(
             (spirit::traits::is_component<karma::domain, Padding>::value),
             padding_is_not_convertible_to_a_generator, (Context, Padding));
-
+
         typedef
             typename result_of::as_component<karma::domain, Embedded>::type
         embedded;
         typedef
             typename result_of::as_component<karma::domain, Padding>::type
         padding;
-
+
         // wrap the given output iterator to allow left padding
         detail::enable_buffering<OutputIterator> buffering(sink, width);
-
+
         // first generate the embedded output
         embedded ec = spirit::as_component(karma::domain(), e);
         typedef typename embedded::director director;

Modified: trunk/boost/spirit/home/karma/numeric/real.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/real.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/real.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -49,8 +49,9 @@
         generate(Component const& component, OutputIterator& sink,
             Context& /*ctx*/, Delimiter const& d, Parameter const& param)
         {
- RealPolicies const& p = detail::real_policy<RealPolicies>::get(
- fusion::at_c<0>(component.elements));
+ RealPolicies const& p =
+ detail::real_policy<RealPolicies>::get(spirit::subject(component));
+
             bool result = real_inserter<T, RealPolicies, Tag>::
                 call(sink, param, p);
 

Added: trunk/boost/spirit/home/support/auxiliary/confix.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/auxiliary/confix.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -0,0 +1,87 @@
+// Copyright (c) 2001-2008 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(BOOST_SPIRIT_SUPPORT_CONFIX_AUG_19_2008_1103AM)
+#define BOOST_SPIRIT_SUPPORT_CONFIX_AUG_19_2008_1103AM
+
+#include <boost/spirit/home/support/placeholders.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace tag
+{
+ // This is the tag returned by the confix() function
+ template <typename Prefix, typename Suffix>
+ struct confix
+ {
+ Prefix prefix;
+ Suffix suffix;
+ };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Prefix, typename Suffix = Prefix>
+ struct confix_spec
+ : proto::terminal<tag::confix<Prefix, Suffix> >::type
+ {
+ private:
+ typedef typename
+ proto::terminal<tag::confix<Prefix, Suffix> >::type
+ base_type;
+
+ base_type make_tag(Prefix const& prefix, Suffix const& suffix) const
+ {
+ base_type xpr = {{prefix, suffix}};
+ return xpr;
+ }
+
+ public:
+ confix_spec(Prefix const& prefix, Suffix const& suffix)
+ : base_type(make_tag(prefix, suffix))
+ {}
+ };
+
+ namespace detail
+ {
+ struct confix_extractor
+ {
+ template <typename Prefix, typename Suffix>
+ static Prefix const& prefix(tag::confix<Prefix, Suffix> const& c)
+ { return c.prefix; }
+
+ template <typename Prefix, typename Suffix>
+ static Suffix const& suffix(tag::confix<Prefix, Suffix> const& c)
+ { return c.suffix; }
+ };
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // construct a confix component
+ ///////////////////////////////////////////////////////////////////////////
+ inline confix_spec<char const*>
+ confix(char const* prefix, char const* suffix)
+ {
+ return confix_spec<char const*>(prefix, suffix);
+ }
+
+ inline confix_spec<wchar_t const*>
+ confix(wchar_t const* prefix, wchar_t const* suffix)
+ {
+ return confix_spec<wchar_t const*>(prefix, suffix);
+ }
+
+ template <typename Prefix, typename Suffix>
+ inline confix_spec<Prefix, Suffix>
+ confix(Prefix const& prefix, Suffix const& suffix)
+ {
+ return confix_spec<Prefix, Suffix>(prefix, suffix);
+ }
+
+}}
+
+#endif

Modified: trunk/boost/spirit/home/support/placeholders.hpp
==============================================================================
--- trunk/boost/spirit/home/support/placeholders.hpp (original)
+++ trunk/boost/spirit/home/support/placeholders.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -30,7 +30,7 @@
         struct bin {};
         struct oct {};
         struct hex {};
-
+
         struct byte {};
         struct word {};
         struct dword {};
@@ -44,7 +44,7 @@
         struct little_qword {};
 #endif
         struct pad {};
-
+
         struct ushort {};
         struct ulong {};
         struct uint {};
@@ -72,10 +72,10 @@
         struct lazy {};
         struct omit {};
         struct raw {};
-
+
         struct stream {};
         struct wstream {};
-
+
         struct token {};
     }
 

Added: trunk/libs/spirit/test/karma/confix.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/karma/confix.cpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -0,0 +1,83 @@
+// Copyright (c) 2001-2008 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)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/karma_auxiliary.hpp>
+#include <boost/spirit/include/karma_char.hpp>
+#include <boost/spirit/include/karma_string.hpp>
+#include <boost/spirit/include/karma_generate.hpp>
+
+#include <iostream>
+#include "test.hpp"
+
+namespace html
+{
+ ///////////////////////////////////////////////////////////////////////////////
+ // define a HTML tag helper generator
+ template <typename Char, typename Traits, typename Allocator>
+ inline boost::spirit::confix_spec<std::basic_string<Char, Traits, Allocator> >
+ tag (std::basic_string<Char, Traits, Allocator> const& tagname)
+ {
+ typedef std::basic_string<Char, Traits, Allocator> string_type;
+ return boost::spirit::confix_spec<string_type>(
+ string_type("<") + tagname + ">", string_type("</") + tagname + ">");
+ }
+
+ inline boost::spirit::confix_spec<std::string>
+ tag (char const* tagname)
+ {
+ return tag(std::string(tagname));
+ }
+
+ typedef boost::spirit::confix_spec<std::string> html_tag_type;
+
+ html_tag_type const ol = tag("ol");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ using namespace spirit_test;
+ using namespace boost::spirit;
+ using namespace boost::spirit::ascii;
+
+ {
+ BOOST_TEST((test("<tag>a</tag>",
+ confix("<tag>", "</tag>")[char_('a')])));
+ BOOST_TEST((test("// some C++ comment\n",
+ confix(lit("//"), eol)[" some C++ comment"])));
+ BOOST_TEST((test("<ol>some text</ol>", html::ol["some text"])));
+ }
+
+ {
+ BOOST_TEST((test(L"<tag>a</tag>",
+ confix(L"<tag>", L"</tag>")[wchar(L'a')])));
+ BOOST_TEST((test(L"// some C++ comment\n",
+ confix(wlit(L"//"), eol)[L" some C++ comment"])));
+ BOOST_TEST((test(L"<ol>some text</ol>", html::ol[L"some text"])));
+ }
+
+ {
+ BOOST_TEST((test_delimited("<tag> a </tag> ",
+ confix("<tag>", "</tag>")[char_('a')], space)));
+ BOOST_TEST((test_delimited("// some C++ comment \n ",
+ confix(lit("//"), eol)["some C++ comment"], space)));
+ BOOST_TEST((test_delimited("<ol> some text </ol> ",
+ html::ol["some text"], space)));
+ }
+
+ {
+ BOOST_TEST((test_delimited(L"<tag> a </tag> ",
+ confix(L"<tag>", L"</tag>")[wchar(L'a')], space)));
+ BOOST_TEST((test_delimited(L"// some C++ comment \n ",
+ confix(wlit(L"//"), eol)[L"some C++ comment"], space)));
+ BOOST_TEST((test_delimited(L"<ol> some text </ol> ",
+ html::ol[L"some text"], space)));
+ }
+
+ return boost::report_errors();
+}

Modified: trunk/libs/spirit/test/karma/test.hpp
==============================================================================
--- trunk/libs/spirit/test/karma/test.hpp (original)
+++ trunk/libs/spirit/test/karma/test.hpp 2008-08-26 20:15:36 EDT (Tue, 26 Aug 2008)
@@ -49,14 +49,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
-
+
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g);
-
+
         return result && generated == expected;
     }
 
@@ -65,14 +65,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g);
-
+
         return result && generated == expected;
     }
 
@@ -83,14 +83,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g, parameter);
-
+
         return result && generated == expected;
     }
 
@@ -100,14 +100,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g, parameter);
-
+
         return result && generated == expected;
     }
 
@@ -118,14 +118,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated), g, d);
-
+
         return result && generated == expected;
     }
 
@@ -135,14 +135,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated), g, d);
-
+
         return result && generated == expected;
     }
 
@@ -154,7 +154,7 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
@@ -162,7 +162,7 @@
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated),
             g, parameter, d);
-
+
         return result && generated == expected;
     }
 
@@ -173,7 +173,7 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<Char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
@@ -181,7 +181,7 @@
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated),
             g, parameter, d);
-
+
         return result && generated == expected;
     }
 
@@ -193,14 +193,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g);
-
+
         return result && !std::memcmp(generated.c_str(), expected, size);
     }
 
@@ -212,14 +212,14 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
 
         string_type generated;
         bool result = karma::generate(std::back_inserter(generated), g, parameter);
-
+
         return result && !std::memcmp(generated.c_str(), expected, size);
     }
 
@@ -231,7 +231,7 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
@@ -239,7 +239,7 @@
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated),
             g, d);
-
+
         return result && !std::memcmp(generated.c_str(), expected, size);
     }
 
@@ -251,7 +251,7 @@
     {
         namespace karma = boost::spirit::karma;
         typedef std::basic_string<char> string_type;
-
+
         // we don't care about the result of the "what" function.
         // we only care that all generators have it:
         karma::what(g);
@@ -259,7 +259,7 @@
         string_type generated;
         bool result = karma::generate_delimited(std::back_inserter(generated),
             g, parameter, d);
-
+
         return result && !std::memcmp(generated.c_str(), expected, size);
     }
 


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