Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61002 - in trunk/boost/spirit/home: qi/numeric support
From: joel_at_[hidden]
Date: 2010-04-02 12:00:04


Author: djowel
Date: 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
New Revision: 61002
URL: http://svn.boost.org/trac/boost/changeset/61002

Log:
- better attribute handling
- introduced is_proxy
Text files modified:
   trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp | 38 ++++++++++++++---
   trunk/boost/spirit/home/qi/numeric/real.hpp | 21 ++++++++-
   trunk/boost/spirit/home/support/attributes.hpp | 88 +++++++++++++++++++++++++--------------
   trunk/boost/spirit/home/support/attributes_fwd.hpp | 10 +++
   4 files changed, 114 insertions(+), 43 deletions(-)

Modified: trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/numeric_utils.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -51,10 +51,8 @@
             Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
             not_supported_radix, ());
 
- template <typename Iterator, typename Attribute>
- static bool call(
- Iterator& first, Iterator const& last,
- Attribute& attr)
+ template <typename Iterator>
+ static bool call(Iterator& first, Iterator const& last, T& attr)
         {
             if (first == last)
                 return false;
@@ -70,13 +68,26 @@
 
             Iterator save = first;
             if (!extract_type::parse(first, last,
- detail::cast_unsigned<Attribute>::call(attr)))
+ detail::cast_unsigned<T>::call(attr)))
             {
                 first = save;
                 return false;
             }
             return true;
         }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
     };
 
     ///////////////////////////////////////////////////////////////////////////
@@ -90,8 +101,8 @@
             Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
             not_supported_radix, ());
 
- template <typename Iterator, typename Attribute>
- static bool call(Iterator& first, Iterator const& last, Attribute& attr)
+ template <typename Iterator>
+ static bool call(Iterator& first, Iterator const& last, T& attr)
         {
             if (first == last)
                 return false;
@@ -118,6 +129,19 @@
             }
             return true;
         }
+
+ template <typename Iterator, typename Attribute>
+ static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (call(first, last, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
     };
 }}}
 

Modified: trunk/boost/spirit/home/qi/numeric/real.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/numeric/real.hpp (original)
+++ trunk/boost/spirit/home/qi/numeric/real.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -62,17 +62,32 @@
             typedef T type;
         };
 
- template <typename Iterator, typename Context
- , typename Skipper, typename Attribute>
+ template <typename Iterator, typename Context, typename Skipper>
         bool parse(Iterator& first, Iterator const& last
           , Context& /*context*/, Skipper const& skipper
- , Attribute& attr) const
+ , T& attr) const
         {
             qi::skip_over(first, last, skipper);
             return detail::real_impl<T, RealPolicies>::
                 parse(first, last, attr, RealPolicies());
         }
 
+ template <typename Iterator, typename Context
+ , typename Skipper, typename Attribute>
+ bool parse(Iterator& first, Iterator const& last
+ , Context& context, Skipper const& skipper
+ , Attribute& attr_) const
+ {
+ // this case is called when Attribute is not T
+ T attr;
+ if (parse(first, last, context, skipper, attr))
+ {
+ traits::assign_to(attr, attr_);
+ return true;
+ }
+ return false;
+ }
+
         template <typename Context>
         info what(Context& /*context*/) const
         {

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -25,6 +25,8 @@
 #include <boost/fusion/include/pop_front.hpp>
 #include <boost/fusion/include/is_sequence.hpp>
 #include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/is_view.hpp>
+#include <boost/fusion/include/is_sequence.hpp>
 #include <boost/foreach.hpp>
 #include <boost/utility/value_init.hpp>
 #include <boost/type_traits/is_same.hpp>
@@ -52,6 +54,19 @@
     // components.
     ///////////////////////////////////////////////////////////////////////////
 
+ template <typename T, typename Enable/* = void*/>
+ struct is_proxy : mpl::false_ {};
+
+ template <typename T>
+ struct is_proxy<T,
+ typename enable_if<
+ mpl::and_<
+ fusion::traits::is_sequence<T>,
+ fusion::traits::is_view<T>
+ >
+ >::type>
+ : mpl::true_ {};
+
     template <typename T>
     struct not_is_variant
       : mpl::true_
@@ -80,25 +95,25 @@
     {};
 
     ///////////////////////////////////////////////////////////////////////////
- // The compute_compatible_component_variant
+ // The compute_compatible_component_variant
     ///////////////////////////////////////////////////////////////////////////
     namespace detail
     {
- // A component is compatible to a given Attribute type if the
+ // A component is compatible to a given Attribute type if the
         // Attribute is the same as the expected type of the component
         template <typename Expected, typename Attribute>
- struct attribute_is_compatible
- : is_convertible<Attribute, Expected>
+ struct attribute_is_compatible
+ : is_convertible<Attribute, Expected>
         {};
 
         template <typename Expected, typename Attribute>
         struct attribute_is_compatible<Expected, boost::optional<Attribute> >
- : is_convertible<Attribute, Expected>
+ : is_convertible<Attribute, Expected>
         {};
 
         template <typename Container>
         struct is_hold_any_container
- : is_same<hold_any, typename traits::container_value<Container>::type>
+ : is_same<hold_any, typename traits::container_value<Container>::type>
         {};
     }
 
@@ -106,11 +121,11 @@
     struct compute_compatible_component_variant
       : mpl::or_<
             traits::detail::attribute_is_compatible<Expected, Attribute>
- , is_same<hold_any, Expected>
+ , is_same<hold_any, Expected>
           , mpl::eval_if<
                 is_container<Expected>
               , traits::detail::is_hold_any_container<Expected>
- , mpl::false_> >
+ , mpl::false_> >
     {};
 
     template <typename Expected, typename Variant>
@@ -120,8 +135,8 @@
         typedef typename variant_type::types types;
         typedef typename mpl::end<types>::type end;
 
- typedef typename
- mpl::find_if<types, is_same<Expected, mpl::_1> >::type
+ typedef typename
+ mpl::find_if<types, is_same<Expected, mpl::_1> >::type
         iter;
 
         typedef typename mpl::distance<
@@ -133,8 +148,8 @@
         enum { value = type::value };
 
         // return the type in the variant the attribute is compatible with
- typedef typename
- mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
+ typedef typename
+ mpl::eval_if<type, mpl::deref<iter>, mpl::identity<unused_type> >::type
         compatible_type;
     };
 
@@ -488,39 +503,50 @@
     // attributes. This template can be used as a customization point, where
     // the user is able specify specific transformation rules for any attribute
     // type.
- //
- // The default attribute transformation (where the exposed attribute type is
- // different from the required transformed attribute type) relies on the
- // convertibility 'exposed type' --> 'transformed type', which has to exist
- // in order to successfully execute the pre transform step.
     ///////////////////////////////////////////////////////////////////////////
- template <typename Exposed, typename Transformed, typename Enable/* = void*/>
- struct transform_attribute
+ template <typename Exposed, typename Transformed>
+ struct default_transform_attribute
     {
         typedef Transformed type;
 
- static Transformed pre(Exposed& val) { return Transformed(val); }
+ static Transformed pre(Exposed& val) { return Transformed(); }
 
- // By default do post transformation only if types are convertible,
- // otherwise we assume no post transform is required (i.e. the user
- // utilizes nview et.al.).
- static void post(Exposed&, Transformed const&, mpl::false_)
- {
- }
- static void post(Exposed& val, Transformed const& attr, mpl::true_)
+ static void post(Exposed& val, Transformed const& attr)
         {
             assign_to(attr, val);
         }
 
- static void post(Exposed& val, Transformed const& attr)
- {
- post(val, attr, is_convertible<Transformed, Exposed>());
- }
+ // fail() will be called by Qi rule's if the rhs failed parsing
+ static void fail(Exposed&) {}
+ };
+
+ template <typename Exposed, typename Transformed>
+ struct proxy_transform_attribute
+ {
+ typedef Transformed type;
+
+ static Transformed pre(Exposed& val) { return Transformed(val); }
+ static void post(Exposed& val, Transformed const& attr) { /* no-op */ }
 
         // fail() will be called by Qi rule's if the rhs failed parsing
         static void fail(Exposed&) {}
     };
 
+ template <typename Exposed, typename Transformed, typename Enable/* = void*/>
+ struct transform_attribute
+ : default_transform_attribute<Exposed, Transformed> {};
+
+ template <typename Exposed, typename Transformed>
+ struct transform_attribute<Exposed, Transformed,
+ typename enable_if<
+ mpl::and_<
+ mpl::not_<is_const<Exposed> >,
+ mpl::not_<is_reference<Exposed> >,
+ is_proxy<Transformed>
+ >
+ >::type>
+ : proxy_transform_attribute<Exposed, Transformed> {};
+
     template <typename Exposed, typename Transformed>
     struct transform_attribute<Exposed const, Transformed>
     {

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 2010-04-02 12:00:02 EDT (Fri, 02 Apr 2010)
@@ -15,6 +15,12 @@
 namespace boost { namespace spirit { namespace traits
 {
     ///////////////////////////////////////////////////////////////////////////
+ // Determine if T is a proxy
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename T, typename Enable = void>
+ struct is_proxy;
+
+ ///////////////////////////////////////////////////////////////////////////
     // Retrieve the attribute type to use from the given type
     //
     // This is needed to extract the correct attribute type from proxy classes
@@ -39,7 +45,7 @@
 
     ///////////////////////////////////////////////////////////////////////////
     // Sometimes the user needs to transform the attribute types for certain
- // attributes. This template can be used as a customization point, where
+ // attributes. This template can be used as a customization point, where
     // the user is able specify specific transformation rules for any attribute
     // type.
     ///////////////////////////////////////////////////////////////////////////
@@ -111,7 +117,7 @@
     template <typename Exposed, typename Transformed>
     struct pre_transform;
 
- template <typename T>
+ template <typename T>
     struct optional_value;
 
     template <typename Container>


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