$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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>