Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67315 - in trunk/boost/spirit: home/karma home/karma/action home/karma/detail home/karma/directive home/karma/nonterminal home/karma/operator home/karma/string home/qi/directive home/support home/support/utree include
From: hartmut.kaiser_at_[hidden]
Date: 2010-12-18 22:36:07


Author: hkaiser
Date: 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
New Revision: 67315
URL: http://svn.boost.org/trac/boost/changeset/67315

Log:
Spirit: improving integration of utree in Karma
Added:
   trunk/boost/spirit/home/karma/detail/as_string.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/directive/as_string.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp (contents, props changed)
   trunk/boost/spirit/home/support/handles_container.hpp (contents, props changed)
   trunk/boost/spirit/include/karma_as_string.hpp (contents, props changed)
   trunk/boost/spirit/include/qi_as_string.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/action/action.hpp | 8 +
   trunk/boost/spirit/home/karma/detail/pass_container.hpp | 15 ++
   trunk/boost/spirit/home/karma/directive.hpp | 6 +
   trunk/boost/spirit/home/karma/directive/buffer.hpp | 11 ++
   trunk/boost/spirit/home/karma/directive/center_alignment.hpp | 13 +++
   trunk/boost/spirit/home/karma/directive/columns.hpp | 9 ++
   trunk/boost/spirit/home/karma/directive/delimit.hpp | 12 ++
   trunk/boost/spirit/home/karma/directive/duplicate.hpp | 8 +
   trunk/boost/spirit/home/karma/directive/left_alignment.hpp | 15 +++
   trunk/boost/spirit/home/karma/directive/maxwidth.hpp | 7 +
   trunk/boost/spirit/home/karma/directive/no_delimit.hpp | 8 +
   trunk/boost/spirit/home/karma/directive/omit.hpp | 8 +
   trunk/boost/spirit/home/karma/directive/repeat.hpp | 14 +++
   trunk/boost/spirit/home/karma/directive/right_alignment.hpp | 14 +++
   trunk/boost/spirit/home/karma/directive/upper_lower_case.hpp | 1
   trunk/boost/spirit/home/karma/directive/verbatim.hpp | 7 +
   trunk/boost/spirit/home/karma/nonterminal/grammar.hpp | 24 ++++-
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp | 35 ++++++-
   trunk/boost/spirit/home/karma/operator/alternative.hpp | 12 ++
   trunk/boost/spirit/home/karma/operator/and_predicate.hpp | 7 +
   trunk/boost/spirit/home/karma/operator/kleene.hpp | 11 ++
   trunk/boost/spirit/home/karma/operator/list.hpp | 11 ++
   trunk/boost/spirit/home/karma/operator/not_predicate.hpp | 7 +
   trunk/boost/spirit/home/karma/operator/optional.hpp | 7 +
   trunk/boost/spirit/home/karma/operator/plus.hpp | 12 ++
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 14 +++
   trunk/boost/spirit/home/karma/string/lit.hpp | 20 ++++
   trunk/boost/spirit/home/qi/directive/as_string.hpp | 1
   trunk/boost/spirit/home/support/attributes_fwd.hpp | 17 ++++
   trunk/boost/spirit/home/support/has_semantic_action.hpp | 1
   trunk/boost/spirit/home/support/utree.hpp | 2
   trunk/boost/spirit/home/support/utree/utree.hpp | 14 +-
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 165 +++++++++++++--------------------------
   33 files changed, 374 insertions(+), 142 deletions(-)

Modified: trunk/boost/spirit/home/karma/action/action.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/action/action.hpp (original)
+++ trunk/boost/spirit/home/karma/action/action.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/action_dispatch.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/meta_compiler.hpp>
 #include <boost/spirit/home/karma/generator.hpp>
@@ -119,9 +121,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Action>
     struct has_semantic_action<karma::action<Subject, Action> >
       : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Action, typename Attribute>
+ struct has_semantic_action<karma::action<Subject, Action>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Added: trunk/boost/spirit/home/karma/detail/as_string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/as_string.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,72 @@
+// Copyright (c) 2001-2010 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_AS_STRING_DEC_18_0644PM)
+#define BOOST_SPIRIT_KARMA_AS_STRING_DEC_18_0644PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attributes_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // This file contains the attribute to string conversion utility. The
+ // utility provided also accept spirit's unused_type; all no-ops. Compiler
+ // optimization will easily strip these away.
+ ///////////////////////////////////////////////////////////////////////////
+
+ // This is the default case: the plain attribute values
+ template <typename Attribute, typename Enable/*= void*/>
+ struct attribute_as_string
+ {
+ typedef Attribute const& type;
+
+ static type call(Attribute const& attr)
+ {
+ return attr;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute>
+ typename spirit::result_of::attribute_as_string<Attribute>::type
+ as_string(Attribute const& attr)
+ {
+ return attribute_as_string<Attribute>::call(attr);
+ }
+
+ inline unused_type as_string(unused_type)
+ {
+ return unused;
+ }
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace result_of
+{
+ template <typename Attribute>
+ struct attribute_as_string
+ : traits::attribute_as_string<Attribute>
+ {};
+
+ template <>
+ struct attribute_as_string<unused_type>
+ {
+ typedef unused_type type;
+ };
+
+ template <>
+ struct attribute_as_string<unused_type const>
+ {
+ typedef unused_type type;
+ };
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/pass_container.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/pass_container.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -14,6 +14,7 @@
 
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/detail/hold_any.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/type_traits/is_convertible.hpp>
@@ -107,9 +108,13 @@
             typedef typename traits::attribute_of<
                 Component, context_type>::type attribute_type;
 
+// typedef mpl::and_<
+// traits::is_container<attribute_type>
+// , is_convertible<Attr, attribute_type> > predicate;
+
             typedef mpl::and_<
                 traits::is_container<attribute_type>
- , is_convertible<Attr, attribute_type> > predicate;
+ , traits::handles_container<Component, Attr> > predicate;
 
             return dispatch_attribute_element(component, predicate());
         }
@@ -157,9 +162,13 @@
             typedef typename traits::attribute_of<
                 Component, context_type>::type lhs_attribute;
 
+ typedef mpl::and_<
+ has_same_elements<rhs, lhs_attribute>
+ , traits::handles_container<Component, Attr> > predicate;
+
             // false means everything went ok
- return dispatch_main(component
- , has_same_elements<rhs, lhs_attribute>());
+ return dispatch_main(component, predicate());
+// , has_same_elements<rhs, lhs_attribute>());
         }
 
         F f;

Modified: trunk/boost/spirit/home/karma/directive.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive.hpp (original)
+++ trunk/boost/spirit/home/karma/directive.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -66,4 +66,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 #include <boost/spirit/home/karma/directive/strict_relaxed.hpp>
 
+///////////////////////////////////////////////////////////////////////////////
+// as_string and as_wstring directives
+// as_string[...], as_wstring[...]
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/home/karma/directive/as_string.hpp>
+
 #endif

Added: trunk/boost/spirit/home/karma/directive/as_string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/directive/as_string.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,125 @@
+// Copyright (c) 2001-2010 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(SPIRIT_KARMA_AS_STRING_DEC_18_0510PM)
+#define SPIRIT_KARMA_AS_STRING_DEC_18_0510PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/meta_compiler.hpp>
+#include <boost/spirit/home/karma/generator.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/spirit/home/karma/detail/as_string.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/spirit/home/karma/detail/attributes.hpp>
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
+ struct use_directive<karma::domain, tag::as_string> // enables as_string
+ : mpl::true_ {};
+
+ template <>
+ struct use_directive<karma::domain, tag::as_wstring> // enables as_wstring
+ : mpl::true_ {};
+}}
+
+namespace boost { namespace spirit { namespace karma
+{
+ using spirit::as_string;
+ using spirit::as_string_type;
+ using spirit::as_wstring;
+ using spirit::as_wstring_type;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // as_string_directive allows to hook custom conversions to string into the
+ // output generation process
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Char>
+ struct as_string_directive
+ : unary_generator<as_string_directive<Subject, Char> >
+ {
+ typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
+
+ as_string_directive(Subject const& subject)
+ : subject(subject) {}
+
+ template <typename Context, typename Iterator>
+ struct attribute
+ : traits::attribute_of<subject_type, Context, Iterator>
+ {};
+
+ template <typename OutputIterator, typename Context, typename Delimiter
+ , typename Attribute>
+ bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
+ , Attribute const& attr) const
+ {
+ return subject.generate(sink, ctx, d, traits::as_string(attr)) &&
+ karma::delimit_out(sink, d); // always do post-delimiting
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ return info("as_string", subject.what(context));
+ }
+
+ Subject subject;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Generator generators: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Modifiers>
+ struct make_directive<tag::as_string, Subject, Modifiers>
+ {
+ typedef as_string_directive<Subject, char> result_type;
+
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
+ {
+ return result_type(subject);
+ }
+ };
+
+ template <typename Subject, typename Modifiers>
+ struct make_directive<tag::as_wstring, Subject, Modifiers>
+ {
+ typedef as_string_directive<Subject, wchar_t> result_type;
+
+ result_type operator()(unused_type, Subject const& subject
+ , unused_type) const
+ {
+ return result_type(subject);
+ }
+ };
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Char>
+ struct has_semantic_action<karma::as_string_directive<Subject, Char> >
+ : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute, typename Char>
+ struct handles_container<
+ karma::as_string_directive<Subject, Char>, Attribute>
+ : mpl::false_ {}; // always dereference attribute if used in sequences
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/directive/buffer.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/buffer.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/buffer.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -17,6 +17,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 namespace boost { namespace spirit
@@ -36,8 +38,8 @@
     using spirit::buffer_type;
 
     ///////////////////////////////////////////////////////////////////////////
- // omit_directive consumes the attribute of subject generator without
- // generating anything
+ // buffer_directive buffers all generated output of the embedded generator
+ // and flushes it only if the whole embedded generator succeeds
     ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct buffer_directive : unary_generator<buffer_directive<Subject> >
@@ -112,10 +114,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::buffer_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::buffer_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/center_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/center_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/center_alignment.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
@@ -300,6 +302,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Width>
     struct has_semantic_action<karma::simple_center_alignment<Subject, Width> >
       : unary_has_semantic_action<Subject> {};
@@ -309,6 +312,16 @@
             karma::padding_center_alignment<Subject, Padding, Width> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Width, typename Attribute>
+ struct handles_container<
+ karma::simple_center_alignment<Subject, Width>, typename Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Padding, typename Width, typename Attribute>
+ struct handles_container<
+ karma::padding_center_alignment<Subject, Padding, Width>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/columns.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/columns.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/columns.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -265,9 +267,16 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename T1, typename T2>
     struct has_semantic_action<karma::columns_generator<Subject, T1, T2> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename T1, typename T2, typename Attribute>
+ struct handles_container<
+ karma::columns_generator<Subject, T1, T2>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/delimit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/delimit.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/delimit.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -18,6 +18,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -170,6 +172,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::redelimit_generator<Subject> >
       : unary_has_semantic_action<Subject> {};
@@ -178,6 +181,15 @@
     struct has_semantic_action<karma::delimit_generator<Subject, Delimiter> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::redelimit_generator<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Delimiter, typename Attribute>
+ struct handles_container<
+ karma::delimit_generator<Subject, Delimiter>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/duplicate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/duplicate.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/duplicate.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -18,6 +18,8 @@
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/support/assert_msg.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/fusion/include/cons.hpp>
 #include <boost/fusion/include/vector.hpp>
 #include <boost/fusion/include/at_c.hpp>
@@ -209,9 +211,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::duplicate_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::duplicate_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/left_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/left_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/left_alignment.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -22,6 +22,8 @@
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/vector.hpp>
 #include <boost/lexical_cast.hpp>
@@ -283,6 +285,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Width>
     struct has_semantic_action<karma::simple_left_alignment<Subject, Width> >
       : unary_has_semantic_action<Subject> {};
@@ -292,6 +295,18 @@
             karma::padding_left_alignment<Subject, Padding, Width> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Width, typename Attribute>
+ struct handles_container<
+ karma::simple_left_alignment<Subject, Width>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Padding, typename Width
+ , typename Attribute>
+ struct handles_container<
+ karma::padding_left_alignment<Subject, Padding, Width>
+ , Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/maxwidth.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/maxwidth.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/maxwidth.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
@@ -224,10 +226,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Width, typename Rest>
     struct has_semantic_action<karma::maxwidth_width<Subject, Width, Rest> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Width, typename Rest, typename Attribute>
+ struct handles_container<karma::maxwidth_width<Subject, Width, Rest>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/no_delimit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/no_delimit.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/no_delimit.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -17,6 +17,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 
@@ -96,9 +98,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::no_delimit_generator<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::no_delimit_generator<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/omit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/omit.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/omit.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 namespace boost { namespace spirit
@@ -115,9 +117,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, bool Execute>
     struct has_semantic_action<karma::omit_directive<Subject, Execute> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, bool Execute, typename Attribute>
+ struct handles_container<karma::omit_directive<Subject, Execute>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/repeat.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/repeat.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/repeat.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/karma/operator/kleene.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -349,6 +351,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename LoopIter>
     struct has_semantic_action<karma::repeat_generator<Subject, LoopIter> >
       : unary_has_semantic_action<Subject> {};
@@ -356,6 +359,17 @@
     template <typename Subject, typename LoopIter>
     struct has_semantic_action<karma::strict_repeat_generator<Subject, LoopIter> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename LoopIter, typename Attribute>
+ struct handles_container<
+ karma::repeat_generator<Subject, LoopIter>, Attribute>
+ : mpl::true_ {};
+
+ template <typename Subject, typename LoopIter, typename Attribute>
+ struct handles_container<
+ karma::strict_repeat_generator<Subject, LoopIter>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/right_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/right_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/right_alignment.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
@@ -293,6 +295,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Width>
     struct has_semantic_action<karma::simple_right_alignment<Subject, Width> >
       : unary_has_semantic_action<Subject> {};
@@ -302,6 +305,17 @@
             karma::padding_right_alignment<Subject, Padding, Width> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Width, typename Attribute>
+ struct handles_container<
+ karma::simple_right_alignment<Subject, Width>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Padding, typename Width, typename Attribute>
+ struct handles_container<
+ karma::padding_right_alignment<Subject, Padding, Width>
+ , Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/upper_lower_case.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/upper_lower_case.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/upper_lower_case.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -80,7 +80,6 @@
                 tag::char_code<tag::lower, CharEncoding> const&)
           : Current(current) {}
     };
-
 }}
 
 #endif

Modified: trunk/boost/spirit/home/karma/directive/verbatim.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/verbatim.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/verbatim.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -18,6 +18,8 @@
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
 
@@ -94,10 +96,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::verbatim_generator<Subject> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::verbatim_generator<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/nonterminal/grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/grammar.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/grammar.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -16,19 +16,15 @@
 #include <boost/spirit/home/support/assert_msg.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/nonterminal/rule.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
 #include <boost/spirit/home/karma/reference.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/type_traits/is_same.hpp>
 
 namespace boost { namespace spirit { namespace karma
 {
- template <
- typename OutputIterator
- , typename T1 = unused_type
- , typename T2 = unused_type
- , typename T3 = unused_type
- , typename T4 = unused_type
- >
+ template <typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4>
     struct grammar
       : proto::extends<
             typename proto::terminal<
@@ -115,7 +111,21 @@
 
         std::string name_;
     };
+}}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4, typename Attribute>
+ struct handles_container<
+ karma::grammar<OutputIterator, T1, T2, T3, T4>, Attribute>
+ : detail::nonterminal_handles_container<
+ typename attribute_of<
+ karma::grammar<OutputIterator, T1, T2, T3, T4> >::type
+ , Attribute>
+ {};
 }}}
 
 #endif

Added: trunk/boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,31 @@
+// Copyright (c) 2001-2010 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_NONTERMINAL_FWD_DEC_18_2010_0913PM)
+#define BOOST_SPIRIT_KARMA_NONTERMINAL_FWD_DEC_18_2010_0913PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace karma
+{
+ // forward declaration only
+ template <
+ typename OutputIterator, typename T1 = unused_type
+ , typename T2 = unused_type, typename T3 = unused_type
+ , typename T4 = unused_type>
+ struct rule;
+
+ template <
+ typename OutputIterator, typename T1 = unused_type
+ , typename T2 = unused_type, typename T3 = unused_type
+ , typename T4 = unused_type>
+ struct grammar;
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/rule.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/rule.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -35,6 +35,7 @@
 #include <boost/spirit/home/support/nonterminal/locals.hpp>
 #include <boost/spirit/home/karma/reference.hpp>
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
 #include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp>
 #include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp>
 
@@ -63,13 +64,8 @@
     using spirit::info;
     using spirit::locals;
 
- template <
- typename OutputIterator
- , typename T1 = unused_type
- , typename T2 = unused_type
- , typename T3 = unused_type
- , typename T4 = unused_type
- >
+ template <typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4>
     struct rule
       : proto::extends<
             typename proto::terminal<
@@ -389,6 +385,31 @@
 #endif
 }}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ namespace detail
+ {
+ template <typename RuleAttribute, typename Attribute>
+ struct nonterminal_handles_container
+ : mpl::and_<
+ traits::is_container<RuleAttribute>
+ , is_convertible<Attribute, RuleAttribute> >
+ {};
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4, typename Attribute>
+ struct handles_container<
+ karma::rule<OutputIterator, T1, T2, T3, T4>, Attribute>
+ : detail::nonterminal_handles_container<
+ typename attribute_of<
+ karma::rule<OutputIterator, T1, T2, T3, T4> >::type
+ , Attribute>
+ {};
+}}}
+
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif

Modified: trunk/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/alternative.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -18,6 +18,8 @@
 #include <boost/spirit/home/karma/meta_compiler.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/detail/what_function.hpp>
 #include <boost/fusion/include/any.hpp>
 #include <boost/fusion/include/mpl.hpp>
@@ -176,6 +178,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<karma::alternative<Elements> >
       : nary_has_semantic_action<Elements> {};
@@ -183,6 +186,15 @@
     template <typename Elements>
     struct has_semantic_action<karma::strict_alternative<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<karma::alternative<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
+
+ template <typename Elements, typename Attribute>
+ struct handles_container<karma::strict_alternative<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/and_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/and_predicate.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/and_predicate.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -17,6 +17,8 @@
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 
 namespace boost { namespace spirit
 {
@@ -77,10 +79,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::and_predicate<Subject> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::and_predicate<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/kleene.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/kleene.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/kleene.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,7 @@
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 #include <boost/type_traits/add_const.hpp>
@@ -156,6 +157,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::kleene<Subject> >
       : unary_has_semantic_action<Subject> {};
@@ -163,6 +165,15 @@
     template <typename Subject>
     struct has_semantic_action<karma::strict_kleene<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::kleene<Subject>, Attribute>
+ : mpl::true_ {};
+
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::strict_kleene<Subject>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/list.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/list.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/list.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,7 @@
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 namespace boost { namespace spirit
@@ -189,6 +190,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Left, typename Right>
     struct has_semantic_action<karma::list<Left, Right> >
       : binary_has_semantic_action<Left, Right> {};
@@ -196,6 +198,15 @@
     template <typename Left, typename Right>
     struct has_semantic_action<karma::strict_list<Left, Right> >
       : binary_has_semantic_action<Left, Right> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Left, typename Right, typename Attribute>
+ struct handles_container<karma::list<Left, Right>, Attribute>
+ : mpl::true_ {};
+
+ template <typename Left, typename Right, typename Attribute>
+ struct handles_container<karma::strict_list<Left, Right>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/not_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/not_predicate.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/not_predicate.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -17,6 +17,8 @@
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 
 namespace boost { namespace spirit
 {
@@ -78,10 +80,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::not_predicate<Subject> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::not_predicate<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/optional.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/optional.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/optional.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -18,6 +18,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/optional.hpp>
 #include <boost/type_traits/is_convertible.hpp>
@@ -87,10 +89,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::optional<Subject> >
       : unary_has_semantic_action<Subject> {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::optional<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/plus.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/plus.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/plus.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 #include <boost/type_traits/add_const.hpp>
@@ -169,6 +171,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<karma::plus<Subject> >
       : unary_has_semantic_action<Subject> {};
@@ -176,6 +179,15 @@
     template <typename Subject>
     struct has_semantic_action<karma::strict_plus<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::plus<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::strict_plus<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/sequence.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/sequence.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -23,6 +23,8 @@
 #include <boost/spirit/home/support/algorithm/any_if.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/sequence_base_id.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/fusion/include/vector.hpp>
 #include <boost/fusion/include/as_vector.hpp>
 #include <boost/fusion/include/for_each.hpp>
@@ -363,6 +365,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<karma::sequence<Elements> >
       : nary_has_semantic_action<Elements> {};
@@ -370,6 +373,17 @@
     template <typename Elements>
     struct has_semantic_action<karma::strict_sequence<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<karma::sequence<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute>
+ {};
+
+ template <typename Elements, typename Attribute>
+ struct handles_container<karma::strict_sequence<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute>
+ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/string/lit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/string/lit.hpp (original)
+++ trunk/boost/spirit/home/karma/string/lit.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -15,6 +15,7 @@
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/char_class.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/detail/get_encoding.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/meta_compiler.hpp>
@@ -62,7 +63,6 @@
       , tag::char_code<tag::string, CharEncoding>
       , 1 /*arity*/
> : mpl::true_ {};
-
 }}
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -98,7 +98,7 @@
             return
                 karma::detail::string_generate(sink
                   , traits::extract_from<attribute_type>(attr, context)
- , char_encoding(), Tag()) &&
+ , char_encoding(), Tag()) &&
                 karma::delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -271,7 +271,21 @@
             return result_type(fusion::at_c<0>(term.args));
         }
     };
-
 }}} // namespace boost::spirit::karma
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename CharEncoding, typename Tag, typename Attribute>
+ struct handles_container<karma::any_string<CharEncoding, Tag>, Attribute>
+ : mpl::false_ {};
+
+ template <typename String, typename CharEncoding, typename Tag
+ , bool no_attribute, typename Attribute>
+ struct handles_container<
+ karma::literal_string<String, CharEncoding, Tag, no_attribute>
+ , Attribute>
+ : mpl::false_ {};
+}}}
+
 #endif

Modified: trunk/boost/spirit/home/qi/directive/as_string.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/as_string.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/as_string.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -78,7 +78,6 @@
         info what(Context& context) const
         {
             return info("as_string", subject.what(context));
-
         }
 
         Subject subject;

Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -25,6 +25,9 @@
     template <typename Exposed, typename Attribute>
     struct extract_from;
 
+ template <typename Attribute>
+ struct attribute_as_string;
+
     template <typename Exposed, typename Transformed, typename Domain>
     struct pre_transform;
 
@@ -118,6 +121,15 @@
     );
 
     ///////////////////////////////////////////////////////////////////////////
+ // Karma only
+ template <typename Attribute, typename Enable = void>
+ struct attribute_as_string;
+
+ template <typename Attribute>
+ typename spirit::result_of::attribute_as_string<Attribute>::type
+ as_string(Attribute const& attr);
+
+ ///////////////////////////////////////////////////////////////////////////
     // return the type currently stored in the given variant
     ///////////////////////////////////////////////////////////////////////////
     template <typename T, typename Enable = void>
@@ -148,6 +160,11 @@
     struct is_container;
 
     ///////////////////////////////////////////////////////////////////////////
+ // Karma only
+ template <typename T, typename Attribute, typename Enable = void>
+ struct handles_container;
+
+ ///////////////////////////////////////////////////////////////////////////
     // Qi only
     template <typename Container, typename T, typename Enable = void>
     struct push_back_container;

Added: trunk/boost/spirit/home/support/handles_container.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/handles_container.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,50 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 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_HANDLES_CONTAINER_DEC_18_2010_0920AM)
+#define BOOST_SPIRIT_HANDLES_CONTAINER_DEC_18_2010_0920AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/attributes_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace spirit { namespace traits
+{
+ // Finding out, whether a component handles container attributes
+ // intrinsically (or whether container attributes need to be split up
+ // separately). This customization point is used by karma sequences.
+ template <typename T, typename Attribute, typename Enable>
+ struct handles_container : mpl::false_ {};
+
+ template <typename Subject, typename Attribute>
+ struct unary_handles_container : handles_container<Subject, Attribute> {};
+
+ template <typename Left, typename Right, typename Attribute>
+ struct binary_handles_container
+ : mpl::or_<
+ handles_container<Left, Attribute>
+ , handles_container<Right, Attribute> >
+ {};
+
+ template <typename Elements, typename Attribute>
+ struct nary_handles_container
+ : mpl::not_<
+ is_same<
+ typename mpl::find_if<
+ Elements, handles_container<mpl::_, Attribute>
+ >::type
+ , typename mpl::end<Elements>::type> >
+ {};
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/support/has_semantic_action.hpp
==============================================================================
--- trunk/boost/spirit/home/support/has_semantic_action.hpp (original)
+++ trunk/boost/spirit/home/support/has_semantic_action.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -42,7 +42,6 @@
               , typename mpl::end<Elements>::type
>
> {};
-
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/support/utree.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree.hpp (original)
+++ trunk/boost/spirit/home/support/utree.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -13,7 +13,7 @@
 
 #include <boost/spirit/home/support/utree/utree.hpp>
 #include <boost/spirit/home/support/utree/operators.hpp>
-#include <boost/spirit/home/support/utree/utree_traits.hpp>
 #include <boost/spirit/home/support/utree/detail/utree_detail2.hpp>
+#include <boost/spirit/home/support/utree/utree_traits.hpp>
 
 #endif

Modified: trunk/boost/spirit/home/support/utree/utree.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -127,31 +127,31 @@
     typedef basic_string<
         boost::iterator_range<char const*>,
         utree_type::binary_type>
- binary_range;
+ binary_range;
     typedef basic_string<
         std::string,
         utree_type::binary_type>
- binary_string;
+ binary_string;
 
     // UTF-8 string
     typedef basic_string<
         boost::iterator_range<char const*>,
         utree_type::string_type>
- utf8_string_range;
+ utf8_string_range;
     typedef basic_string<
         std::string,
         utree_type::string_type>
- utf8_string_type;
+ utf8_string_type;
 
     // UTF-8 symbol
     typedef basic_string<
         boost::iterator_range<char const*>,
         utree_type::symbol_type>
- utf8_symbol_range;
+ utf8_symbol_range;
     typedef basic_string<
         std::string,
         utree_type::symbol_type>
- utf8_symbol;
+ utf8_symbol;
     //]
 
     ///////////////////////////////////////////////////////////////////////////
@@ -454,7 +454,7 @@
     //]
 
     //[utree_scope
- class scope: public boost::iterator_range<utree*> {
+ class scope : public boost::iterator_range<utree*> {
       public:
         scope(utree* first = 0,
               utree* last = 0,

Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -13,6 +13,7 @@
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/support/utree.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
 
 #include <string>
 
@@ -73,10 +74,10 @@
     {
         static void call(Attribute const& val, utree& attr, mpl::false_)
         {
- if (attr.empty())
- attr = val;
- else
- push_back(attr, val);
+ if (attr.empty())
+ attr = val;
+ else
+ push_back(attr, val);
         }
 
         static void call(Attribute const& val, utree& attr, mpl::true_)
@@ -136,6 +137,19 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // Karma only: convert utree node to string
+ template <>
+ struct attribute_as_string<utree>
+ {
+ typedef utf8_string_range type;
+
+ static type call(utree const& attr)
+ {
+ return boost::get<utf8_string_range>(attr);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // push_back support for utree allows concatenation of strings
     // (utree strings are immutable)
     template <typename T>
@@ -175,6 +189,44 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // force utree list attribute in a sequence to be dereferenced if a rule
+ // or a grammar takes an utree
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4>
+ struct handles_container<
+ karma::rule<OutputIterator, T1, T2, T3, T4>, utree>
+ : mpl::false_
+ {};
+
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
+ , typename T4>
+ struct handles_container<
+ karma::grammar<OutputIterator, T1, T2, T3, T4>, utree>
+ : mpl::false_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // the specialization below tells Spirit how to handle utree if it is used
+ // with an optional component
+ template <>
+ struct optional_attribute<utree>
+ {
+ typedef utree const& type;
+
+ static type call(utree const& val)
+ {
+ return val;
+ }
+
+ static bool is_valid(utree const& val)
+ {
+ return val.which() != utree_type::nil_type;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // the specialization below tells Spirit to handle utree as if it
     // where a 'real' variant (in the context of karma)
     template <>
@@ -609,111 +661,6 @@
             return std::string(r.begin(), r.end());
         }
     };
-
-// ///////////////////////////////////////////////////////////////////////////
-// // generic iterator for arbitrary utree node types
-// template <typename Value>
-// class utree_node_iterator
-// : public boost::iterator_facade<
-// utree_node_iterator<Value>
-// , Value
-// , boost::bidirectional_traversal_tag>
-// {
-// public:
-// // utree_node_iterator() : node(0), prev(0), node_iter() {}
-// utree_node_iterator(Value& val)
-// : node(&val), prev(0)
-// {
-// if (node->which() == utree_type::list_type)
-// node_iter = node->begin();
-// }
-// utree_node_iterator(Value& val, int)
-// : node(0), prev(0)
-// {
-// if (val.which() == utree_type::list_type)
-// node_iter = val.end();
-// }
-//
-// private:
-// friend class boost::iterator_core_access;
-// friend class boost::spirit::utree;
-//
-// void increment()
-// {
-// if (node->which() == utree_type::list_type)
-// {
-// ++node_iter;
-// }
-// else
-// {
-// prev = node;
-// node = 0;
-// }
-// }
-//
-// void decrement()
-// {
-// if (node->which() == utree_type::list_type)
-// {
-// --node_iter;
-// }
-// else
-// {
-// node = prev;
-// prev = 0;
-// }
-// }
-//
-// bool equal(utree_node_iterator const& other) const
-// {
-// if (0 != node && node->which() == utree_type::list_type)
-// {
-// return node_iter == other.node_iter;
-// }
-// return node == other.node;
-// }
-//
-// typename utree_node_iterator::reference dereference() const
-// {
-// if (node->which() == utree_type::list_type)
-// {
-// return *node_iter;
-// }
-// return *node;
-// }
-//
-// Value* node;
-// Value* prev;
-// spirit::detail::list::node_iterator<Value> node_iter;
-// };
-//
-// template <>
-// struct container_iterator<utree const>
-// {
-// typedef utree_node_iterator<utree const> type;
-// };
-//
-// template <>
-// struct begin_container<utree const>
-// {
-// typedef container_iterator<utree const>::type iterator_type;
-//
-// static iterator_type call(utree const& c)
-// {
-// return iterator_type(c);
-// }
-// };
-//
-// template <>
-// struct end_container<utree const>
-// {
-// typedef container_iterator<utree const>::type iterator_type;
-//
-// static iterator_type call(utree const& c)
-// {
-// return iterator_type(c, 0);
-// }
-// };
 }}}
 
 #endif

Added: trunk/boost/spirit/include/karma_as_string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/include/karma_as_string.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
+#define BOOST_SPIRIT_INCLUDE_KARMA_AS_STRING
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/directive/as_string.hpp>
+
+#endif

Added: trunk/boost/spirit/include/qi_as_string.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/include/qi_as_string.hpp 2010-12-18 22:36:02 EST (Sat, 18 Dec 2010)
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+ Copyright (c) 2001-2010 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ 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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_INCLUDE_QI_AS_STRING
+#define BOOST_SPIRIT_INCLUDE_QI_AS_STRING
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/directive/as_string.hpp>
+
+#endif


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