|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r55365 - in trunk/boost/spirit/home: karma/operator qi/operator support
From: hartmut.kaiser_at_[hidden]
Date: 2009-08-02 13:14:33
Author: hkaiser
Date: 2009-08-02 13:14:33 EDT (Sun, 02 Aug 2009)
New Revision: 55365
URL: http://svn.boost.org/trac/boost/changeset/55365
Log:
Spirit: enabled special attribute handling for sequences if attribute is a fusion sequence and the sequence has exactly one element exposing an attribute
Text files modified:
trunk/boost/spirit/home/karma/operator/sequence.hpp | 10 +++++++---
trunk/boost/spirit/home/qi/operator/sequence_base.hpp | 8 ++++++--
trunk/boost/spirit/home/support/attributes.hpp | 25 ++++++++++++++++++++++---
3 files changed, 35 insertions(+), 8 deletions(-)
Modified: trunk/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/sequence.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/sequence.hpp 2009-08-02 13:14:33 EDT (Sun, 02 Aug 2009)
@@ -90,7 +90,7 @@
typedef Elements elements_type;
struct sequence_base_id;
- template <typename Context, typename Unused>
+ template <typename Context, typename Unused = unused_type>
struct attribute
{
// Put all the element attributes in a tuple
@@ -124,8 +124,12 @@
OutputIterator, Context, Delimiter> fail_function;
typedef traits::attribute_not_unused<Context> predicate;
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
+ // wrap the attribute in a tuple if it is not a tuple or if the
+ // attribute of this sequence is a single element tuple
+ typedef typename attribute<Context>::type_ attr_type_;
+ typename traits::wrap_if_not_tuple<Attribute
+ , typename traits::one_element_sequence<attr_type_>::type
+ >::type attr(attr_);
// return false if *any* of the generators fail
return !spirit::any_if(elements, attr, fail_function(sink, ctx, d)
Modified: trunk/boost/spirit/home/qi/operator/sequence_base.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/sequence_base.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/sequence_base.hpp 2009-08-02 13:14:33 EDT (Sun, 02 Aug 2009)
@@ -70,8 +70,12 @@
Iterator iter = first;
typedef traits::attribute_not_unused<Context, Iterator> predicate;
- // wrap the attribute in a tuple if it is not a tuple
- typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
+ // wrap the attribute in a tuple if it is not a tuple or if the
+ // attribute of this sequence is a single element tuple
+ typedef typename attribute<Context, Iterator>::type_ attr_type_;
+ typename traits::wrap_if_not_tuple<Attribute
+ , typename traits::one_element_sequence<attr_type_>::type
+ >::type attr(attr_);
// return false if *any* of the parsers fail
if (spirit::any_if(elements, attr
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2009-08-02 13:14:33 EDT (Sun, 02 Aug 2009)
@@ -95,21 +95,27 @@
// Subclass a pass_attribute specialization from this to wrap
// the attribute in a tuple only IFF it is not already a fusion tuple.
///////////////////////////////////////////////////////////////////////////
- template <typename Attribute>
+ template <typename Attribute, typename Force = mpl::false_>
struct wrap_if_not_tuple
: mpl::if_<
fusion::traits::is_sequence<Attribute>
, Attribute&, fusion::vector1<Attribute&> >
{};
+ template <typename Attribute>
+ struct wrap_if_not_tuple<Attribute, mpl::true_>
+ {
+ typedef fusion::vector1<Attribute&> type;
+ };
+
template <>
- struct wrap_if_not_tuple<unused_type>
+ struct wrap_if_not_tuple<unused_type, mpl::false_>
{
typedef unused_type type;
};
template <>
- struct wrap_if_not_tuple<unused_type const>
+ struct wrap_if_not_tuple<unused_type const, mpl::false_>
{
typedef unused_type type;
};
@@ -417,6 +423,19 @@
};
///////////////////////////////////////////////////////////////////////////
+ // meta function to return whether the argument is a one element fusion
+ // sequence
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct one_element_sequence : mpl::false_ {};
+
+ template <typename T>
+ struct one_element_sequence<fusion::vector1<T> > : mpl::true_ {};
+
+ template <typename T>
+ struct one_element_sequence<fusion::vector<T> > : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////
// clear
//
// Clear data efficiently
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