Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56533 - in trunk/boost/spirit: home/karma home/karma/auxiliary home/karma/binary home/karma/char home/karma/detail home/karma/directive home/karma/nonterminal home/karma/numeric home/karma/operator home/karma/stream home/karma/string home/lex/lexer home/lex/lexer/lexertl home/lex/qi home/qi home/qi/auxiliary home/qi/binary home/qi/char home/qi/detail home/qi/directive home/qi/nonterminal home/qi/nonterminal/detail home/qi/numeric home/qi/operator home/qi/string home/support include
From: hartmut.kaiser_at_[hidden]
Date: 2009-10-02 17:18:45


Author: hkaiser
Date: 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
New Revision: 56533
URL: http://svn.boost.org/trac/boost/changeset/56533

Log:
Spirit: restructured customization points, added qi::attr_cast, added phoenix expression support for Karma attributes
Added:
   trunk/boost/spirit/home/karma/detail/extract_from.hpp (contents, props changed)
   trunk/boost/spirit/home/karma/phoenix_attributes.hpp (contents, props changed)
   trunk/boost/spirit/home/qi/auxiliary/attr_cast.hpp (contents, props changed)
   trunk/boost/spirit/home/support/attributes_fwd.hpp (contents, props changed)
   trunk/boost/spirit/include/karma_phoenix_attributes.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/auxiliary/attr_cast.hpp | 70 +++++--
   trunk/boost/spirit/home/karma/binary/binary.hpp | 3
   trunk/boost/spirit/home/karma/char/char_generator.hpp | 5
   trunk/boost/spirit/home/karma/detail/pass_container.hpp | 8
   trunk/boost/spirit/home/karma/directive/repeat.hpp | 2
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp | 8
   trunk/boost/spirit/home/karma/numeric/bool.hpp | 5
   trunk/boost/spirit/home/karma/numeric/int.hpp | 5
   trunk/boost/spirit/home/karma/numeric/real.hpp | 5
   trunk/boost/spirit/home/karma/numeric/uint.hpp | 5
   trunk/boost/spirit/home/karma/operator/list.hpp | 10
   trunk/boost/spirit/home/karma/stream/stream.hpp | 5
   trunk/boost/spirit/home/karma/string/lit.hpp | 76 -------
   trunk/boost/spirit/home/lex/lexer/lexer.hpp | 2
   trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp | 215 ++++++++++++++----------
   trunk/boost/spirit/home/lex/lexer/token_def.hpp | 2
   trunk/boost/spirit/home/lex/qi/plain_token.hpp | 2
   trunk/boost/spirit/home/qi/auxiliary.hpp | 1
   trunk/boost/spirit/home/qi/auxiliary/attr.hpp | 2
   trunk/boost/spirit/home/qi/binary/binary.hpp | 4
   trunk/boost/spirit/home/qi/char/char_parser.hpp | 2
   trunk/boost/spirit/home/qi/detail/assign_to.hpp | 121 +++++--------
   trunk/boost/spirit/home/qi/detail/construct.hpp | 184 ++++++++++++--------
   trunk/boost/spirit/home/qi/detail/string_parse.hpp | 8
   trunk/boost/spirit/home/qi/directive/raw.hpp | 2
   trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp | 24 ++
   trunk/boost/spirit/home/qi/nonterminal/rule.hpp | 8
   trunk/boost/spirit/home/qi/numeric/bool_policies.hpp | 4
   trunk/boost/spirit/home/qi/operator/optional.hpp | 2
   trunk/boost/spirit/home/qi/string/symbols.hpp | 2
   trunk/boost/spirit/home/support/attributes.hpp | 207 ++++++++++++-----------
   trunk/boost/spirit/home/support/container.hpp | 351 ++++++++++++++++++++++++++-------------
   trunk/boost/spirit/home/support/terminal.hpp | 10
   33 files changed, 756 insertions(+), 604 deletions(-)

Modified: trunk/boost/spirit/home/karma/auxiliary/attr_cast.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/auxiliary/attr_cast.hpp (original)
+++ trunk/boost/spirit/home/karma/auxiliary/attr_cast.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -23,19 +23,36 @@
 {
     ///////////////////////////////////////////////////////////////////////////
     // enables attr_cast<>() pseudo generator
- template <typename Expr, typename Attribute>
+ template <typename Expr, typename Exposed, typename Transformed>
     struct use_terminal<karma::domain
- , tag::stateful_tag<Expr, tag::attr_cast, Attribute> >
+ , tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
       : mpl::true_ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // This one is the function that the user can call directly in order
     // to create a customized attr_cast component
- template <typename Attribute, typename Data>
- stateful_tag_type<Data, tag::attr_cast, Attribute>
- attr_cast(Data const& data)
+ template <typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast> >::type
+ attr_cast(Expr const& expr)
     {
- return stateful_tag_type<Data, tag::attr_cast, Attribute>(data);
+ return stateful_tag_type<Expr, tag::attr_cast>(expr);
+ }
+
+ template <typename Exposed, typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast, Exposed> >::type
+ attr_cast(Expr const& expr)
+ {
+ return stateful_tag_type<Expr, tag::attr_cast, Exposed>(expr);
+ }
+
+ template <typename Exposed, typename Transformed, typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed> >::type
+ attr_cast(Expr const& expr)
+ {
+ return stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed>(expr);
     }
 }}
 
@@ -47,15 +64,21 @@
     // attr_cast_generator consumes the attribute of subject generator without
     // generating anything
     ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Subject>
+ template <typename Exposed, typename Transformed, typename Subject>
     struct attr_cast_generator
- : unary_generator<attr_cast_generator<Attribute, Subject> >
+ : unary_generator<attr_cast_generator<Exposed, Transformed, Subject> >
     {
         typedef typename result_of::compile<karma::domain, Subject>::type
             subject_type;
 
         typedef mpl::int_<subject_type::properties::value> properties;
 
+ typedef typename mpl::eval_if<
+ traits::is_not_unused<Transformed>
+ , mpl::identity<Transformed>
+ , traits::attribute_of<subject_type> >::type
+ transformed_attribute_type;
+
         attr_cast_generator(Subject const& subject)
           : subject(subject)
         {
@@ -65,23 +88,22 @@
             BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Subject);
         }
 
+ // If Exposed is given, we use the given type, otherwise all we can do
+ // is to guess, so we expose our inner type as an attribute and
+ // deal with the passed attribute inside the parse function.
         template <typename Context, typename Unused>
         struct attribute
- {
- typedef Attribute type;
- };
+ : mpl::if_<traits::is_not_unused<Exposed>, Exposed
+ , transformed_attribute_type>
+ {};
 
         template <typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute_>
+ , typename Attribute>
         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
- , Attribute_ const& attr) const
+ , Attribute const& attr) const
         {
- // create the proper attribute transformation
- typedef traits::transform_attribute<
- Attribute, Attribute_ const> transform;
-
- return compile<karma::domain>(subject).
- generate(sink, ctx, d, transform::call(attr));
+ return compile<karma::domain>(subject).generate(sink, ctx, d
+ , traits::pre_transform<transformed_attribute_type>(attr));
         }
 
         template <typename Context>
@@ -97,16 +119,18 @@
     ///////////////////////////////////////////////////////////////////////////
     // Generator generator: make_xxx function (objects)
     ///////////////////////////////////////////////////////////////////////////
- template <typename Expr, typename Attribute, typename Modifiers>
+ template <typename Expr, typename Exposed, typename Transformed
+ , typename Modifiers>
     struct make_primitive<
- tag::stateful_tag<Expr, tag::attr_cast, Attribute>, Modifiers>
+ tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
     {
- typedef attr_cast_generator<Attribute, Expr> result_type;
+ typedef attr_cast_generator<Exposed, Transformed, Expr> result_type;
 
         template <typename Terminal>
         result_type operator()(Terminal const& term, unused_type) const
         {
- typedef tag::stateful_tag<Expr, tag::attr_cast, Attribute> tag_type;
+ typedef tag::stateful_tag<
+ Expr, tag::attr_cast, Exposed, Transformed> tag_type;
             using spirit::detail::get_stateful_data;
             return result_type(get_stateful_data<tag_type>::call(term));
         }

Modified: trunk/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/karma/binary/binary.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -19,6 +19,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/fusion/include/vector.hpp>
@@ -191,7 +192,7 @@
             boost::integer::endian<
                 endian, typename karma::detail::integer<bits>::type, bits
> p;
- p = traits::optional_value(attr);
+ p = traits::extract_from(attr);
             unsigned char const* bytes =
                 reinterpret_cast<unsigned char const*>(&p);
 

Modified: trunk/boost/spirit/home/karma/char/char_generator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/char/char_generator.hpp (original)
+++ trunk/boost/spirit/home/karma/char/char_generator.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -14,6 +14,7 @@
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/generator.hpp>
 #include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/meta_compiler.hpp>
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/support/unused.hpp>
@@ -73,8 +74,8 @@
             if (!traits::has_optional_value(attr))
                 return false;
 
- Char ch = Char();
- if (!this->derived().test(traits::optional_value(attr), ch, context))
+ Attr ch = Attr();
+ if (!this->derived().test(traits::extract_from(attr), ch, context))
                 return false;
 
             return karma::detail::generate_to(sink, ch, char_encoding(), tag()) &&

Added: trunk/boost/spirit/home/karma/detail/extract_from.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/detail/extract_from.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,119 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM)
+#define BOOST_SPIRIT_KARMA_EXTRACT_FROM_SEP_30_2009_0732AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/phoenix/core/actor.hpp>
+#include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/container.hpp>
+
+#include <boost/ref.hpp>
+#include <boost/optional.hpp>
+
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // This file contains attribute extraction utilities. The utilities
+ // provided also accept spirit's unused_type; all no-ops. Compiler
+ // optimization will easily strip these away.
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ template <typename Attribute, typename Enable/* = void*/>
+ struct extract_from
+ {
+ typedef Attribute const& type;
+ };
+
+ template <typename Attribute>
+ struct extract_from<optional<Attribute> >
+ {
+ typedef Attribute const& type;
+ };
+
+ template <typename Attribute>
+ struct extract_from<optional<Attribute const> >
+ {
+ typedef Attribute const& type;
+ };
+
+ template <>
+ struct extract_from<unused_type>
+ {
+ typedef unused_type type;
+ };
+
+ template <>
+ struct extract_from<unused_type const>
+ {
+ typedef unused_type type;
+ };
+ }
+
+ // This is the default case: the plain attribute values
+ template <typename Attribute, typename Enable/* = void*/>
+ struct extract_from_attribute
+ {
+ typedef Attribute const& type;
+ static type call(Attribute const& attr)
+ {
+ return attr;
+ }
+ };
+
+ // This handles optional attributes.
+ template <typename Attribute>
+ struct extract_from_attribute<optional<Attribute> >
+ {
+ typedef Attribute const& type;
+ static type call(optional<Attribute> const& attr)
+ {
+ return boost::get<Attribute>(attr);
+ }
+ };
+
+ template <typename Attribute>
+ struct extract_from_attribute<optional<Attribute const> >
+ {
+ typedef Attribute const& type;
+ static type call(optional<Attribute const> const& attr)
+ {
+ return boost::get<Attribute const>(attr);
+ }
+ };
+
+ // This handles attributes wrapped inside a boost::ref().
+ template <typename Attribute>
+ struct extract_from_attribute<reference_wrapper<Attribute> >
+ {
+ typedef Attribute const& type;
+ static type call(reference_wrapper<Attribute> const& attr)
+ {
+ return attr.get();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute>
+ typename extract_from_attribute<Attribute>::type
+ extract_from(Attribute const& attr)
+ {
+ return extract_from_attribute<Attribute>::call(attr);
+ };
+
+ inline unused_type extract_from(unused_type)
+ {
+ return unused;
+ };
+
+}}}
+
+#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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -75,7 +75,9 @@
         bool dispatch_attribute_element(Component const& component, mpl::false_) const
         {
             // get the next value to generate from container
- if (!traits::compare(iter, traits::end(attr)) &&
+ typename traits::result_of::iterator<Attr>::type end =
+ traits::end(attr);
+ if (!traits::compare(iter, end) &&
                 !f(component, traits::deref(iter)))
             {
                 // needs to return false as long as everything is ok
@@ -92,7 +94,9 @@
         template <typename Component>
         bool dispatch_attribute_element(Component const& component, mpl::true_) const
         {
- bool result = f(component, make_iterator_range(iter, traits::end(attr)));
+ typename traits::result_of::iterator<Attr>::type end =
+ traits::end(attr);
+ bool result = f(component, make_iterator_range(iter, end));
             if (result)
                 iter = traits::end(attr); // adjust current iter to the end
             return result;

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -131,7 +131,7 @@
             typename OutputIterator, typename Context, typename Delimiter
           , typename Iterator>
         bool generate_subject(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator& it, Iterator const& end) const
+ , Delimiter const& d, Iterator& it, Iterator& end) const
         {
             while (!traits::compare(it, end))
             {

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -221,8 +221,8 @@
             if (f)
             {
                 // Create an attribute if none is supplied.
- typedef traits::make_transformed_attribute<
- attr_type, Attribute const> make_attribute;
+ typedef traits::make_attribute<attr_type, Attribute>
+ make_attribute;
 
                 // If you are seeing a compilation error here, you are probably
                 // trying to use a rule or a grammar which has inherited
@@ -250,8 +250,8 @@
             if (f)
             {
                 // Create an attribute if none is supplied.
- typedef traits::make_transformed_attribute<
- attr_type, Attribute const> make_attribute;
+ typedef traits::make_attribute<attr_type, Attribute>
+ make_attribute;
 
                 // If you are seeing a compilation error here, you are probably
                 // trying to use a rule or a grammar which has inherited

Modified: trunk/boost/spirit/home/karma/numeric/bool.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/bool.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/bool.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -20,6 +20,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/numeric/bool_policies.hpp>
 #include <boost/spirit/home/karma/numeric/detail/bool_utils.hpp>
@@ -131,7 +132,7 @@
                 return false; // fail if it's an uninitialized optional
 
             return bool_inserter<T, Policies, CharEncoding, Tag>::call(
- sink, traits::optional_value(attr), p_) &&
+ sink, traits::extract_from(attr), p_) &&
                    delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -185,7 +186,7 @@
           , Attribute const& attr) const
         {
             if (!traits::has_optional_value(attr) ||
- bool(n_) != bool(traits::optional_value(attr)))
+ bool(n_) != bool(traits::extract_from(attr)))
             {
                 return false;
             }

Modified: trunk/boost/spirit/home/karma/numeric/int.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/int.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/int.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -22,6 +22,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -215,7 +216,7 @@
             if (!traits::has_optional_value(attr))
                 return false; // fail if it's an uninitialized optional
 
- return insert_int(sink, traits::optional_value(attr)) &&
+ return insert_int(sink, traits::extract_from(attr)) &&
                    delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -283,7 +284,7 @@
           , Attribute const& attr) const
         {
             if (!traits::has_optional_value(attr) ||
- n_ != traits::optional_value(attr))
+ n_ != traits::extract_from(attr))
             {
                 return false;
             }

Modified: trunk/boost/spirit/home/karma/numeric/real.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/real.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/real.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -22,6 +22,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/numeric/real_policies.hpp>
 #include <boost/spirit/home/karma/numeric/detail/real_utils.hpp>
@@ -174,7 +175,7 @@
                 return false; // fail if it's an uninitialized optional
 
             typedef real_inserter<T, Policies, CharEncoding, Tag> inserter_type;
- return inserter_type::call(sink, traits::optional_value(attr), p_) &&
+ return inserter_type::call(sink, traits::extract_from(attr), p_) &&
                    karma::delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -228,7 +229,7 @@
           , Attribute const& attr) const
         {
             if (!traits::has_optional_value(attr) ||
- n_ != traits::optional_value(attr))
+ n_ != traits::extract_from(attr))
             {
                 return false;
             }

Modified: trunk/boost/spirit/home/karma/numeric/uint.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/numeric/uint.hpp (original)
+++ trunk/boost/spirit/home/karma/numeric/uint.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -22,6 +22,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/karma/numeric/detail/numeric_utils.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -246,7 +247,7 @@
                 return false; // fail if it's an uninitialized optional
 
             return int_inserter<Radix, CharEncoding, Tag>::
- call(sink, traits::optional_value(attr)) &&
+ call(sink, traits::extract_from(attr)) &&
                    delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -303,7 +304,7 @@
           , Attribute const& attr) const
         {
             if (!traits::has_optional_value(attr) ||
- n_ != traits::optional_value(attr))
+ n_ != traits::extract_from(attr))
             {
                 return false;
             }

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -1,5 +1,5 @@
-// Copyright (c) 2001-2009 Joel de Guzman
 // Copyright (c) 2001-2009 Hartmut Kaiser
+// Copyright (c) 2001-2009 Joel de Guzman
 //
 // 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)
@@ -43,7 +43,7 @@
             typename OutputIterator, typename Context, typename Delimiter
           , typename Iterator>
         bool generate_left(OutputIterator& sink, Context& ctx
- , Delimiter const& d, Iterator& it, Iterator const& end) const
+ , Delimiter const& d, Iterator& it, Iterator& end) const
         {
             while (!traits::compare(it, end))
             {
@@ -71,12 +71,12 @@
         template <typename Context, typename Iterator>
         struct attribute
           : traits::build_std_vector<
- typename traits::attribute_of<Left, Context, Iterator>::type
- >
+ typename traits::attribute_of<Left, Context, Iterator>::type>
         {};
 
         list(Left const& left, Right const& right)
- : left(left), right(right) {}
+ : left(left), right(right)
+ {}
 
         template <
             typename OutputIterator, typename Context, typename Delimiter

Added: trunk/boost/spirit/home/karma/phoenix_attributes.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/karma/phoenix_attributes.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,110 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM)
+#define BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/attributes.hpp>
+#include <boost/spirit/home/support/container.hpp>
+
+#include <boost/spirit/include/phoenix_core.hpp>
+#include <boost/utility/result_of.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Provide customization points allowing the use of phoenix expressions as
+ // generator functions in the context of generators expecting a container
+ // attribute (Kleene, plus, list, repeat, etc.)
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ template <typename Eval>
+ struct iterator<phoenix::actor<Eval> const>
+ {
+ typedef phoenix::actor<Eval> const& type;
+ };
+ }
+
+ template <typename Eval>
+ struct begin_container<phoenix::actor<Eval> const>
+ {
+ typedef phoenix::actor<Eval> const& type;
+ static type call(phoenix::actor<Eval> const& f)
+ {
+ return f;
+ }
+ };
+
+ template <typename Eval>
+ struct end_container<phoenix::actor<Eval> const>
+ {
+ typedef phoenix::actor<Eval> const& type;
+ static type call(phoenix::actor<Eval> const& f)
+ {
+ return f;
+ }
+ };
+
+ template <typename Eval>
+ struct deref_iterator<phoenix::actor<Eval> const>
+ {
+ typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
+ static type call(phoenix::actor<Eval> const& f)
+ {
+ return f();
+ }
+ };
+
+ template <typename Eval>
+ struct next_iterator<phoenix::actor<Eval> const>
+ {
+ typedef phoenix::actor<Eval> const& type;
+ static type call(phoenix::actor<Eval> const& f)
+ {
+ return f;
+ }
+ };
+
+ template <typename Eval>
+ struct compare_iterators<phoenix::actor<Eval> const>
+ {
+ static bool
+ call(phoenix::actor<Eval> const&, phoenix::actor<Eval> const&)
+ {
+ return false;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Handle Phoenix actors as attributes, just invoke the function object
+ // and deal with the result as the attribute.
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ template <typename Eval>
+ struct extract_from<phoenix::actor<Eval> >
+ : boost::result_of<phoenix::actor<Eval>()>
+ {};
+ }
+
+ template <typename Eval>
+ struct extract_from_attribute<phoenix::actor<Eval> >
+ {
+ typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
+ static type call(phoenix::actor<Eval> const& f)
+ {
+ return f();
+ }
+ };
+
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/karma/stream/stream.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/stream/stream.hpp (original)
+++ trunk/boost/spirit/home/karma/stream/stream.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -22,6 +22,7 @@
 #include <boost/spirit/home/karma/stream/detail/format_manip.hpp>
 #include <boost/spirit/home/karma/stream/detail/iterator_sink.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/vector.hpp>
 #include <boost/fusion/include/cons.hpp>
@@ -132,7 +133,7 @@
 
             // use existing operator<<()
             boost::iostreams::stream<sink_device> ostr(sink);
- ostr << traits::optional_value(attr) << std::flush;
+ ostr << traits::extract_from(attr) << std::flush;
 
             if (ostr.good())
                 return karma::delimit_out(sink, d); // always do post-delimiting
@@ -163,7 +164,7 @@
             // use existing operator<<()
             boost::iostreams::stream<sink_device> ostr(sink);
             ostr.imbue(sink.get_ostream().getloc());
- ostr << traits::optional_value(attr) << std::flush;
+ ostr << traits::extract_from(attr) << std::flush;
 
             if (ostr.good())
                 return karma::delimit_out(sink, d); // always do post-delimiting

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -21,6 +21,7 @@
 #include <boost/spirit/home/karma/delimit_out.hpp>
 #include <boost/spirit/home/karma/auxiliary/lazy.hpp>
 #include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/extract_from.hpp>
 #include <boost/spirit/home/karma/detail/string_generate.hpp>
 #include <boost/spirit/home/karma/detail/string_compare.hpp>
 #include <boost/fusion/include/at.hpp>
@@ -84,10 +85,8 @@
         };
 
         // lit has an attached attribute
- template <
- typename OutputIterator, typename Context,
- typename Delimiter, typename Attribute
- >
+ template <typename OutputIterator, typename Context, typename Delimiter
+ , typename Attribute>
         static bool
         generate(OutputIterator& sink, Context& /*ctx*/, Delimiter const& d,
             Attribute const& attr)
@@ -97,7 +96,7 @@
 
             return
                 karma::detail::string_generate(sink
- , traits::optional_value(attr), char_encoding(), Tag()) &&
+ , traits::extract_from(attr), char_encoding(), Tag()) &&
                 karma::delimit_out(sink, d); // always do post-delimiting
         }
 
@@ -156,10 +155,11 @@
             if (!traits::has_optional_value(attr))
                 return false;
 
- // fail if attribute isn't matched my immediate literal
+ // fail if attribute isn't matched by immediate literal
             using spirit::traits::get_c_string;
- if (!detail::string_compare(get_c_string(attr), get_c_string(str_)
- , char_encoding(), Tag()))
+ if (!detail::string_compare(
+ get_c_string(traits::extract_from(attr))
+ , get_c_string(str_), char_encoding(), Tag()))
             {
                 return false;
             }
@@ -186,66 +186,6 @@
         string_type str_;
     };
 
- template <typename String, typename Tag, bool no_attribute>
- struct literal_string<String, unused_type, Tag, no_attribute>
- : primitive_generator<literal_string<String, unused_type, Tag, no_attribute> >
- {
- typedef typename
- remove_const<typename traits::char_type_of<String>::type>::type
- char_type;
- typedef std::basic_string<char_type> string_type;
-
- template <typename Context, typename Unused>
- struct attribute
- {
- typedef typename mpl::if_c<
- no_attribute, unused_type, string_type>::type
- type;
- };
-
- literal_string(typename add_reference<String>::type str)
- : str_(str) {}
-
- // A string("...") which additionally has an associated attribute emits
- // its immediate literal only if it matches the attribute, otherwise
- // it fails.
- template <
- typename OutputIterator, typename Context, typename Delimiter
- , typename Attribute>
- bool generate(OutputIterator& sink, Context&, Delimiter const& d
- , Attribute const& attr) const
- {
- if (!traits::has_optional_value(attr))
- return false;
-
- // fail if attribute isn't matched my immediate literal
- using spirit::traits::get_c_string;
- if (!detail::string_compare(get_c_string(attr), get_c_string(str_)))
- return false;
-
- return detail::string_generate(sink, str_) &&
- karma::delimit_out(sink, d); // always do post-delimiting
- }
-
- // A string("...") without any associated attribute just emits its
- // immediate literal
- template <typename OutputIterator, typename Context, typename Delimiter>
- bool generate(OutputIterator& sink, Context&, Delimiter const& d
- , unused_type) const
- {
- return detail::string_generate(sink, str_) &&
- karma::delimit_out(sink, d); // always do post-delimiting
- }
-
- template <typename Context>
- info what(Context const& ctx) const
- {
- return info("literal-string", str_);
- }
-
- string_type str_;
- };
-
     ///////////////////////////////////////////////////////////////////////////
     // Generator generators: make_xxx function (objects)
     ///////////////////////////////////////////////////////////////////////////

Modified: trunk/boost/spirit/home/lex/lexer/lexer.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexer.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexer.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -90,7 +90,7 @@
                     token_type &t = *first;
                     if (token_is_valid(t) && t.state() == first.get_state()) {
                     // any of the token definitions matched
- qi::detail::assign_to(t, attr);
+ spirit::traits::assign_to(t, attr);
                         ++first;
                         return true;
                     }

Modified: trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -12,6 +12,7 @@
 
 #include <boost/spirit/home/qi/detail/assign_to.hpp>
 #include <boost/spirit/home/support/safe_bool.hpp>
+#include <boost/spirit/home/support/attributes.hpp>
 #include <boost/spirit/home/support/argument.hpp>
 #include <boost/spirit/home/support/detail/lexer/generator.hpp>
 #include <boost/spirit/home/support/detail/lexer/rules.hpp>
@@ -356,126 +357,156 @@
         return t ? true : false;
     }
 
+}}}}
+
+namespace boost { namespace spirit { namespace traits
+{
     ///////////////////////////////////////////////////////////////////////////
- // We have to provide overloads for the construct() function allowing
- // to extract the needed value from the token. These overloads have to be
- // defined in the same namespace as the token class itself to allow ADL to
- // find them.
+ // We have to provide specializations for the customization point
+ // assign_to_attribute_from_value allowing to extract the needed value
+ // from the token.
     ///////////////////////////////////////////////////////////////////////////
 
     // This is called from the parse function of token_def if the token_def
     // has been defined to carry a special attribute type
     template <typename Attribute, typename Iterator, typename AttributeTypes
       , typename HasState>
- inline void
- construct(Attribute& attr, token<Iterator, AttributeTypes, HasState>& t)
+ struct assign_to_attribute_from_value<Attribute
+ , lex::lexertl::token<Iterator, AttributeTypes, HasState> >
     {
- // The goal of this function is to avoid the conversion of the pair of
- // iterators (to the matched character sequence) into the token value
- // of the required type being done more than once. For this purpose it
- // checks whether the stored value type is still the default one (pair
- // of iterators) and if yes, replaces the pair of iterators with the
- // converted value to be returned from subsequent calls.
-
- if (0 == t.value().which()) {
- // first access to the token value
- typedef iterator_range<Iterator> iterpair_type;
- iterpair_type const& ip = get<iterpair_type>(t.value());
-
- // Interestingly enough we use the assign_to() framework defined in
- // Spirit.Qi allowing to convert the pair of iterators to almost any
- // required type (assign_to(), if available, uses the standard Spirit
- // parsers to do the conversion, and falls back to boost::lexical_cast
- // otherwise).
- qi::detail::assign_to(ip.begin(), ip.end(), attr);
-
- // If you get an error during the compilation of the following
- // assignment expression, you probably forgot to list one or more
- // types used as token value types (in your token_def<...>
- // definitions) in your definition of the token class. I.e. any token
- // value type used for a token_def<...> definition has to be listed
- // during the declaration of the token type to use. For instance let's
- // assume we have two token_def's:
- //
- // token_def<int> number; number = "...";
- // token_def<std::string> identifier; identifier = "...";
- //
- // Then you'll have to use the following token type definition
- // (assuming you are using the token class):
- //
- // typedef mpl::vector<int, std::string> token_values;
- // typedef token<base_iter_type, token_values> token_type;
- //
- // where: base_iter_type is the iterator type used to expose the
- // underlying input stream.
- //
- // This token_type has to be used as the second template parameter
- // to the lexer class:
- //
- // typedef lexer<base_iter_type, token_type> lexer_type;
- //
- // again, assuming you're using the lexer<> template for your
- // tokenization.
-
- t.value() = attr; // re-assign value
- }
- else {
- // reuse the already assigned value
- qi::detail::assign_to(get<Attribute>(t.value()), attr);
+ static void
+ call(lex::lexertl::token<Iterator, AttributeTypes, HasState> const& t
+ , Attribute& attr)
+ {
+ // The goal of this function is to avoid the conversion of the pair of
+ // iterators (to the matched character sequence) into the token value
+ // of the required type being done more than once. For this purpose it
+ // checks whether the stored value type is still the default one (pair
+ // of iterators) and if yes, replaces the pair of iterators with the
+ // converted value to be returned from subsequent calls.
+
+ if (0 == t.value().which()) {
+ // first access to the token value
+ typedef iterator_range<Iterator> iterpair_type;
+ iterpair_type const& ip = get<iterpair_type>(t.value());
+
+ // Interestingly enough we use the assign_to() framework defined in
+ // Spirit.Qi allowing to convert the pair of iterators to almost any
+ // required type (assign_to(), if available, uses the standard Spirit
+ // parsers to do the conversion, and falls back to boost::lexical_cast
+ // otherwise).
+ spirit::traits::assign_to(ip.begin(), ip.end(), attr);
+
+ // If you get an error during the compilation of the following
+ // assignment expression, you probably forgot to list one or more
+ // types used as token value types (in your token_def<...>
+ // definitions) in your definition of the token class. I.e. any token
+ // value type used for a token_def<...> definition has to be listed
+ // during the declaration of the token type to use. For instance let's
+ // assume we have two token_def's:
+ //
+ // token_def<int> number; number = "...";
+ // token_def<std::string> identifier; identifier = "...";
+ //
+ // Then you'll have to use the following token type definition
+ // (assuming you are using the token class):
+ //
+ // typedef mpl::vector<int, std::string> token_values;
+ // typedef token<base_iter_type, token_values> token_type;
+ //
+ // where: base_iter_type is the iterator type used to expose the
+ // underlying input stream.
+ //
+ // This token_type has to be used as the second template parameter
+ // to the lexer class:
+ //
+ // typedef lexer<base_iter_type, token_type> lexer_type;
+ //
+ // again, assuming you're using the lexer<> template for your
+ // tokenization.
+
+ typedef lex::lexertl::token<
+ Iterator, AttributeTypes, HasState> token_type;
+ const_cast<token_type&>(t).value() = attr; // re-assign value
+ }
+ else {
+ // reuse the already assigned value
+ spirit::traits::assign_to(get<Attribute>(t.value()), attr);
+ }
         }
- }
+ };
 
     // These are called from the parse function of token_def if the token type
     // has no special attribute type assigned
     template <typename Attribute, typename Iterator, typename HasState>
- inline void construct(Attribute& attr,
- token<Iterator, mpl::vector0<>, HasState>& t)
+ struct assign_to_attribute_from_value<
+ Attribute, lex::lexertl::token<Iterator, mpl::vector0<>, HasState> >
     {
- // The default type returned by the token_def parser component (if it
- // has no token value type assigned) is the pair of iterators to the
- // matched character sequence.
-
- qi::detail::assign_to(t.value().begin(), t.value().end(), attr);
- }
+ static void
+ call(lex::lexertl::token<Iterator, mpl::vector0<>, HasState> const& t
+ , Attribute& attr)
+ {
+ // The default type returned by the token_def parser component (if
+ // it has no token value type assigned) is the pair of iterators
+ // to the matched character sequence.
+ spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
+ }
+ };
 
     // same as above but using mpl::vector<> instead of mpl::vector0<>
     template <typename Attribute, typename Iterator, typename HasState>
- inline void construct(Attribute& attr,
- token<Iterator, mpl::vector<>, HasState>& t)
+ struct assign_to_attribute_from_value<
+ Attribute, lex::lexertl::token<Iterator, mpl::vector<>, HasState> >
     {
- // The default type returned by the token_def parser component (if it
- // has no token value type assigned) is the pair of iterators to the
- // matched character sequence.
-
- qi::detail::assign_to(t.value().begin(), t.value().end(), attr);
- }
+ static void
+ call(lex::lexertl::token<Iterator, mpl::vector<>, HasState> const& t
+ , Attribute& attr)
+ {
+ // The default type returned by the token_def parser component (if
+ // it has no token value type assigned) is the pair of iterators
+ // to the matched character sequence.
+ spirit::traits::assign_to(t.value().begin(), t.value().end(), attr);
+ }
+ };
 
     // This is called from the parse function of token_def if the token type
     // has been explicitly omitted (i.e. no attribute value is used), which
     // essentially means that every attribute gets initialized using default
     // constructed values.
     template <typename Attribute, typename Iterator, typename HasState>
- inline void
- construct(Attribute& attr, token<Iterator, lex::omit, HasState>& t) {}
+ struct assign_to_attribute_from_value<
+ Attribute, lex::lexertl::token<Iterator, lex::omit, HasState> >
+ {
+ static void
+ call(lex::lexertl::token<Iterator, lex::omit, HasState> const& t
+ , Attribute& attr)
+ {
+ // do nothing
+ }
+ };
 
     // This is called from the parse function of lexer_def_
     template <typename Iterator, typename AttributeTypes, typename HasState>
- inline void
- construct(fusion::vector2<std::size_t, iterator_range<Iterator> >& attr,
- token<Iterator, AttributeTypes, HasState> const& t)
- {
- // The type returned by the lexer_def_ parser components
- // is a fusion::vector containing the token id of the matched token
- // and the pair of iterators to the matched character sequence.
-
- typedef iterator_range<Iterator> iterpair_type;
- typedef fusion::vector2<std::size_t, iterator_range<Iterator> >
- attribute_type;
+ struct assign_to_attribute_from_value<
+ fusion::vector2<std::size_t, iterator_range<Iterator> >
+ , lex::lexertl::token<Iterator, AttributeTypes, HasState> >
+ {
+ static void
+ call(lex::lexertl::token<Iterator, AttributeTypes, HasState> const& t
+ , fusion::vector2<std::size_t, iterator_range<Iterator> >& attr)
+ {
+ // The type returned by the lexer_def_ parser components is a
+ // fusion::vector containing the token id of the matched token
+ // and the pair of iterators to the matched character sequence.
+ typedef iterator_range<Iterator> iterpair_type;
+ typedef fusion::vector2<std::size_t, iterator_range<Iterator> >
+ attribute_type;
 
- iterpair_type const& ip = get<iterpair_type>(t.value());
- attr = attribute_type(t.id(), get<iterpair_type>(t.value()));
- }
+ iterpair_type const& ip = get<iterpair_type>(t.value());
+ attr = attribute_type(t.id(), get<iterpair_type>(t.value()));
+ }
+ };
 
-}}}}
+}}}
 
 #endif

Modified: trunk/boost/spirit/home/lex/lexer/token_def.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/token_def.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/token_def.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -98,7 +98,7 @@
 
                 token_type &t = *first;
                 if (token_id_ == t.id() && token_state_ == t.state()) {
- qi::detail::assign_to(t, attr);
+ spirit::traits::assign_to(t, attr);
                     ++first;
                     return true;
                 }

Modified: trunk/boost/spirit/home/lex/qi/plain_token.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/qi/plain_token.hpp (original)
+++ trunk/boost/spirit/home/lex/qi/plain_token.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -83,7 +83,7 @@
 
                 token_type &t = *first;
                 if (id_type(id) == t.id()) {
- qi::detail::assign_to(t, attr);
+ spirit::traits::assign_to(t, attr);
                     ++first;
                     return true;
                 }

Modified: trunk/boost/spirit/home/qi/auxiliary.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/auxiliary.hpp (original)
+++ trunk/boost/spirit/home/qi/auxiliary.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -17,5 +17,6 @@
 #include <boost/spirit/home/qi/auxiliary/eol.hpp>
 #include <boost/spirit/home/qi/auxiliary/eoi.hpp>
 #include <boost/spirit/home/qi/auxiliary/attr.hpp>
+#include <boost/spirit/home/qi/auxiliary/attr_cast.hpp>
 
 #endif

Modified: trunk/boost/spirit/home/qi/auxiliary/attr.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/auxiliary/attr.hpp (original)
+++ trunk/boost/spirit/home/qi/auxiliary/attr.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -59,7 +59,7 @@
           , Context& context, Skipper const& skipper
           , Attribute& attr) const
         {
- qi::detail::assign_to(value_, attr);
+ spirit::traits::assign_to(value_, attr);
             return true; // never consume any input, succeed always
         }
 

Added: trunk/boost/spirit/home/qi/auxiliary/attr_cast.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/qi/auxiliary/attr_cast.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,168 @@
+// Copyright (c) 2001-2009 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(SPIRIT_QI_ATTR_CAST_SEP_26_2009_0735PM)
+#define SPIRIT_QI_ATTR_CAST_SEP_26_2009_0735PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/qi/meta_compiler.hpp>
+#include <boost/spirit/home/qi/parser.hpp>
+#include <boost/spirit/home/qi/domain.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/attributes.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Enablers
+ ///////////////////////////////////////////////////////////////////////////
+
+ // enables attr_cast<>() pseudo parser
+ template <typename Expr, typename Exposed, typename Transformed>
+ struct use_terminal<qi::domain
+ , tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
+ : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // This one is the function that the user can call directly in order
+ // to create a customized attr_cast component
+ template <typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast> >::type
+ attr_cast(Expr const& expr)
+ {
+ return stateful_tag_type<Expr, tag::attr_cast>(expr);
+ }
+
+ template <typename Exposed, typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast, Exposed> >::type
+ attr_cast(Expr const& expr)
+ {
+ return stateful_tag_type<Expr, tag::attr_cast, Exposed>(expr);
+ }
+
+ template <typename Exposed, typename Transformed, typename Expr>
+ typename enable_if<proto::is_expr<Expr>
+ , stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed> >::type
+ attr_cast(Expr const& expr)
+ {
+ return stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed>(expr);
+ }
+}}
+
+namespace boost { namespace spirit { namespace qi
+{
+ using spirit::attr_cast;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // attr_cast_parser consumes the attribute of subject generator without
+ // generating anything
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Exposed, typename Transformed, typename Subject>
+ struct attr_cast_parser
+ : unary_parser<attr_cast_parser<Exposed, Transformed, Subject> >
+ {
+ typedef typename result_of::compile<qi::domain, Subject>::type
+ subject_type;
+
+ typedef typename mpl::eval_if<
+ traits::is_not_unused<Transformed>
+ , mpl::identity<Transformed>
+ , traits::attribute_of<subject_type> >::type
+ transformed_attribute_type;
+
+ attr_cast_parser(Subject const& subject)
+ : subject(subject)
+ {
+ // If you got an error_invalid_expression error message here,
+ // then the expression (Subject) is not a valid spirit qi
+ // expression.
+ BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Subject);
+ }
+
+ // If Exposed is given, we use the given type, otherwise all we can do
+ // is to guess, so we expose our inner type as an attribute and
+ // deal with the passed attribute inside the parse function.
+ template <typename Context, typename Iterator>
+ struct attribute
+ : mpl::if_<traits::is_not_unused<Exposed>, Exposed
+ , transformed_attribute_type>
+ {};
+
+ template <typename Iterator, typename Context, typename Skipper
+ , typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr) const
+ {
+ // Find the real exposed attribute. If exposed is given, we use it
+ // otherwise we assume the exposed attribute type to be the actual
+ // attribute type as passed by the user.
+ typedef typename mpl::if_<
+ traits::is_not_unused<Exposed>, Exposed, Attribute>::type
+ exposed_attribute_type;
+
+ // do down-stream transformation, provides attribute for embedded
+ // parser
+ typedef typename traits::result_of::pre_transform<
+ exposed_attribute_type, transformed_attribute_type>::type
+ attribute_type;
+
+ attribute_type attr_ =
+ traits::pre_transform<transformed_attribute_type>(attr);
+
+ if (!compile<qi::domain>(subject).
+ parse(first, last, context, skipper, attr_))
+ {
+ return false;
+ }
+
+ // do up-stream transformation, this mainly integrates the results
+ // back into the original attribute value, if appropriate
+ traits::post_transform(attr, attr_);
+ return true;
+ }
+
+ template <typename Context>
+ info what(Context& context) const
+ {
+ return info("attr_cast"
+ , compile<qi::domain>(subject).what(context));
+ }
+
+ Subject subject;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Parser generator: make_xxx function (objects)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Expr, typename Exposed, typename Transformed
+ , typename Modifiers>
+ struct make_primitive<
+ tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
+ {
+ typedef attr_cast_parser<Exposed, Transformed, Expr> result_type;
+
+ template <typename Terminal>
+ result_type operator()(Terminal const& term, unused_type) const
+ {
+ typedef tag::stateful_tag<
+ Expr, tag::attr_cast, Exposed, Transformed> tag_type;
+ using spirit::detail::get_stateful_data;
+ return result_type(get_stateful_data<tag_type>::call(term));
+ }
+ };
+
+
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/qi/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/qi/binary/binary.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -193,7 +193,7 @@
             }
 
             first = it;
- detail::assign_to(attr_, attr);
+ spirit::traits::assign_to(attr_, attr);
             return true;
         }
 
@@ -244,7 +244,7 @@
             }
 
             first = it;
- detail::assign_to(attr_, attr);
+ spirit::traits::assign_to(attr_, attr);
             return true;
         }
 

Modified: trunk/boost/spirit/home/qi/char/char_parser.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/char/char_parser.hpp (original)
+++ trunk/boost/spirit/home/qi/char/char_parser.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -67,7 +67,7 @@
 
             if (first != last && this->derived().test(*first, context))
             {
- qi::detail::assign_to(*first, attr);
+ spirit::traits::assign_to(*first, attr);
                 ++first;
                 return true;
             }

Modified: trunk/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/assign_to.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/assign_to.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -15,116 +15,87 @@
 
 #include <boost/spirit/home/qi/detail/construct.hpp>
 #include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attributes_fwd.hpp>
+#include <boost/spirit/home/phoenix/core/actor.hpp>
 #include <boost/ref.hpp>
 
-namespace boost { namespace spirit { namespace qi { namespace detail
+namespace boost { namespace spirit { namespace traits
 {
- namespace construct_
+ ///////////////////////////////////////////////////////////////////////////
+ // This file contains assignment utilities. The utilities provided also
+ // accept spirit's unused_type; all no-ops. Compiler optimization will
+ // easily strip these away.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Iterator, typename Enable>
+ struct assign_to_attribute_from_iterators
     {
- ///////////////////////////////////////////////////////////////////////
- // This is used to allow to overload of the attribute creation for
- // arbitrary types
- ///////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename Iterator>
- inline void
- construct(Attribute& attr, Iterator const& first, Iterator const& last)
+ static void
+ call(Iterator const& first, Iterator const& last, Attribute& attr)
         {
             attr = Attribute(first, last);
         }
+ };
 
- template <typename Attribute, typename T>
- inline void
- construct(Attribute& attr, T const& val)
- {
- attr = val;
- }
-
- template <typename Attribute, typename T>
- inline void
- construct(Attribute& attr, T& val)
- {
- attr = val;
- }
-
- template <typename Attribute, typename T>
- inline void
- construct(reference_wrapper<Attribute> attr, T const& val)
+ template <typename Attribute, typename Iterator>
+ struct assign_to_attribute_from_iterators<
+ reference_wrapper<Attribute>, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last
+ , reference_wrapper<Attribute> attr)
         {
- attr = val;
- }
-
- template <typename Attribute, typename T>
- inline void
- construct(reference_wrapper<Attribute> attr, T& val)
- {
- attr = val;
+ attr = Attribute(first, last);
         }
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // This file contains assignment utilities. The utilities provided also
- // accept spirit's unused_type; all no-ops. Compiler optimization will
- // easily strip these away.
- ///////////////////////////////////////////////////////////////////////////
+ };
 
     template <typename Iterator, typename Attribute>
     inline void
     assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
     {
- using namespace construct_;
- construct(attr, first, last);
+ assign_to_attribute_from_iterators<Attribute, Iterator>::
+ call(first, last, attr);
     }
 
     template <typename Iterator>
     inline void
- assign_to(Iterator const& /*first*/, Iterator const& /*last*/, unused_type)
+ assign_to(Iterator const&, Iterator const&, unused_type)
     {
     }
 
- template <typename T, typename Attribute>
- inline void
- assign_to(T const& val, Attribute& attr)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename T, typename Enable>
+ struct assign_to_attribute_from_value
     {
- using namespace construct_;
- construct(attr, val);
- }
+ static void
+ call(T const& val, Attribute& attr)
+ {
+ attr = val;
+ }
+ };
 
- template <typename T, typename Attribute>
- inline void
- assign_to(T& val, Attribute& attr)
+ template <typename Attribute, typename T>
+ struct assign_to_attribute_from_value<reference_wrapper<Attribute>, T>
     {
- using namespace construct_;
- construct(attr, val);
- }
-
- template <typename T, typename Attribute>
- inline void
- assign_to(T const& val, reference_wrapper<Attribute> attr)
- {
- using namespace construct_;
- construct(attr, val);
- }
+ static void
+ call(T const& val, reference_wrapper<Attribute> attr)
+ {
+ attr = val;
+ }
+ };
 
     template <typename T, typename Attribute>
     inline void
- assign_to(T& val, reference_wrapper<Attribute> attr)
- {
- using namespace construct_;
- construct(attr, val);
- }
-
- template <typename T>
- inline void
- assign_to(T const& /*val*/, unused_type)
+ assign_to(T const& val, Attribute& attr)
     {
+ assign_to_attribute_from_value<Attribute, T>::call(val, attr);
     }
 
     template <typename T>
     inline void
- assign_to(T& /*val*/, unused_type)
+ assign_to(T const&, unused_type)
     {
     }
 
-}}}}
+}}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/detail/construct.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/construct.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/construct.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -12,135 +12,171 @@
 #pragma once
 #endif
 
+#include <boost/config.hpp>
 #include <boost/spirit/home/qi/parse.hpp>
 #include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/attributes_fwd.hpp>
 
-namespace boost { namespace spirit { namespace qi { namespace detail
+namespace boost { namespace spirit { namespace traits
 {
- namespace construct_
+ ///////////////////////////////////////////////////////////////////////////
+ // We provide overloads for the assign_to_attribute_from_iterators
+ // customization point for all built in types
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<char, Iterator>
     {
- ///////////////////////////////////////////////////////////////////////
- // We provide overloads for the construct customization point for all
- // built in types
- ///////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- inline void
- construct(char& attr, Iterator const& first, Iterator const& last)
+ static void
+ call(Iterator const& first, Iterator const& last, char& attr)
         {
             attr = *first;
         }
+ };
 
-#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- // wchar_t is intrinsic
- template <typename Iterator>
- inline void
- construct(wchar_t& attr, Iterator const& first, Iterator const& last)
+ // wchar_t is intrinsic
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<wchar_t, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, wchar_t& attr)
         {
             attr = *first;
         }
- template <typename Iterator>
- inline void
- construct(unsigned short& attr, Iterator const& first,
- Iterator const& last)
- {
- Iterator first_ = first;
- parse(first_, last, ushort_, attr);
- }
-#else
- // is wchar_t is not an intrinsic type, treat wchar_t only
- template <typename Iterator>
- inline void
- construct(wchar_t& attr, Iterator const& first, Iterator const& last)
+ };
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+ // wchar_t is intrinsic, have separate overload for unsigned short
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<unsigned short, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, unsigned short& attr)
         {
             attr = *first;
         }
+ };
 #endif
 
- template <typename Iterator>
- inline void
- construct(short& attr, Iterator const& first, Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<bool, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, char& attr)
+ {
+ Iterator first_ = first;
+ qi::parse(first_, last, bool_, attr);
+ }
+ };
+
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<short, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, short& attr)
         {
             Iterator first_ = first;
- parse(first_, last, short_, attr);
+ qi::parse(first_, last, short_, attr);
         }
+ };
 
- template <typename Iterator>
- inline void
- construct(int& attr, Iterator const& first, Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<int, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, int& attr)
         {
             Iterator first_ = first;
- parse(first_, last, int_, attr);
+ qi::parse(first_, last, int_, attr);
         }
- template <typename Iterator>
- inline void
- construct(unsigned int& attr, Iterator const& first,
- Iterator const& last)
+ };
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<unsigned int, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, unsigned int& attr)
         {
             Iterator first_ = first;
- parse(first_, last, uint_, attr);
+ qi::parse(first_, last, uint_, attr);
         }
+ };
 
- template <typename Iterator>
- inline void
- construct(long& attr, Iterator const& first, Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<long, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, long& attr)
         {
             Iterator first_ = first;
- parse(first_, last, long_, attr);
+ qi::parse(first_, last, long_, attr);
         }
- template <typename Iterator>
- inline void
- construct(unsigned long& attr, Iterator const& first,
- Iterator const& last)
+ };
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<unsigned long, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, unsigned long& attr)
         {
             Iterator first_ = first;
- parse(first_, last, ulong_, attr);
+ qi::parse(first_, last, ulong_, attr);
         }
+ };
 
 #ifdef BOOST_HAS_LONG_LONG
- template <typename Iterator>
- inline void
- construct(boost::long_long_type& attr, Iterator const& first,
- Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<long_long_type, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, long_long_type& attr)
         {
             Iterator first_ = first;
- parse(first_, last, long_long, attr);
+ qi::parse(first_, last, long_long, attr);
         }
- template <typename Iterator>
- inline void
- construct(boost::ulong_long_type& attr, Iterator const& first,
- Iterator const& last)
+ };
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<ulong_long_type, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, ulong_long_type& attr)
         {
             Iterator first_ = first;
- parse(first_, last, ulong_long, attr);
+ qi::parse(first_, last, ulong_long, attr);
         }
+ };
 #endif
 
- template <typename Iterator>
- inline void
- construct(float& attr, Iterator const& first, Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<float, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, float& attr)
         {
             Iterator first_ = first;
- parse(first_, last, float_, attr);
+ qi::parse(first_, last, float_, attr);
         }
+ };
 
- template <typename Iterator>
- inline void
- construct(double& attr, Iterator const& first, Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<double, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, double& attr)
         {
             Iterator first_ = first;
- parse(first_, last, double_, attr);
+ qi::parse(first_, last, double_, attr);
         }
+ };
 
- template <typename Iterator>
- inline void
- construct(long double& attr, Iterator const& first,
- Iterator const& last)
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<long double, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, long double& attr)
         {
             Iterator first_ = first;
- parse(first_, last, long_double, attr);
+ qi::parse(first_, last, long_double, attr);
         }
- }
+ };
 
-}}}}
+}}}
 
 #endif

Modified: trunk/boost/spirit/home/qi/detail/string_parse.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/string_parse.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/string_parse.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -30,7 +30,7 @@
             ch = *++str;
         }
 
- detail::assign_to(first, i, attr);
+ spirit::traits::assign_to(first, i, attr);
         first = i;
         return true;
     }
@@ -47,7 +47,7 @@
         for (; stri != str_last; ++stri, ++i)
             if (i == last || (*stri != *i))
                 return false;
- detail::assign_to(first, i, attr);
+ spirit::traits::assign_to(first, i, attr);
         first = i;
         return true;
     }
@@ -62,7 +62,7 @@
         for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
             if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
                 return false;
- detail::assign_to(first, i, attr);
+ spirit::traits::assign_to(first, i, attr);
         first = i;
         return true;
     }
@@ -80,7 +80,7 @@
         for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
             if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
                 return false;
- detail::assign_to(first, i, attr);
+ spirit::traits::assign_to(first, i, attr);
         first = i;
         return true;
     }

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -58,7 +58,7 @@
             Iterator i = first;
             if (subject.parse(i, last, context, skipper, unused))
             {
- detail::assign_to(first, i, attr);
+ spirit::traits::assign_to(first, i, attr);
                 first = i;
                 return true;
             }

Modified: trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -21,6 +21,7 @@
     template <typename Parser, typename Auto>
     struct parser_binder
     {
+
         parser_binder(Parser const& p)
           : p(p) {}
 
@@ -37,6 +38,29 @@
         bool call(Iterator& first, Iterator const& last
           , Context& context, Skipper const& skipper, mpl::false_) const
         {
+// typedef typename traits::attribute_of<Parser>::type
+// subject_attribute_type;
+// typedef typename Context::attributes_type context_attributes_type;
+// typedef typename fusion::result_of::at_c<
+// context_attributes_type, 0>::type attribute_type;
+//
+// // do down-stream transformation, provides attribute for embedded
+// // parser
+// typename traits::result_of::pre_transform<
+// subject_attribute_type, attribute_type>::type
+// attr_ = traits::pre_transform<subject_attribute_type>(
+// fusion::at_c<0>(context.attributes));
+//
+// // If DeducedAuto is true (no semantic action), we pass the rule's
+// // attribute on to the component.
+// if (!p.parse(first, last, context, skipper, attr_))
+// return false;
+//
+// // do up-stream transformation, this mainly integrates the results
+// // back into the original attribute value, if appropriate
+// traits::post_transform<subject_attribute_type>(attr_
+// , fusion::at_c<0>(context.attributes));
+
             // If DeducedAuto is true (no semantic action), we pass the rule's
             // attribute on to the component.
             return p.parse(first, last, context, skipper

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -214,9 +214,7 @@
             
             if (f)
             {
- // Create an attribute if none is supplied.
- typedef traits::make_transformed_attribute<
- attr_type, Attribute> make_attribute;
+ typedef traits::make_attribute<attr_type, Attribute> make_attribute;
 
                 typename make_attribute::type attr_ = make_attribute::call(attr);
 
@@ -247,9 +245,7 @@
 
             if (f)
             {
- // Create an attribute if none is supplied.
- typedef traits::make_transformed_attribute<
- attr_type, Attribute> make_attribute;
+ typedef traits::make_attribute<attr_type, Attribute> make_attribute;
 
                 typename make_attribute::type attr_ = make_attribute::call(attr);
 

Modified: trunk/boost/spirit/home/qi/numeric/bool_policies.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/bool_policies.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/bool_policies.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -28,7 +28,7 @@
         {
             if (detail::string_parse("true", first, last, unused))
             {
- detail::assign_to(T(true), attr); // result is true
+ spirit::traits::assign_to(T(true), attr); // result is true
                 return true;
             }
             return false;
@@ -40,7 +40,7 @@
         {
             if (detail::string_parse("false", first, last, unused))
             {
- detail::assign_to(T(false), attr); // result is false
+ spirit::traits::assign_to(T(false), attr); // result is false
                 return true;
             }
             return false;

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 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -66,7 +66,7 @@
             if (subject.parse(first, last, context, skipper, val))
             {
                 // assign the parsed value into our attribute
- qi::detail::assign_to(val, attr);
+ spirit::traits::assign_to(val, attr);
             }
             return true;
         }

Modified: trunk/boost/spirit/home/qi/string/symbols.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/string/symbols.hpp (original)
+++ trunk/boost/spirit/home/qi/string/symbols.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -204,7 +204,7 @@
             if (value_type* val_ptr
                 = lookup->find(first, last, Filter()))
             {
- detail::assign_to(*val_ptr, attr);
+ spirit::traits::assign_to(*val_ptr, attr);
                 return true;
             }
             return false;

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -14,6 +14,7 @@
 
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/has_semantic_action.hpp>
+#include <boost/spirit/home/support/attributes_fwd.hpp>
 #include <boost/spirit/home/support/detail/as_variant.hpp>
 #include <boost/optional/optional.hpp>
 #include <boost/fusion/include/transform.hpp>
@@ -42,11 +43,13 @@
 
     template <typename T>
     struct not_is_variant
- : mpl::true_ {};
+ : mpl::true_
+ {};
 
     template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
     struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : mpl::false_ {};
+ : mpl::false_
+ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // attribute_of
@@ -86,7 +89,7 @@
     // a single value in any case (even if it actually already is a fusion
     // sequence in its own).
     ///////////////////////////////////////////////////////////////////////////
- template <typename Component, typename Attribute, typename Enable = void>
+ template <typename Component, typename Attribute, typename Enable/* = void*/>
     struct pass_attribute
     {
         typedef fusion::vector1<Attribute&> type;
@@ -309,40 +312,58 @@
     // attributes. This template can be used as a customization point, where
     // the user is able specify specific transformation rules for any attribute
     // type.
- template <typename Destination, typename Source>
+ template <typename Exposed, typename Transformed, typename Enable/* = void*/>
     struct transform_attribute
     {
- static Destination call(Source& val) { return Destination(val); }
- };
-
- template <typename Destination, typename Source>
- struct transform_attribute<Destination, Source const>
- {
- static Destination call(Source const& val) { return Destination(val); }
+ typedef Transformed type;
+ static Transformed pre(Exposed& val) { return Transformed(val); }
+ static void post(Exposed&, Transformed const&) {}
     };
 
     // The default is not to do any transformation
     template <typename Attribute>
     struct transform_attribute<Attribute, Attribute>
     {
- static Attribute& call(Attribute& val) { return val; }
+ typedef Attribute& type;
+ static Attribute& pre(Attribute& val) { return val; }
+ static void post(Attribute&, Attribute const&) {}
     };
 
     template <typename Attribute>
- struct transform_attribute<Attribute, Attribute const>
+ struct transform_attribute<Attribute const, Attribute>
     {
- static Attribute const& call(Attribute const& val) { return val; }
+ typedef Attribute const& type;
+ static Attribute const& pre(Attribute const& val) { return val; }
+ static void post(Attribute const&, Attribute const&) {}
     };
 
- // unused_type needs some special handling
+ // reference types need special handling
+ template <typename Exposed, typename Transformed>
+ struct transform_attribute<Exposed&, Transformed>
+ : transform_attribute<Exposed, Transformed>
+ {};
+
+ template <typename Attribute>
+ struct transform_attribute<Attribute&, Attribute>
+ : transform_attribute<Attribute, Attribute>
+ {};
+
+ template <typename Attribute>
+ struct transform_attribute<Attribute const&, Attribute>
+ : transform_attribute<Attribute const, Attribute>
+ {};
+
+ // unused_type needs some special handling as well
     template <>
     struct transform_attribute<unused_type, unused_type>
     {
- static unused_type call(unused_type) { return unused; }
+ typedef unused_type type;
+ static unused_type pre(unused_type) { return unused; }
+ static void post(unused_type, unused_type) {}
     };
 
     template <>
- struct transform_attribute<unused_type, unused_type const>
+ struct transform_attribute<unused_type const, unused_type>
       : transform_attribute<unused_type, unused_type>
     {};
 
@@ -352,20 +373,43 @@
     {};
 
     template <typename Attribute>
- struct transform_attribute<unused_type, Attribute const>
- : transform_attribute<unused_type, unused_type>
- {};
-
- template <typename Attribute>
     struct transform_attribute<Attribute, unused_type>
       : transform_attribute<unused_type, unused_type>
     {};
 
     template <typename Attribute>
- struct transform_attribute<Attribute, unused_type const>
+ struct transform_attribute<Attribute const, unused_type>
       : transform_attribute<unused_type, unused_type>
     {};
 
+ namespace result_of
+ {
+ template <typename Exposed, typename Transformed, typename Enable/* = void*/>
+ struct pre_transform
+ : traits::transform_attribute<Exposed, Transformed>
+ {};
+ }
+
+ template <typename Transformed, typename Exposed>
+ typename traits::result_of::pre_transform<Exposed, Transformed>::type
+ pre_transform(Exposed& attr)
+ {
+ return transform_attribute<Exposed, Transformed>::pre(attr);
+ }
+
+ template <typename Transformed, typename Exposed>
+ typename traits::result_of::pre_transform<Exposed const, Transformed>::type
+ pre_transform(Exposed const& attr)
+ {
+ return transform_attribute<Exposed const, Transformed>::pre(attr);
+ }
+
+ template <typename Exposed, typename Transformed>
+ void post_transform(Exposed& dest, Transformed const& attr)
+ {
+ return transform_attribute<Exposed, Transformed>::post(dest, attr);
+ }
+
     ///////////////////////////////////////////////////////////////////////////
     // make_attribute
     //
@@ -429,64 +473,6 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Attribute, typename ActualAttribute>
- struct make_transformed_attribute
- {
- // We assume that as soon as the source and destination attribute types
- // are not the same we need to create a new instance of the destination
- // in order to do the conversion. In this case we can't just pass
- // through the references anymore (as it's done in the template
- // make_attribute above).
- typedef typename remove_const<ActualAttribute>::type
- non_const_actual_attribute;
-
- typedef typename
- mpl::if_<
- is_same<non_const_actual_attribute, Attribute>
- , ActualAttribute&
- , Attribute>::type
- attribute_type;
-
- typedef typename
- mpl::if_<
- is_same<non_const_actual_attribute, unused_type>
- , typename remove_const<Attribute>::type
- , attribute_type>::type
- type;
-
- static Attribute call(unused_type)
- {
- // synthesize the attribute/parameter
- return boost::get(value_initialized<Attribute>());
- }
-
- template <typename T>
- static type call(T& value)
- {
- // create the proper attribute transformation
- typedef transform_attribute<Attribute, ActualAttribute> transform;
-
- // return either the transformed value or pass 'value' through
- return transform::call(value);
- }
- };
-
- template <typename Attribute, typename ActualAttribute>
- struct make_transformed_attribute<Attribute&, ActualAttribute>
- : make_attribute<Attribute, ActualAttribute>
- {};
-
- template <typename Attribute, typename ActualAttribute>
- struct make_transformed_attribute<Attribute const&, ActualAttribute>
- : make_attribute<Attribute, ActualAttribute>
- {};
-
- template <typename ActualAttribute>
- struct make_transformed_attribute<unused_type, ActualAttribute>
- : make_attribute<unused_type, ActualAttribute>
- {};
-
- ///////////////////////////////////////////////////////////////////////////
     // swap_impl
     //
     // Swap (with proper handling of unused_types)
@@ -547,13 +533,19 @@
     // sequence
     ///////////////////////////////////////////////////////////////////////////
     template <typename T>
- struct one_element_sequence : mpl::false_ {};
+ struct one_element_sequence
+ : mpl::false_
+ {};
 
     template <typename T>
- struct one_element_sequence<fusion::vector1<T> > : mpl::true_ {};
+ struct one_element_sequence<fusion::vector1<T> >
+ : mpl::true_
+ {};
 
     template <typename T>
- struct one_element_sequence<fusion::vector<T> > : mpl::true_ {};
+ struct one_element_sequence<fusion::vector<T> >
+ : mpl::true_
+ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // clear
@@ -561,7 +553,7 @@
     // Clear data efficiently
     ///////////////////////////////////////////////////////////////////////////
     template <typename T>
- struct is_container;
+ void clear(T& val);
 
     namespace detail
     {
@@ -604,31 +596,46 @@
         }
     }
 
- // main dispatch
+ template <typename T, typename Enable/* = void*/>
+ struct clear_value
+ {
+ static void call(T& val)
+ {
+ detail::clear_impl(val, typename is_container<T>::type());
+ }
+ };
+
+ // optionals
     template <typename T>
- void clear(T& val)
+ struct clear_value<optional<T> >
     {
- detail::clear_impl(val, typename is_container<T>::type());
- }
+ static void call(optional<T>& val)
+ {
+ if (val)
+ clear(*val);
+ }
+ };
 
- // for unused
- inline void clear(unused_type)
+ // variants
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct clear_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
     {
- }
+ static void call(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& val)
+ {
+ apply_visitor(detail::clear_visitor(), val);
+ }
+ };
 
- // optionals
+ // main dispatch
     template <typename T>
- void clear(optional<T>& val)
+ void clear(T& val)
     {
- if (val)
- clear(*val);
+ clear_value<T>::call(val);
     }
 
- // variants
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- void clear(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& var)
+ // for unused
+ inline void clear(unused_type)
     {
- apply_visitor(detail::clear_visitor(), var);
     }
 
 }}}

Added: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Hartmut Kaiser
+ Copyright (c) 2001-2009 Joel de Guzman
+
+ 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_ATTRIBUTES_FWD_OCT_01_2009_0715AM)
+#define BOOST_SPIRIT_ATTRIBUTES_FWD_OCT_01_2009_0715AM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+namespace boost { namespace spirit { namespace traits
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // Determines how we pass attributes to semantic actions. This
+ // may be specialized. By default, all attributes are wrapped in
+ // a fusion sequence, because the attribute has to be treated as being
+ // a single value in any case (even if it actually already is a fusion
+ // sequence in its own).
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Component, typename Attribute, typename Enable = void>
+ struct pass_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct optional_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Sometimes the user needs to transform the attribute types for certain
+ // attributes. This template can be used as a customization point, where
+ // the user is able specify specific transformation rules for any attribute
+ // type.
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ ///////////////////////////////////////////////////////////////////////
+ // Attribute type to be returned by pre_transform()
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T, typename Attribute, typename Enable = void>
+ struct pre_transform;
+ }
+
+ template <typename Exposed, typename Transformed, typename Enable = void>
+ struct transform_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Iterator, typename Enable = void>
+ struct assign_to_attribute_from_iterators;
+
+ template <typename Attribute, typename T, typename Enable = void>
+ struct assign_to_attribute_from_value;
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ ///////////////////////////////////////////////////////////////////////
+ // Attribute type to be extracted by extract_from()
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Enable = void>
+ struct extract_from;
+ }
+
+ template <typename Attribute, typename Enable = void>
+ struct extract_from_attribute;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Clear data efficiently
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct clear_value;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Determine the value type of the given container type
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct container_value;
+
+ template <typename T, typename Enable = void>
+ struct is_container;
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename T, typename Enable = void>
+ struct push_back_container;
+
+ ///////////////////////////////////////////////////////////////////////////
+ namespace result_of
+ {
+ ///////////////////////////////////////////////////////////////////////
+ // Determine the iterator type of the given container type
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable = void>
+ struct iterator;
+ }
+
+ template <typename Container, typename Enable = void>
+ struct begin_container;
+
+ template <typename Container, typename Enable = void>
+ struct end_container;
+
+ template <typename Iterator, typename Enable = void>
+ struct deref_iterator;
+
+ template <typename Iterator, typename Enable = void>
+ struct next_iterator;
+
+ template <typename Iterator, typename Enable = void>
+ struct compare_iterators;
+
+}}}
+
+#endif
+

Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp (original)
+++ trunk/boost/spirit/home/support/container.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -14,6 +14,7 @@
 #endif
 
 #include <boost/spirit/home/support/unused.hpp>
+#include <boost/spirit/home/support/attributes_fwd.hpp>
 #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/bool.hpp>
@@ -38,19 +39,19 @@
         BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
     }
 
- template <typename T>
- struct is_container :
- mpl::bool_<
+ template <typename T, typename Enable/* = void*/>
+ struct is_container
+ : mpl::bool_<
             detail::has_value_type<T>::value &&
             detail::has_iterator<T>::value &&
             detail::has_size_type<T>::value &&
- detail::has_reference<T>::value
- >
+ detail::has_reference<T>::value>
     {};
 
    template <typename T>
    struct is_container<optional<T> >
- : is_container<T> {};
+ : is_container<T>
+ {};
 
 #define BOOST_SPIRIT_IS_CONTAINER(z, N, data) \
        is_container<BOOST_PP_CAT(T, N)>::value || \
@@ -59,7 +60,8 @@
    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
    struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
      : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
- , BOOST_SPIRIT_IS_CONTAINER, _) false> {};
+ , BOOST_SPIRIT_IS_CONTAINER, _) false>
+ {};
 
 #undef BOOST_SPIRIT_IS_CONTAINER
 
@@ -73,7 +75,8 @@
         };
 
         template <typename T>
- struct remove_value_const<T const> : remove_value_const<T>
+ struct remove_value_const<T const>
+ : remove_value_const<T>
         {};
 
         template <typename F, typename S>
@@ -85,55 +88,10 @@
         };
     }
 
- ///////////////////////////////////////////////////////////////////////
- template <typename Container>
- struct container_value
- {
- typedef typename detail::remove_value_const<
- typename Container::value_type>::type
- type;
- };
-
- // this will be instantiated if the optional holds a container
- template <typename T>
- struct container_value<optional<T> > : container_value<T> {};
-
- // this will be instantiated if the variant holds a container
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- {
- typedef typename
- variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
- types;
- typedef typename
- mpl::find_if<types, is_container<mpl::_1> >::type
- iter;
-
- typedef typename container_value<
- typename mpl::if_<
- is_same<iter, typename mpl::end<types>::type>
- , unused_type, typename mpl::deref<iter>::type
- >::type
- >::type type;
- };
-
- template <>
- struct container_value<unused_type>
- {
- typedef unused_type type;
- };
-
- template <>
- struct container_value<unused_type const>
- {
- typedef unused_type type;
- };
-
- ///////////////////////////////////////////////////////////////////////
-
     namespace result_of
     {
- template <typename Container>
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable/* = void*/>
         struct iterator
         {
             typedef typename Container::iterator type;
@@ -170,6 +128,12 @@
             typedef T type;
         };
 
+ template <typename T>
+ struct optional_value<optional<T> const>
+ {
+ typedef T const type;
+ };
+
         template <>
         struct optional_value<unused_type>
         {
@@ -183,34 +147,114 @@
         };
     }
 
+ ///////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable/* = void*/>
+ struct container_value
+ : detail::remove_value_const<typename Container::value_type>
+ {};
+
+ // this will be instantiated if the optional holds a container
+ template <typename T>
+ struct container_value<optional<T> >
+ : container_value<T>
+ {};
+
+ // this will be instantiated if the variant holds a container
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ {
+ typedef typename
+ variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
+ types;
+ typedef typename
+ mpl::find_if<types, is_container<mpl::_1> >::type
+ iter;
+
+ typedef typename container_value<
+ typename mpl::if_<
+ is_same<iter, typename mpl::end<types>::type>
+ , unused_type, typename mpl::deref<iter>::type
+ >::type
+ >::type type;
+ };
+
+ template <>
+ struct container_value<unused_type>
+ {
+ typedef unused_type type;
+ };
+
+ template <>
+ struct container_value<unused_type const>
+ {
+ typedef unused_type type;
+ };
+
     ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable/* = void*/>
+ struct optional_attribute
+ {
+ typedef T const& type;
+
+ static type call(T const& val)
+ {
+ return val;
+ }
+
+ static bool is_valid(T const&)
+ {
+ return true;
+ }
+ };
+
     template <typename T>
- T const& optional_value(T const& v)
+ struct optional_attribute<optional<T> >
     {
- return v;
- }
+ typedef T const& type;
+
+ static type call(optional<T> const& val)
+ {
+ return boost::get<T>(val);
+ }
+
+ static bool is_valid(optional<T> const& val)
+ {
+ return val;
+ }
+ };
 
     template <typename T>
- T const& optional_value(boost::optional<T> const& v)
+ struct optional_attribute<optional<T const> >
     {
- return boost::get<T>(v);
- }
+ typedef T const& type;
 
- inline unused_type optional_value(unused_type)
+ static type call(optional<T const> const& val)
+ {
+ return boost::get<T const>(val);
+ }
+
+ static bool is_valid(optional<T const> const& val)
+ {
+ return val;
+ }
+ };
+
+ template <typename T>
+ typename optional_attribute<T>::type
+ optional_value(T const& val)
     {
- return unused;
+ return optional_attribute<T>::call(val);
     }
 
- template <typename T>
- bool has_optional_value(T const&)
+ inline unused_type optional_value(unused_type)
     {
- return true;
+ return unused;
     }
 
     template <typename T>
- bool has_optional_value(boost::optional<T> const& v)
+ bool has_optional_value(T const& val)
     {
- return v;
+ return optional_attribute<T>::is_valid(val);
     }
 
     inline bool has_optional_value(unused_type)
@@ -220,18 +264,27 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Container, typename T>
- inline void push_back(Container& c, T const& val)
+ void push_back(Container& c, T const& val);
+
+ template <typename Container, typename T, typename Enable/* = void*/>
+ struct push_back_container
     {
- c.insert(c.end(), val);
- }
+ static void call(Container& c, T const& val)
+ {
+ c.insert(c.end(), val);
+ }
+ };
 
     template <typename Container, typename T>
- inline void push_back(optional<Container>& c, T const& val)
+ struct push_back_container<optional<Container>, T>
     {
- if (!c)
- c = Container();
- push_back(boost::get<Container>(c), val);
- }
+ static void call(optional<Container>& c, T const& val)
+ {
+ if (!c)
+ c = Container();
+ push_back(boost::get<Container>(c), val);
+ }
+ };
 
     namespace detail
     {
@@ -264,19 +317,27 @@
     }
 
     template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T>
- inline void push_back(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c
- , T const& val)
+ struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T>
+ {
+ static void call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
+ {
+ apply_visitor(detail::push_back_visitor<T>(val), c);
+ }
+ };
+
+ template <typename Container, typename T>
+ void push_back(Container& c, T const& val)
     {
- apply_visitor(detail::push_back_visitor<T>(val), c);
+ push_back_container<Container, T>::call(c, val);
     }
 
     template <typename Container>
- inline void push_back(Container&, unused_type)
+ void push_back(Container&, unused_type)
     {
     }
 
     template <typename T>
- inline void push_back(unused_type, T const&)
+ void push_back(unused_type, T const&)
     {
     }
 
@@ -285,18 +346,29 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Container>
- inline typename result_of::iterator<Container>::type
- begin(Container& c)
+ template <typename Container, typename Enable/* = void*/>
+ struct begin_container
     {
- return c.begin();
+ typedef typename result_of::iterator<Container>::type type;
+ static type call(Container& c)
+ {
+ return c.begin();
+ }
+ };
+
+ namespace result_of
+ {
+ template <typename Container>
+ struct begin
+ : traits::begin_container<Container>
+ {};
     }
 
     template <typename Container>
- inline typename result_of::iterator<Container const>::type
- begin(Container const& c)
+ typename begin_container<Container>::type
+ begin(Container& c)
     {
- return c.begin();
+ return begin_container<Container>::call(c);
     }
 
     inline unused_type const*
@@ -305,18 +377,30 @@
         return &unused;
     }
 
- template <typename Container>
- inline typename result_of::iterator<Container>::type
- end(Container& c)
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Container, typename Enable/* = void*/>
+ struct end_container
     {
- return c.end();
+ typedef typename result_of::iterator<Container>::type type;
+ static type call(Container& c)
+ {
+ return c.end();
+ }
+ };
+
+ namespace result_of
+ {
+ template <typename Container>
+ struct end
+ : traits::end_container<Container>
+ {};
     }
 
     template <typename Container>
- inline typename result_of::iterator<Container const>::type
- end(Container const& c)
+ inline typename end_container<Container>::type
+ end(Container& c)
     {
- return c.end();
+ return end_container<Container>::call(c);
     }
 
     inline unused_type const*
@@ -326,17 +410,29 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- inline typename boost::detail::iterator_traits<Iterator>::reference
- deref(Iterator& it)
+ template <typename Iterator, typename Enable/* = void*/>
+ struct deref_iterator
     {
- return *it;
+ typedef typename boost::detail::iterator_traits<Iterator>::reference type;
+ static type call(Iterator& it)
+ {
+ return *it;
+ }
+ };
+
+ namespace result_of
+ {
+ template <typename Iterator>
+ struct deref
+ : traits::deref_iterator<Iterator>
+ {};
     }
 
- inline unused_type
- deref(unused_type*)
+ template <typename Iterator>
+ typename deref_iterator<Iterator>::type
+ deref(Iterator& it)
     {
- return unused;
+ return deref_iterator<Iterator>::call(it);
     }
 
     inline unused_type
@@ -346,43 +442,56 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- inline Iterator
- next(Iterator& it)
+ template <typename Iterator, typename Enable/* = void*/>
+ struct next_iterator
     {
- return ++it;
+ typedef Iterator type;
+ static type call(Iterator& it)
+ {
+ return ++it;
+ }
+ };
+
+ namespace result_of
+ {
+ template <typename Iterator>
+ struct next
+ : traits::next_iterator<Iterator>
+ {};
     }
 
- inline unused_type
- next(unused_type*)
+ template <typename Iterator>
+ typename next_iterator<Iterator>::type
+ next(Iterator& it)
     {
- return &unused;
+ return next_iterator<Iterator>::call(it);
     }
 
     inline unused_type
     next(unused_type const*)
     {
- return &unused;
+ return unused;
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Iterator>
- inline bool
- compare(Iterator const& it1, Iterator const& it2)
+ template <typename Iterator, typename Enable/* = void*/>
+ struct compare_iterators
     {
- return it1 == it2;
- }
+ static bool call(Iterator const& it1, Iterator const& it2)
+ {
+ return it1 == it2;
+ }
+ };
 
- inline bool
- compare(unused_type*, unused_type*)
+ template <typename Iterator>
+ bool compare(Iterator& it1, Iterator& it2)
     {
- return true;
+ return compare_iterators<Iterator>::call(it1, it2);
     }
 
- inline bool
- compare(unused_type const*, unused_type const*)
+ inline bool compare(unused_type const*, unused_type const*)
     {
- return true;
+ return false;
     }
 
 }}}

Modified: trunk/boost/spirit/home/support/terminal.hpp
==============================================================================
--- trunk/boost/spirit/home/support/terminal.hpp (original)
+++ trunk/boost/spirit/home/support/terminal.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -436,7 +436,8 @@
     // support for stateful tag types
     namespace tag
     {
- template <typename Data, typename Tag, typename DataTag = unused_type>
+ template <typename Data, typename Tag
+ , typename DataTag1 = unused_type, typename DataTag2 = unused_type>
         struct stateful_tag
         {
             typedef Data data_type;
@@ -448,11 +449,12 @@
         };
     }
 
- template <typename Data, typename Tag, typename DataTag = unused_type>
+ template <typename Data, typename Tag
+ , typename DataTag1 = unused_type, typename DataTag2 = unused_type>
     struct stateful_tag_type
- : spirit::terminal<tag::stateful_tag<Data, Tag, DataTag> >
+ : spirit::terminal<tag::stateful_tag<Data, Tag, DataTag1, DataTag2> >
     {
- typedef tag::stateful_tag<Data, Tag, DataTag> tag_type;
+ typedef tag::stateful_tag<Data, Tag, DataTag1, DataTag2> tag_type;
 
         stateful_tag_type() {}
         stateful_tag_type(Data const& data)

Added: trunk/boost/spirit/include/karma_phoenix_attributes.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/include/karma_phoenix_attributes.hpp 2009-10-02 17:18:41 EDT (Fri, 02 Oct 2009)
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2001-2009 Joel de Guzman
+ Copyright (c) 2001-2009 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_PHOENIX_ATTRIBUTES
+#define BOOST_SPIRIT_INCLUDE_KARMA_PHOENIX_ATTRIBUTES
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/karma/phoenix_attributes.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