Boost logo

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