|
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