Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67447 - in trunk: boost/spirit/home/karma boost/spirit/home/karma/action boost/spirit/home/karma/detail boost/spirit/home/karma/directive boost/spirit/home/karma/nonterminal boost/spirit/home/qi boost/spirit/home/qi/action boost/spirit/home/qi/detail boost/spirit/home/qi/directive boost/spirit/home/qi/nonterminal boost/spirit/home/qi/operator boost/spirit/home/qi/string boost/spirit/home/support boost/spirit/home/support/utree boost/spirit/home/support/utree/detail libs/spirit/test/karma libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2010-12-25 16:14:01


Author: hkaiser
Date: 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
New Revision: 67447
URL: http://svn.boost.org/trac/boost/changeset/67447

Log:
Spirit: utree integration, initial implementation complete
Added:
   trunk/boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/action/action.hpp | 2
   trunk/boost/spirit/home/karma/detail/pass_container.hpp | 1
   trunk/boost/spirit/home/karma/directive/as.hpp | 2
   trunk/boost/spirit/home/karma/nonterminal/grammar.hpp | 3
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp | 3
   trunk/boost/spirit/home/karma/reference.hpp | 10 +
   trunk/boost/spirit/home/qi/action/action.hpp | 6
   trunk/boost/spirit/home/qi/detail/pass_container.hpp | 19 +
   trunk/boost/spirit/home/qi/directive/as.hpp | 7
   trunk/boost/spirit/home/qi/directive/hold.hpp | 7
   trunk/boost/spirit/home/qi/directive/lexeme.hpp | 7
   trunk/boost/spirit/home/qi/directive/matches.hpp | 7
   trunk/boost/spirit/home/qi/directive/no_skip.hpp | 8
   trunk/boost/spirit/home/qi/directive/omit.hpp | 7
   trunk/boost/spirit/home/qi/directive/raw.hpp | 7
   trunk/boost/spirit/home/qi/directive/repeat.hpp | 8
   trunk/boost/spirit/home/qi/directive/skip.hpp | 12 +
   trunk/boost/spirit/home/qi/nonterminal/grammar.hpp | 22 +
   trunk/boost/spirit/home/qi/nonterminal/rule.hpp | 21 +
   trunk/boost/spirit/home/qi/operator/alternative.hpp | 8
   trunk/boost/spirit/home/qi/operator/and_predicate.hpp | 8
   trunk/boost/spirit/home/qi/operator/difference.hpp | 8
   trunk/boost/spirit/home/qi/operator/expect.hpp | 8
   trunk/boost/spirit/home/qi/operator/kleene.hpp | 8
   trunk/boost/spirit/home/qi/operator/list.hpp | 8
   trunk/boost/spirit/home/qi/operator/not_predicate.hpp | 8
   trunk/boost/spirit/home/qi/operator/optional.hpp | 8
   trunk/boost/spirit/home/qi/operator/permutation.hpp | 9
   trunk/boost/spirit/home/qi/operator/plus.hpp | 8
   trunk/boost/spirit/home/qi/operator/sequence.hpp | 6
   trunk/boost/spirit/home/qi/operator/sequence_base.hpp | 2
   trunk/boost/spirit/home/qi/operator/sequential_or.hpp | 7
   trunk/boost/spirit/home/qi/reference.hpp | 11 +
   trunk/boost/spirit/home/qi/string/lit.hpp | 14 +
   trunk/boost/spirit/home/support/attributes.hpp | 9
   trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 5
   trunk/boost/spirit/home/support/utree/utree.hpp | 2
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 387 +++++++++++++++++++++++++++------------
   trunk/libs/spirit/test/karma/utree.cpp | 71 ++++++
   trunk/libs/spirit/test/qi/utree.cpp | 51 ++++-
   40 files changed, 639 insertions(+), 166 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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -128,7 +128,7 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Action, typename Attribute>
- struct has_semantic_action<karma::action<Subject, Action>, Attribute>
+ struct handles_container<karma::action<Subject, Action>, Attribute>
       : unary_handles_container<Subject, Attribute> {};
 }}}
 

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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -168,7 +168,6 @@
 
             // false means everything went ok
             return dispatch_main(component, predicate());
-// , has_same_elements<rhs, lhs_attribute>());
         }
 
         F f;

Modified: trunk/boost/spirit/home/karma/directive/as.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/as.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/as.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -145,7 +145,7 @@
       : unary_has_semantic_action<Subject> {};
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Subject, typename Attribute, typename T>
+ template <typename Subject, typename T, typename Attribute>
     struct handles_container<karma::as_directive<Subject, T>, Attribute>
       : mpl::false_ {}; // always dereference attribute if used in sequences
 }}}

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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -23,7 +23,8 @@
 
 namespace boost { namespace spirit { namespace karma
 {
- template <typename OutputIterator, typename T1, typename T2, typename T3
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
       , typename T4>
     struct grammar
       : proto::extends<

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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -64,7 +64,8 @@
     using spirit::info;
     using spirit::locals;
 
- template <typename OutputIterator, typename T1, typename T2, typename T3
+ template <
+ typename OutputIterator, typename T1, typename T2, typename T3
       , typename T4>
     struct rule
       : proto::extends<

Modified: trunk/boost/spirit/home/karma/reference.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/reference.hpp (original)
+++ trunk/boost/spirit/home/karma/reference.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -14,6 +14,8 @@
 #include <boost/spirit/home/karma/meta_compiler.hpp>
 #include <boost/spirit/home/karma/generator.hpp>
 #include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/type_traits/remove_const.hpp>
 #include <boost/ref.hpp>
 
 namespace boost { namespace spirit { namespace karma
@@ -72,7 +74,15 @@
 
         boost::reference_wrapper<Subject> ref;
     };
+}}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<karma::reference<Subject>, Attribute>
+ : handles_container<typename remove_const<Subject>::type, Attribute>
+ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/action/action.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/action/action.hpp (original)
+++ trunk/boost/spirit/home/qi/action/action.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -19,6 +19,7 @@
 #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/handles_container.hpp>
 
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/if.hpp>
@@ -126,10 +127,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename Action>
     struct has_semantic_action<qi::action<Subject, Action> >
       : mpl::true_ {};
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Action, typename Attribute>
+ struct handles_container<qi::action<Subject, Action>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/pass_container.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/pass_container.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -14,6 +14,7 @@
 
 #include <boost/spirit/home/qi/detail/attributes.hpp>
 #include <boost/spirit/home/support/container.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/type_traits/is_base_of.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/mpl/bool.hpp>
@@ -99,10 +100,12 @@
         template <typename Component>
         bool dispatch_attribute(Component const& component, mpl::true_) const
         {
- typedef traits::is_container<
- typename traits::attribute_of<
- Component, context_type, iterator_type
- >::type
+ typedef typename traits::attribute_of<
+ Component, context_type, iterator_type>::type attribute_type;
+
+ typedef mpl::and_<
+ traits::is_container<attribute_type>
+ , traits::handles_container<Component, Attr>
> predicate;
 
             return dispatch_attribute_element(component, predicate());
@@ -153,8 +156,12 @@
                 Component, context_type, iterator_type>::type
             rhs_attribute;
 
- return dispatch_main(component
- , has_same_elements<lhs, rhs_attribute>());
+ typedef mpl::and_<
+ has_same_elements<lhs, rhs_attribute>
+ , traits::handles_container<Component, Attr>
+ > predicate;
+
+ return dispatch_main(component, predicate());
         }
 
         F f;

Modified: trunk/boost/spirit/home/qi/directive/as.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/as.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/as.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -22,6 +22,7 @@
 #include <boost/spirit/home/support/common_terminals.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/range/iterator_range.hpp>
 #include <string>
 
@@ -140,9 +141,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename T>
     struct has_semantic_action<qi::as_directive<Subject, T> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename T, typename Attribute>
+ struct handles_container<qi::as_directive<Subject, T>, Attribute>
+ : mpl::false_ {}; // always dereference attribute if used in sequences
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/hold.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/hold.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/hold.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -19,6 +19,7 @@
 #include <boost/spirit/home/support/common_terminals.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>
 
 namespace boost { namespace spirit
 {
@@ -90,9 +91,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::hold_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::hold_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/lexeme.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/lexeme.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/lexeme.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -19,6 +19,7 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
 #include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 
 namespace boost { namespace spirit
 {
@@ -87,9 +88,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::lexeme_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::lexeme_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/matches.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/matches.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/matches.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -18,6 +18,7 @@
 #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>
 
 namespace boost { namespace spirit
 {
@@ -89,9 +90,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::matches_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::matches_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/no_skip.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/no_skip.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/no_skip.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -20,6 +20,8 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/support/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
 {
@@ -88,9 +90,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::no_skip_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::no_skip_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/omit.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/omit.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/omit.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -18,6 +18,7 @@
 #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>
 
 namespace boost { namespace spirit
 {
@@ -88,9 +89,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::omit_directive<Subject> >
       : mpl::false_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::omit_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/raw.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/raw.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/raw.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -20,6 +20,7 @@
 #include <boost/spirit/home/support/common_terminals.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/range/iterator_range.hpp>
 
 namespace boost { namespace spirit
@@ -92,9 +93,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::raw_directive<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::raw_directive<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/repeat.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/repeat.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/repeat.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/qi/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>
 #include <boost/fusion/include/at.hpp>
 #include <boost/foreach.hpp>
 #include <vector>
@@ -320,9 +322,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject, typename LoopIter>
     struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename LoopIter, typename Attribute>
+ struct handles_container<qi::repeat_parser<Subject, LoopIter>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/directive/skip.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/skip.hpp (original)
+++ trunk/boost/spirit/home/qi/directive/skip.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -22,6 +22,8 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/qi/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>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/vector.hpp>
 
@@ -160,6 +162,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::reskip_parser<Subject> >
       : unary_has_semantic_action<Subject> {};
@@ -167,6 +170,15 @@
     template <typename Subject, typename Skipper>
     struct has_semantic_action<qi::skip_parser<Subject, Skipper> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::reskip_parser<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
+
+ template <typename Subject, typename Skipper, typename Attribute>
+ struct handles_container<qi::skip_parser<Subject, Skipper>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/nonterminal/grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/grammar.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/grammar.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -16,6 +16,7 @@
 #include <boost/spirit/home/support/assert_msg.hpp>
 #include <boost/spirit/home/qi/domain.hpp>
 #include <boost/spirit/home/qi/nonterminal/rule.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
 #include <boost/spirit/home/qi/reference.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/type_traits/is_same.hpp>
@@ -23,12 +24,8 @@
 namespace boost { namespace spirit { namespace qi
 {
     template <
- typename Iterator
- , typename T1 = unused_type
- , typename T2 = unused_type
- , typename T3 = unused_type
- , typename T4 = unused_type
- >
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4>
     struct grammar
       : proto::extends<
             typename proto::terminal<
@@ -116,4 +113,17 @@
     };
 }}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4, typename Attribute>
+ struct handles_container<qi::grammar<Iterator, T1, T2, T3, T4>, Attribute>
+ : traits::is_container<
+ typename attribute_of<qi::grammar<Iterator, T1, T2, T3, T4> >::type
+ >
+ {};
+}}}
+
 #endif

Added: trunk/boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp 2010-12-25 16:13:56 EST (Sat, 25 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_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM)
+#define BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/unused.hpp>
+
+namespace boost { namespace spirit { namespace qi
+{
+ // forward declaration only
+ template <
+ typename Iterator, typename T1 = unused_type
+ , typename T2 = unused_type, typename T3 = unused_type
+ , typename T4 = unused_type>
+ struct rule;
+
+ template <
+ typename Iterator, typename T1 = unused_type
+ , typename T2 = unused_type, typename T3 = unused_type
+ , typename T4 = unused_type>
+ struct grammar;
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/qi/nonterminal/rule.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/rule.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/rule.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -35,6 +35,7 @@
 #include <boost/spirit/home/qi/reference.hpp>
 #include <boost/spirit/home/qi/nonterminal/detail/parameterized.hpp>
 #include <boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
 #include <boost/spirit/home/qi/skip_over.hpp>
 
 #if defined(BOOST_MSVC)
@@ -63,12 +64,8 @@
     using spirit::locals;
 
     template <
- typename Iterator
- , typename T1 = unused_type
- , typename T2 = unused_type
- , typename T3 = unused_type
- , typename T4 = unused_type
- >
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4>
     struct rule
       : proto::extends<
             typename proto::terminal<
@@ -393,6 +390,18 @@
 #endif
 }}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4, typename Attribute>
+ struct handles_container<qi::rule<Iterator, T1, T2, T3, T4>, Attribute>
+ : traits::is_container<
+ typename attribute_of<qi::rule<Iterator, T1, T2, T3, T4> >::type>
+ {};
+}}}
+
 #if defined(BOOST_MSVC)
 # pragma warning(pop)
 #endif

Modified: trunk/boost/spirit/home/qi/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/alternative.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/qi/meta_compiler.hpp>
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/qi/detail/attributes.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/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.hpp>
@@ -99,9 +101,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<qi::alternative<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<qi::alternative<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/and_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/and_predicate.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/and_predicate.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/qi/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>
 #include <boost/fusion/include/at.hpp>
 
 namespace boost { namespace spirit
@@ -74,9 +76,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::and_predicate<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::and_predicate<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/difference.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/difference.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/difference.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/qi/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>
 #include <boost/fusion/include/at.hpp>
 
 namespace boost { namespace spirit
@@ -94,9 +96,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Left, typename Right>
     struct has_semantic_action<qi::difference<Left, Right> >
       : binary_has_semantic_action<Left, Right> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Left, typename Right, typename Attribute>
+ struct handles_container<qi::difference<Left, Right>, Attribute>
+ : binary_handles_container<Left, Right, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/expect.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/expect.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/expect.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -14,6 +14,8 @@
 #include <boost/spirit/home/qi/operator/sequence_base.hpp>
 #include <boost/spirit/home/qi/detail/expect_function.hpp>
 #include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <stdexcept>
 
@@ -84,9 +86,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<qi::expect<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<qi::expect<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/kleene.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/kleene.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/kleene.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -15,6 +15,8 @@
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 
 namespace boost { namespace spirit
@@ -108,9 +110,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::kleene<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::kleene<Subject>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/list.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/list.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/list.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -15,6 +15,8 @@
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <vector>
 
@@ -105,9 +107,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Left, typename Right>
     struct has_semantic_action<qi::list<Left, Right> >
       : binary_has_semantic_action<Left, Right> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Left, typename Right, typename Attribute>
+ struct handles_container<qi::list<Left, Right>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/not_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/not_predicate.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/not_predicate.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -15,6 +15,8 @@
 #include <boost/spirit/home/qi/meta_compiler.hpp>
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 
 namespace boost { namespace spirit
@@ -73,9 +75,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::not_predicate<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::not_predicate<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/optional.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/optional.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/optional.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -13,6 +13,8 @@
 
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/qi/meta_compiler.hpp>
@@ -91,9 +93,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::optional<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::optional<Subject>, Attribute>
+ : unary_handles_container<Subject, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/permutation.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/permutation.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/permutation.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -16,6 +16,8 @@
 #include <boost/spirit/home/qi/detail/attributes.hpp>
 #include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
 #include <boost/spirit/home/support/detail/what_function.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/fusion/include/size.hpp>
 #include <boost/optional.hpp>
@@ -119,6 +121,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     // We specialize this for permutation (see support/attributes.hpp).
     // For permutation, we only wrap the attribute in a tuple IFF
     // it is not already a fusion tuple.
@@ -126,9 +129,15 @@
     struct pass_attribute<qi::permutation<Elements>, Attribute>
       : wrap_if_not_tuple<Attribute> {};
 
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<qi::permutation<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<qi::permutation<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/plus.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/plus.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/plus.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -15,6 +15,8 @@
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/qi/detail/attributes.hpp>
+#include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/spirit/home/support/info.hpp>
 
 namespace boost { namespace spirit
@@ -102,9 +104,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Subject>
     struct has_semantic_action<qi::plus<Subject> >
       : unary_has_semantic_action<Subject> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::plus<Subject>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/sequence.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/sequence.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/sequence.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -79,9 +79,15 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<qi::sequence<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<qi::sequence<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/operator/sequence_base.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/sequence_base.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/sequence_base.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -19,6 +19,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/info.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/spirit/home/qi/parser.hpp>
 #include <boost/fusion/include/as_vector.hpp>
 #include <boost/fusion/include/vector.hpp>

Modified: trunk/boost/spirit/home/qi/operator/sequential_or.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/sequential_or.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/sequential_or.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -101,6 +101,7 @@
 
 namespace boost { namespace spirit { namespace traits
 {
+ ///////////////////////////////////////////////////////////////////////////
     // We specialize this for sequential_or (see support/attributes.hpp).
     // For sequential_or, we only wrap the attribute in a tuple IFF
     // it is not already a fusion tuple.
@@ -108,9 +109,15 @@
     struct pass_attribute<qi::sequential_or<Elements>, Attribute>
       : wrap_if_not_tuple<Attribute> {};
 
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Elements>
     struct has_semantic_action<qi::sequential_or<Elements> >
       : nary_has_semantic_action<Elements> {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elements, typename Attribute>
+ struct handles_container<qi::sequential_or<Elements>, Attribute>
+ : nary_handles_container<Elements, Attribute> {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/reference.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/reference.hpp (original)
+++ trunk/boost/spirit/home/qi/reference.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -14,6 +14,8 @@
 #include <boost/spirit/home/qi/meta_compiler.hpp>
 #include <boost/spirit/home/qi/parser.hpp>
 #include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/type_traits/remove_const.hpp>
 #include <boost/ref.hpp>
 
 namespace boost { namespace spirit { namespace qi
@@ -52,4 +54,13 @@
     };
 }}}
 
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Subject, typename Attribute>
+ struct handles_container<qi::reference<Subject>, Attribute>
+ : handles_container<typename remove_const<Subject>::type, Attribute>
+ {};
+}}}
+
 #endif

Modified: trunk/boost/spirit/home/qi/string/lit.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/string/lit.hpp (original)
+++ trunk/boost/spirit/home/qi/string/lit.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -25,6 +25,7 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/support/string_traits.hpp>
 #include <boost/spirit/home/support/detail/get_encoding.hpp>
+#include <boost/spirit/home/support/handles_container.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/value_at.hpp>
 #include <boost/type_traits/add_reference.hpp>
@@ -237,7 +238,20 @@
             return result_type(traits::get_c_string<String>::call(str), encoding());
         }
     };
+}}}
+
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename String, bool no_attribute, typename Attribute>
+ struct handles_container<
+ qi::literal_string<String, no_attribute>, Attribute>
+ : mpl::true_ {};
 
+ template <typename String, bool no_attribute, typename Attribute>
+ struct handles_container<
+ qi::no_case_literal_string<String, no_attribute>, Attribute>
+ : mpl::true_ {};
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -570,24 +570,25 @@
     template <typename Attribute, typename ActualAttribute>
     struct make_attribute
     {
+ typedef typename remove_const<Attribute>::type attribute_type;
         typedef typename
             mpl::if_<
                 is_same<typename remove_const<ActualAttribute>::type, unused_type>
- , typename remove_const<Attribute>::type
+ , attribute_type
               , ActualAttribute&>::type
         type;
 
         typedef typename
             mpl::if_<
                 is_same<typename remove_const<ActualAttribute>::type, unused_type>
- , typename remove_const<Attribute>::type
+ , attribute_type
               , ActualAttribute>::type
         value_type;
 
         static Attribute call(unused_type)
         {
              // synthesize the attribute/parameter
- return boost::get(value_initialized<Attribute>());
+ return boost::get(value_initialized<attribute_type>());
         }
 
         template <typename T>
@@ -604,7 +605,7 @@
 
     template <typename Attribute, typename ActualAttribute>
     struct make_attribute<Attribute const&, ActualAttribute>
- : make_attribute<Attribute, ActualAttribute>
+ : make_attribute<Attribute const, ActualAttribute>
     {};
 
     template <typename ActualAttribute>

Modified: trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp (original)
+++ trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -330,12 +330,11 @@
     template <typename T>
     inline void list::push_back(T const& val)
     {
-
         if (last == 0)
             push_front(val);
         else {
- detail::list::node* new_node
- = new detail::list::node(val, last->next, last);
+ detail::list::node* new_node =
+ new detail::list::node(val, last->next, last);
             last->next = new_node;
             last = new_node;
             ++size;

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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -1,7 +1,7 @@
 /*=============================================================================
     Copyright (c) 2001-2011 Joel de Guzman
     Copyright (c) 2001-2011 Hartmut Kaiser
- Copyright (c) 2011 Bryce Lelbach
+ Copyright (c) 2010-2011 Bryce Lelbach
 
     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)

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-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -1,7 +1,7 @@
 /*=============================================================================
     Copyright (c) 2001-2011 Joel de Guzman
     Copyright (c) 2001-2011 Hartmut Kaiser
- Copyright (c) 2011 Bryce Lelbach
+ Copyright (c) 2010-2011 Bryce Lelbach
 
     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)
@@ -12,7 +12,9 @@
 #include <boost/spirit/home/support/attributes.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/support/utree.hpp>
+#include <boost/spirit/home/qi/domain.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
 #include <boost/spirit/home/karma/nonterminal/nonterminal_fwd.hpp>
 
 #include <string>
@@ -120,7 +122,7 @@
     }
 
     template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct assign_to_attribute_from_value<
+ struct assign_to_container_from_value<
         utree, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
     {
         static void
@@ -134,7 +136,7 @@
     // this specialization tells Spirit.Qi to allow assignment to an utree from
     // a STL container
     template <typename Attribute>
- struct assign_to_attribute_from_value<utree, Attribute>
+ struct assign_to_container_from_value<utree, Attribute>
     {
         // any non-container type will be either directly assigned or appended
         static void call(Attribute const& val, utree& attr, mpl::false_)
@@ -148,7 +150,12 @@
         // any container type will be converted into a list_type utree
         static void call(Attribute const& val, utree& attr, mpl::true_)
         {
- attr = make_iterator_range(traits::begin(val), traits::end(val));
+ typedef typename traits::container_iterator<Attribute const>::type
+ iterator_type;
+
+ iterator_type end = traits::end(val);
+ for (iterator_type i = traits::begin(val); i != end; traits::next(i))
+ push_back(attr, traits::deref(i));
         }
         
         static void call(Attribute const& val, utree& attr)
@@ -161,19 +168,56 @@
     // this specialization is required to disambiguate the specializations
     // related to utree
     template <>
- struct assign_to_attribute_from_value<utree, utree>
+ struct assign_to_container_from_value<utree, utree>
     {
         static void call(utree const& val, utree& attr)
         {
- attr = val;
+ if (val.which() != utree_type::list_type)
+ attr = val;
+ else {
+ typedef utree::const_iterator iterator_type;
+ iterator_type end = val.end();
+ for (iterator_type i = val.begin(); i != end; ++i)
+ attr.push_back(*i);
+ }
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ template <>
+ struct transform_attribute<utree, utree, qi::domain>
+ {
+ typedef utree& type;
+
+ static utree& pre(utree& val) { return val; }
+
+ // If the rhs' attribute is already a list, push it back into the
+ // rule's attribute, otherwise wrap it into a list and push that back.
+ // This ensures that the rule always exposes an utree list node.
+ static void post(utree& attr, utree const& val)
+ {
+ if (val.which() != utree_type::list_type) {
+ utree ut;
+ ut.push_back(val);
+ attr.swap(ut);
+ }
         }
+
+ // fail() will be called by Qi rule's if the rhs failed parsing
+ static void fail(utree&) {}
     };
 
+ template <>
+ struct transform_attribute<utree&, utree, qi::domain>
+ : transform_attribute<utree, utree, qi::domain>
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     // this specialization makes sure strings get assigned as a whole and are
     // not converted into a utree list
     template <>
- struct assign_to_attribute_from_value<utree, utf8_string_type>
+ struct assign_to_container_from_value<utree, utf8_string_type>
     {
         static void call(utf8_string_type const& val, utree& attr)
         {
@@ -186,7 +230,7 @@
 
     // this specialization keeps symbols from being transformed into strings
     template<>
- struct assign_to_attribute_from_value<utree, utf8_symbol_type>
+ struct assign_to_container_from_value<utree, utf8_symbol_type>
     {
         static void call (utf8_symbol_type const& val, utree& attr)
         {
@@ -198,7 +242,7 @@
     };
 
     template<>
- struct assign_to_attribute_from_value<utree, utf8_symbol_range_type>
+ struct assign_to_container_from_value<utree, utf8_symbol_range_type>
     {
         static void call (utf8_symbol_range_type const& val, utree& attr)
         {
@@ -210,7 +254,7 @@
     };
 
     template <>
- struct assign_to_attribute_from_value<utree, std::string>
+ struct assign_to_container_from_value<utree, std::string>
     {
         static void call(std::string const& val, utree& attr)
         {
@@ -232,119 +276,136 @@
         {
             if (attr.empty())
                 attr.assign(first, last);
- else
- for (Iterator it = first; it != last; ++it)
- {
- push_back(attr, *it);
- }
+ else {
+ for (Iterator i = first; i != last; ++i)
+ push_back(attr, *i);
+ }
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////
     // Karma only: convert utree node to string
- template <typename T>
- struct attribute_as_xxx<T, utree,
- typename enable_if<mpl::or_<
- boost::is_same<T, std::string>
- , boost::is_same<T, utf8_string_type>
- , boost::is_same<T, utf8_string_range_type>
- > >::type
- > {
- typedef utf8_string_range_type type;
-
- static type call(utree const& attr)
+ namespace detail
+ {
+ struct attribute_as_string_type
         {
- return boost::get<utf8_string_range_type>(attr);
- }
+ typedef utf8_string_range_type type;
+
+ static type call(utree const& attr)
+ {
+ return boost::get<utf8_string_range_type>(attr);
+ }
         
- static bool is_valid(utree const& attr)
- {
- switch (attr.which())
+ static bool is_valid(utree const& attr)
             {
+ switch (attr.which())
+ {
                 case utree_type::reference_type:
- {
- return is_valid(attr.deref());
- }
+ return is_valid(attr.deref());
+
                 case utree_type::string_range_type:
                 case utree_type::string_type:
- {
- return true;
- }
+ return true;
+
                 default:
- {
- return false;
- }
+ return false;
+ }
             }
- }
- };
+ };
+ }
     
- template <typename T>
- struct attribute_as_xxx<T, utree,
- typename enable_if<mpl::or_<
- boost::is_same<T, utf8_symbol_type>
- , boost::is_same<T, utf8_symbol_range_type>
- > >::type
- > {
- typedef utf8_symbol_range_type type;
+ template <>
+ struct attribute_as_xxx<std::string, utree>
+ : detail::attribute_as_string_type
+ {};
 
- static type call(utree const& attr)
+ template <>
+ struct attribute_as_xxx<utf8_string_type, utree>
+ : detail::attribute_as_string_type
+ {};
+
+ template <>
+ struct attribute_as_xxx<utf8_string_range_type, utree>
+ : detail::attribute_as_string_type
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ struct attribute_as_symbol_type
         {
- return boost::get<utf8_symbol_range_type>(attr);
- }
+ typedef utf8_symbol_range_type type;
+
+ static type call(utree const& attr)
+ {
+ return boost::get<utf8_symbol_range_type>(attr);
+ }
         
- static bool is_valid(utree const& attr)
- {
- switch (attr.which())
+ static bool is_valid(utree const& attr)
             {
+ switch (attr.which())
+ {
                 case utree_type::reference_type:
- {
- return is_valid(attr.deref());
- }
+ return is_valid(attr.deref());
+
                 case utree_type::symbol_type:
- {
- return true;
- }
+ return true;
+
                 default:
- {
- return false;
- }
+ return false;
+ }
             }
- }
- };
+ };
+ }
 
- template <typename T>
- struct attribute_as_xxx<T, utree,
- typename enable_if<mpl::or_<
- boost::is_same<T, binary_string_type>
- , boost::is_same<T, binary_range_type>
- > >::type
- > {
- typedef binary_range_type type;
+ template <>
+ struct attribute_as_xxx<utf8_symbol_type, utree>
+ : detail::attribute_as_symbol_type
+ {};
 
- static type call(utree const& attr)
- {
- return boost::get<binary_range_type>(attr);
- }
+ template <>
+ struct attribute_as_xxx<utf8_symbol_range_type, utree>
+ : detail::attribute_as_symbol_type
+ {};
 
- static bool is_valid(utree const& attr)
+ ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ struct attribute_as_binary_string_type
         {
- switch (attr.which())
+ typedef binary_range_type type;
+
+ static type call(utree const& attr)
             {
+ return boost::get<binary_range_type>(attr);
+ }
+
+ static bool is_valid(utree const& attr)
+ {
+ switch (attr.which())
+ {
                 case utree_type::reference_type:
- {
- return is_valid(attr.deref());
- }
+ return is_valid(attr.deref());
+
                 case utree_type::binary_type:
- {
- return true;
- }
+ return true;
+
                 default:
- {
- return false;
- }
+ return false;
+ }
             }
- }
- };
+ };
+ }
+
+ template <>
+ struct attribute_as_xxx<binary_string_type, utree>
+ : detail::attribute_as_binary_string_type
+ {};
+
+ template <>
+ struct attribute_as_xxx<binary_range_type, utree>
+ : detail::attribute_as_binary_string_type
+ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // push_back support for utree
@@ -358,23 +419,31 @@
                 case utree_type::uninitialized_type:
                 case utree_type::nil_type:
                 case utree_type::list_type:
- {
- c.push_back(val);
- break;
- }
+ c.push_back(val);
+ break;
+
                 default:
- {
- utree ut;
- ut.push_back(c);
- ut.push_back(val);
- c.swap(ut);
- }
+ {
+ utree ut;
+ ut.push_back(c);
+ ut.push_back(val);
+ c.swap(ut);
+ }
+ break;
             }
             return true;
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // an utree is a container on its own
+ template <>
+ struct build_std_vector<utree>
+ {
+ typedef utree type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // debug support for utree
     template <typename Out>
     struct print_attribute_debug<Out, utree>
@@ -387,13 +456,43 @@
 
     ///////////////////////////////////////////////////////////////////////////
     // force utree list attribute in a sequence to be dereferenced if a rule
- // or a grammar takes an utree
+ // or a grammar exposes an utree as it's attribute
+ namespace detail
+ {
+ template <typename Attribute>
+ struct attribute_is_not_utree
+ : mpl::and_<
+ mpl::not_<is_same<utree, Attribute> >,
+ traits::is_container<Attribute> >
+ {};
+ }
+
+ template <
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4>
+ struct handles_container<qi::rule<Iterator, T1, T2, T3, T4>, utree>
+ : detail::attribute_is_not_utree<typename attribute_of<
+ qi::rule<Iterator, T1, T2, T3, T4>
+ >::type>
+ {};
+
+ template <
+ typename Iterator, typename T1, typename T2, typename T3
+ , typename T4>
+ struct handles_container<qi::grammar<Iterator, T1, T2, T3, T4>, utree>
+ : detail::attribute_is_not_utree<typename attribute_of<
+ qi::grammar<Iterator, T1, T2, T3, T4>
+ >::type>
+ {};
+
     template <
         typename OutputIterator, typename T1, typename T2, typename T3
       , typename T4>
     struct handles_container<
             karma::rule<OutputIterator, T1, T2, T3, T4>, utree>
- : mpl::false_
+ : detail::attribute_is_not_utree<typename attribute_of<
+ karma::rule<OutputIterator, T1, T2, T3, T4>
+ >::type>
     {};
 
     template <
@@ -401,7 +500,9 @@
       , typename T4>
     struct handles_container<
             karma::grammar<OutputIterator, T1, T2, T3, T4>, utree>
- : mpl::false_
+ : detail::attribute_is_not_utree<typename attribute_of<
+ karma::grammar<OutputIterator, T1, T2, T3, T4>
+ >::type>
     {};
 
     ///////////////////////////////////////////////////////////////////////////
@@ -424,6 +525,23 @@
         }
     };
 
+ template <>
+ struct build_optional<utree>
+ {
+ typedef utree type;
+ };
+
+ // an utree is an optional (in any domain)
+ template <>
+ struct not_is_optional<utree, qi::domain>
+ : mpl::false_
+ {};
+
+ template <>
+ struct not_is_optional<utree, karma::domain>
+ : mpl::false_
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     // the specialization below tells Spirit to handle utree as if it
     // where a 'real' variant (in the context of karma)
@@ -672,6 +790,17 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename T>
+ inline T get_or_deref(utree const& t)
+ {
+ if (t.which() == utree_type::list_type)
+ return boost::get<T>(t.front());
+ return boost::get<T>(t);
+ }
+ }
+
     template <>
     struct extract_from_attribute<utree, spirit::nil_type>
     {
@@ -692,7 +821,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
+ utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
             return r.front();
         }
     };
@@ -705,7 +834,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- return boost::get<bool>(t);
+ return detail::get_or_deref<bool>(t);
         }
     };
 
@@ -717,7 +846,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- return boost::get<int>(t);
+ return detail::get_or_deref<int>(t);
         }
     };
 
@@ -729,7 +858,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- return boost::get<double>(t);
+ return detail::get_or_deref<double>(t);
         }
     };
 
@@ -741,7 +870,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
             return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
         }
     };
@@ -754,7 +883,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
+ utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
             return std::string(r.begin(), r.end());
         }
     };
@@ -767,7 +896,7 @@
         template <typename Context>
         static type call(utree const& t, Context&)
         {
- utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
             return std::string(r.begin(), r.end());
         }
     };
@@ -791,7 +920,7 @@
 
         static type pre(utree const& t)
         {
- utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
             return r.front();
         }
     };
@@ -803,7 +932,7 @@
 
         static type pre(utree const& t)
         {
- return boost::get<bool>(t);
+ return detail::get_or_deref<bool>(t);
         }
     };
 
@@ -814,7 +943,7 @@
 
         static type pre(utree const& t)
         {
- return boost::get<int>(t);
+ return detail::get_or_deref<int>(t);
         }
     };
 
@@ -825,7 +954,7 @@
 
         static type pre(utree const& t)
         {
- return boost::get<double>(t);
+ return detail::get_or_deref<double>(t);
         }
     };
 
@@ -837,7 +966,7 @@
 
         static type pre(utree const& t)
         {
- utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
             return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
         }
     };
@@ -865,7 +994,7 @@
 
         static type pre(utree const& t)
         {
- utf8_string_range_type r = boost::get<utf8_string_range_type>(t);
+ utf8_string_range_type r = detail::get_or_deref<utf8_string_range_type>(t);
             return std::string(r.begin(), r.end());
         }
     };
@@ -877,10 +1006,30 @@
 
         static type pre(utree const& t)
         {
- utf8_symbol_range_type r = boost::get<utf8_symbol_range_type>(t);
+ utf8_symbol_range_type r = detail::get_or_deref<utf8_symbol_range_type>(t);
             return std::string(r.begin(), r.end());
         }
     };
+
+ // If a rule takes an utree attribute and that utree instance holds nothing
+ // more than a list, we dereference this to simplify attribute handling
+ // down the stream, i.e. ( ( 1 2 3 ) ) --> ( 1 2 3 ).
+ template <>
+ struct transform_attribute<utree const, utree, karma::domain>
+ {
+ typedef utree const& type;
+ static utree const& pre(utree const& val)
+ {
+ if (val.which() == utree_type::list_type && 1 == val.size())
+ return val.front();
+ return val;
+ }
+ };
+
+ template <>
+ struct transform_attribute<utree const&, utree, karma::domain>
+ : transform_attribute<utree const, utree, karma::domain>
+ {};
 }}}
 
 #endif

Modified: trunk/libs/spirit/test/karma/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/utree.cpp (original)
+++ trunk/libs/spirit/test/karma/utree.cpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -88,6 +88,7 @@
         rule<output_iterator, double()> r1 = double_;
         rule<output_iterator, utree()> r2 = double_;
 
+ // ( 1.23 "a" "b" )
         ut.push_back(1.23);
         ut.push_back('a');
         ut.push_back('b');
@@ -95,6 +96,17 @@
         BOOST_TEST(test("1.23ab", r1 << *char_, ut));
         BOOST_TEST(test("1.23ab", r2 << *char_, ut));
 
+ // ( ( 1.23 ) "a" "b" )
+ ut.clear();
+ utree ut1;
+ ut1.push_back(1.23);
+ ut.push_back(ut1);
+ ut.push_back('a');
+ ut.push_back('b');
+ BOOST_TEST(test("1.23ab", r1 << *char_, ut));
+ BOOST_TEST(test("1.23ab", r2 << *char_, ut));
+
+ // ( "a" "b" 1.23 )
         ut.clear();
         ut.push_back('a');
         ut.push_back('b');
@@ -102,6 +114,14 @@
         BOOST_TEST(test("ab1.23", repeat(2)[~digit] << double_, ut));
         BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut));
         BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut));
+
+ // ( "a" "b" ( 1.23 ) )
+ ut.clear();
+ ut.push_back('a');
+ ut.push_back('b');
+ ut.push_back(ut1);
+ BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r1, ut));
+ BOOST_TEST(test("ab1.23", repeat(2)[~digit] << r2, ut));
     }
 
     // kleene star
@@ -124,6 +144,7 @@
 
     // lists
     {
+ // ( "a" "b" )
         rule<output_iterator, utree()> r1 = char_ % ',';
         utree ut;
         ut.push_back('a');
@@ -131,20 +152,60 @@
         BOOST_TEST(test("a,b", char_ % ',', ut));
         BOOST_TEST(test("a,b", r1, ut));
 
- rule<output_iterator, utree()> r2 = int_ % ',';
+ // ( ( "a" "b" ) )
+ utree ut1;
+ ut1.push_back(ut);
+ BOOST_TEST(test("a,b", r1, ut1));
+
+// rule<output_iterator, std::vector<char>()> r2 = char_ % ',';
+// BOOST_TEST(test("a,b", r2, ut));
+// BOOST_TEST(test("a,b", r2, ut1));
+
+ // ( ( "a" "b" ) ( "a" "b" ) )
+ ut1.push_back(ut);
+ BOOST_TEST(test("a,b a,b", r1 << ' ' << r1, ut1));
+
+ // ( 123 456 )
+ rule<output_iterator, utree()> r3 = int_ % ',';
         ut.clear();
         ut.push_back(123);
         ut.push_back(456);
         BOOST_TEST(test("123,456", int_ % ',', ut));
- BOOST_TEST(test("123,456", r2, ut));
+ BOOST_TEST(test("123,456", r3, ut));
 
- ut.clear();
+ // ( ( 123 456 ) )
+ ut1.clear();
+ ut1.push_back(ut);
+ BOOST_TEST(test("123,456", r3, ut1));
+
+// rule<output_iterator, std::vector<int>()> r4 = int_ % ',';
+// BOOST_TEST(test("123,456", r4, ut));
+// BOOST_TEST(test("123,456", r4, ut1));
+
+ // ( ( 123 456 ) ( 123 456 ) )
+ ut1.push_back(ut);
+ BOOST_TEST(test("123,456 123,456", r3 << ' ' << r3, ut1));
 
- rule<output_iterator, utree()> r3 = double_ % ',';
+ // ( 1.23 4.56 )
+ rule<output_iterator, utree()> r5 = double_ % ',';
+ ut.clear();
         ut.push_back(1.23);
         ut.push_back(4.56);
         BOOST_TEST(test("1.23,4.56", double_ % ',', ut));
- BOOST_TEST(test("1.23,4.56", r3, ut));
+ BOOST_TEST(test("1.23,4.56", r5, ut));
+
+ // ( ( 1.23 4.56 ) )
+ ut1.clear();
+ ut1.push_back(ut);
+ BOOST_TEST(test("1.23,4.56", r5, ut1));
+
+// rule<output_iterator, std::vector<double>()> r6 = double_ % ',';
+// BOOST_TEST(test("1.23,4.56", r6, ut));
+// BOOST_TEST(test("1.23,4.56", r6, ut1));
+
+ // ( ( 1.23 4.56 ) ( 1.23 4.56 ) )
+ ut1.push_back(ut);
+ BOOST_TEST(test("1.23,4.56 1.23,4.56", r5 <<' ' << r5, ut1));
     }
 
     // alternatives

Modified: trunk/libs/spirit/test/qi/utree.cpp
==============================================================================
--- trunk/libs/spirit/test/qi/utree.cpp (original)
+++ trunk/libs/spirit/test/qi/utree.cpp 2010-12-25 16:13:56 EST (Sat, 25 Dec 2010)
@@ -10,6 +10,7 @@
 
 #include <boost/spirit/include/support_utree.hpp>
 #include <boost/spirit/include/qi.hpp>
+#include <boost/mpl/print.hpp>
 
 #include <sstream>
 
@@ -79,7 +80,7 @@
         rule<char const*, utree()> r = char_("abc");
 
         BOOST_TEST(test_attr("a", r, ut) &&
- ut.which() == utree_type::string_type && check(ut, "\"a\""));
+ ut.which() == utree_type::list_type && check(ut, "( \"a\" )"));
     }
 
     // sequences
@@ -104,13 +105,12 @@
             ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
 
         rule<char const*, utree()> r1 = double_;
-
         ut.clear();
         BOOST_TEST(test_attr("1.2ab", r1 >> *char_, ut) &&
- ut.which() == utree_type::list_type && check(ut, "( 1.2 \"a\" \"b\" )"));
+ ut.which() == utree_type::list_type && check(ut, "( ( 1.2 ) \"a\" \"b\" )"));
         ut.clear();
         BOOST_TEST(test_attr("ab1.2", *~digit >> r1, ut) &&
- ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
+ ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" ( 1.2 ) )"));
         ut.clear();
         
         rule<char const*, utree()> r2 = int_ >> char_("!") >> double_;
@@ -187,22 +187,20 @@
             ut.which() == utree_type::double_type && check(ut, "10.2"));
 
         rule<char const*, boost::variant<int, double>()> r1 = strict_double | int_;
-
         ut.clear();
         BOOST_TEST(test_attr("10", r1, ut) &&
- ut.which() == utree_type::int_type && check(ut, "10")); // FIXME?: "( 10 )"
+ ut.which() == utree_type::int_type && check(ut, "10"));
         ut.clear();
         BOOST_TEST(test_attr("10.2", r1, ut) &&
- ut.which() == utree_type::double_type && check(ut, "10.2")); // FIXME?: "( 10.2 )"
+ ut.which() == utree_type::double_type && check(ut, "10.2"));
 
         rule<char const*, utree()> r2 = strict_double | int_;
-
         ut.clear();
         BOOST_TEST(test_attr("10", r2, ut) &&
- ut.which() == utree_type::int_type && check(ut, "10")); // FIXME?: "( 10 )"
+ ut.which() == utree_type::list_type && check(ut, "( 10 )"));
         ut.clear();
         BOOST_TEST(test_attr("10.2", r2, ut) &&
- ut.which() == utree_type::double_type && check(ut, "10.2")); // FIXME?: "( 10.2 )"
+ ut.which() == utree_type::list_type && check(ut, "( 10.2 )"));
     }
 
     // optionals
@@ -246,7 +244,7 @@
         ut.clear();
 
         BOOST_TEST(test_attr("a,b1.2", ~digit % ',' >> double_, ut) &&
- ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )")); // FIXME?: "( ( \"a\" \"b\" ) 1.2 )"
+ ut.which() == utree_type::list_type && check(ut, "( \"a\" \"b\" 1.2 )"));
         ut.clear();
     }
 
@@ -307,5 +305,36 @@
         ut.clear();
     }
 
+ // subtrees
+ {
+ // -(+int_) is forcing a subtree
+ utree ut;
+ BOOST_TEST(test_attr("1 2", int_ >> ' ' >> -(+int_), ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( 1 2 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("1 2", int_ >> ' ' >> *int_, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( 1 2 )"));
+ ut.clear();
+
+ rule<char const*, std::vector<int>()> r1 = int_ % ',';
+ BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r1, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( 1 2 3 )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("1,2 2,3", r1 >> ' ' >> r1, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( 1 2 2 3 )"));
+ ut.clear();
+
+ rule<char const*, utree()> r2 = int_ % ',';
+ BOOST_TEST(test_attr("1 2,3", int_ >> ' ' >> r2, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( 1 ( 2 3 ) )"));
+ ut.clear();
+
+ BOOST_TEST(test_attr("1,2 2,3", r2 >> ' ' >> r2, ut) &&
+ ut.which() == utree_type::list_type && check(ut, "( ( 1 2 ) ( 2 3 ) )"));
+ ut.clear();
+ }
+
     return boost::report_errors();
 }


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