Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67711 - in trunk/boost/spirit/home: karma/operator qi/operator support support/utree
From: hartmut.kaiser_at_[hidden]
Date: 2011-01-05 22:11:12


Author: hkaiser
Date: 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
New Revision: 67711
URL: http://svn.boost.org/trac/boost/changeset/67711

Log:
Spirit: added customization points for attribute transformation in compound operators
Text files modified:
   trunk/boost/spirit/home/karma/operator/alternative.hpp | 3 +
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 5 +-
   trunk/boost/spirit/home/qi/operator/alternative.hpp | 5 +-
   trunk/boost/spirit/home/qi/operator/permutation.hpp | 5 +-
   trunk/boost/spirit/home/qi/operator/sequence_base.hpp | 5 +-
   trunk/boost/spirit/home/qi/operator/sequential_or.hpp | 5 +-
   trunk/boost/spirit/home/support/attributes.hpp | 54 +++++++++++++++++++++++++++++++++
   trunk/boost/spirit/home/support/attributes_fwd.hpp | 15 +++++++++
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 63 ++++++++++++++++++++++++++++++++++++++++
   9 files changed, 148 insertions(+), 12 deletions(-)

Modified: trunk/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/alternative.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -89,7 +89,8 @@
         {
             // Put all the element attributes in a tuple
             typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator
+ Elements, Context, traits::alternative_attribute_transform
+ , Iterator, karma::domain
>::type all_attributes;
 
             // Ok, now make a variant over the attribute sequence. Note that

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 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -210,8 +210,9 @@
         {
             // Put all the element attributes in a tuple
             typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
+ Elements, Context, traits::sequence_attribute_transform
+ , Iterator, karma::domain
+ >::type all_attributes;
 
             // Now, build a fusion vector over the attributes. Note
             // that build_fusion_vector 1) removes all unused attributes

Modified: trunk/boost/spirit/home/qi/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/alternative.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -49,8 +49,9 @@
         {
             // Put all the element attributes in a tuple
             typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
+ Elements, Context, traits::alternative_attribute_transform
+ , Iterator, qi::domain
+ >::type all_attributes;
 
             // Ok, now make a variant over the attribute sequence. Note that
             // build_variant makes sure that 1) all attributes in the variant

Modified: trunk/boost/spirit/home/qi/operator/permutation.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/permutation.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/permutation.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -49,8 +49,9 @@
             // Put all the element attributes in a tuple,
             // wrapping each element in a boost::optional
             typedef typename traits::build_attribute_sequence<
- Elements, Context, traits::build_optional, Iterator>::type
- all_attributes;
+ Elements, Context, traits::permutation_attribute_transform
+ , Iterator, qi::domain
+ >::type all_attributes;
 
             // Now, build a fusion vector over the attributes. Note
             // that build_fusion_vector 1) removes all unused attributes

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 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -40,8 +40,9 @@
         {
             // Put all the element attributes in a tuple
             typedef typename traits::build_attribute_sequence<
- Elements, Context, mpl::identity, Iterator>::type
- all_attributes;
+ Elements, Context, traits::sequence_attribute_transform
+ , Iterator, qi::domain
+ >::type all_attributes;
 
             // Now, build a fusion vector over the attributes. Note
             // that build_fusion_vector 1) removes all unused attributes

Modified: trunk/boost/spirit/home/qi/operator/sequential_or.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/sequential_or.hpp (original)
+++ trunk/boost/spirit/home/qi/operator/sequential_or.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -44,8 +44,9 @@
             // Put all the element attributes in a tuple,
             // wrapping each element in a boost::optional
             typedef typename traits::build_attribute_sequence<
- Elements, Context, traits::build_optional, Iterator>::type
- all_attributes;
+ Elements, Context, traits::sequential_or_attribute_transform
+ , Iterator, qi::domain
+ >::type all_attributes;
 
             // Now, build a fusion vector over the attributes. Note
             // that build_fusion_vector 1) removes all unused attributes

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -343,6 +343,44 @@
     {};
 
     ///////////////////////////////////////////////////////////////////////////
+ // sequence_attribute_transform
+ //
+ // This transform is invoked for every attribute in a sequence allowing
+ // to modify the attribute type exposed by a component to the enclosing
+ // sequence component. By default no transformation is performed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
+ struct sequence_attribute_transform
+ : mpl::identity<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // permutation_attribute_transform
+ //
+ // This transform is invoked for every attribute in a sequence allowing
+ // to modify the attribute type exposed by a component to the enclosing
+ // permutation component. By default a build_optional transformation is
+ // performed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
+ struct permutation_attribute_transform
+ : traits::build_optional<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // sequential_or_attribute_transform
+ //
+ // This transform is invoked for every attribute in a sequential_or allowing
+ // to modify the attribute type exposed by a component to the enclosing
+ // sequential_or component. By default a build_optional transformation is
+ // performed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
+ struct sequential_or_attribute_transform
+ : traits::build_optional<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
     // build_fusion_vector
     //
     // Build a fusion vector from a fusion sequence. All unused attributes
@@ -384,7 +422,8 @@
     // components. Transform<T>::type is called on each element.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Sequence, typename Context
- , template <typename T> class Transform, typename Iterator = unused_type>
+ , template <typename T, typename D> class Transform
+ , typename Iterator = unused_type, typename Domain = unused_type>
     struct build_attribute_sequence
     {
         struct element_attribute
@@ -398,6 +437,7 @@
                 typedef typename
                     Transform<
                         typename attribute_of<Element, Context, Iterator>::type
+ , Domain
>::type
                 type;
             };
@@ -479,6 +519,18 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
+ // alternative_attribute_transform
+ //
+ // This transform is invoked for every attribute in an alternative allowing
+ // to modify the attribute type exposed by a component to the enclosing
+ // alternative component. By default no transformation is performed.
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
+ struct alternative_attribute_transform
+ : mpl::identity<Attribute>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
     // build_variant
     //
     // Build a boost::variant from a fusion sequence. build_variant makes sure

Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -232,6 +232,21 @@
 
     template <typename Attribute, typename T, typename Enable = void>
     struct symbols_value;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // transform attribute types exposed from compound operator components
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Attribute, typename Domain>
+ struct alternative_attribute_transform;
+
+ template <typename Attribute, typename Domain>
+ struct sequence_attribute_transform;
+
+ template <typename Attribute, typename Domain>
+ struct permutation_attribute_transform;
+
+ template <typename Attribute, typename Domain>
+ struct sequential_or_attribute_transform;
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp 2011-01-05 22:11:09 EST (Wed, 05 Jan 2011)
@@ -76,6 +76,22 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // Make sure all components of an alternative expose utree, even if they
+ // actually expose a utree::list_type
+ template <typename Domain>
+ struct alternative_attribute_transform<utree::list_type, Domain>
+ : mpl::identity<utree>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Make sure all components of a sequence expose utree, even if they
+ // actually expose a utree::list_type
+ template <typename Domain>
+ struct sequence_attribute_transform<utree::list_type, Domain>
+ : mpl::identity<utree>
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
     // this specialization lets Spirit know that typed basic_strings
     // are strings
     template <typename Base, utree_type::info I>
@@ -407,6 +423,11 @@
       : detail::attribute_as_symbol_type
     {};
 
+ template <typename Attribute>
+ struct attribute_as<Attribute, utree::list_type>
+ : attribute_as<Attribute, utree>
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     namespace detail
     {
@@ -474,6 +495,11 @@
         }
     };
 
+ template <typename T>
+ struct push_back_container<utree::list_type, T>
+ : push_back_container<utree, T>
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     // ensure the utree attribute is an empty list
     template <>
@@ -499,6 +525,12 @@
         typedef utree type;
     };
 
+ template <>
+ struct build_std_vector<utree::list_type>
+ {
+ typedef utree::list_type type;
+ };
+
     ///////////////////////////////////////////////////////////////////////////
     // debug support for utree
     template <typename Out>
@@ -622,6 +654,12 @@
         typedef utree type;
     };
 
+ template <>
+ struct build_optional<utree::list_type>
+ {
+ typedef utree::list_type type;
+ };
+
     // an utree is an optional (in any domain)
     template <>
     struct not_is_optional<utree, qi::domain>
@@ -629,10 +667,20 @@
     {};
 
     template <>
+ struct not_is_optional<utree::list_type, qi::domain>
+ : mpl::false_
+ {};
+
+ template <>
     struct not_is_optional<utree, karma::domain>
       : mpl::false_
     {};
 
+ template <>
+ struct not_is_optional<utree::list_type, karma::domain>
+ : mpl::false_
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     // the specialization below tells Spirit to handle utree as if it
     // where a 'real' variant (in the context of karma)
@@ -641,6 +689,11 @@
       : mpl::false_
     {};
 
+ template <>
+ struct not_is_variant<utree::list_type, karma::domain>
+ : mpl::false_
+ {};
+
     // The specializations below tell Spirit to verify whether an attribute
     // type is compatible with a given variant type
     template <>
@@ -848,6 +901,11 @@
         }
     };
 
+ template <typename Attribute>
+ struct compute_compatible_component_variant<utree::list_type, Attribute>
+ : compute_compatible_component_variant<utree, Attribute>
+ {};
+
     ///////////////////////////////////////////////////////////////////////////
     template <>
     struct symbols_lookup<utree, utf8_symbol_type>
@@ -1094,6 +1152,11 @@
         }
     };
 
+ template <typename Attribute>
+ struct transform_attribute<utree::list_type const, Attribute, karma::domain>
+ : transform_attribute<utree const, Attribute, karma::domain>
+ {};
+
 #if 0
     // If a rule takes an utree attribute and that utree instance holds nothing
     // more than a list, we dereference this to simplify attribute handling


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