$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60885 - in trunk/boost/spirit/home: karma/detail support
From: hartmut.kaiser_at_[hidden]
Date: 2010-03-27 22:06:02
Author: hkaiser
Date: 2010-03-27 22:06:01 EDT (Sat, 27 Mar 2010)
New Revision: 60885
URL: http://svn.boost.org/trac/boost/changeset/60885
Log:
Spirit: improving customization points for karma alternatives
Text files modified: 
   trunk/boost/spirit/home/karma/detail/alternative_function.hpp |    78 +-------------------------------------  
   trunk/boost/spirit/home/support/attributes.hpp                |    80 ++++++++++++++++++++++++++++++++++++++++
   2 files changed, 83 insertions(+), 75 deletions(-)
Modified: trunk/boost/spirit/home/karma/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/alternative_function.hpp	(original)
+++ trunk/boost/spirit/home/karma/detail/alternative_function.hpp	2010-03-27 22:06:01 EDT (Sat, 27 Mar 2010)
@@ -19,12 +19,6 @@
 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
 #include <boost/spirit/home/support/container.hpp>
 #include <boost/utility/enable_if.hpp>
-#include <boost/mpl/find_if.hpp>
-#include <boost/mpl/deref.hpp>
-#include <boost/mpl/distance.hpp>
-#include <boost/mpl/or.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/type_traits/is_convertible.hpp>
 #include <boost/variant.hpp>
 #include <boost/detail/workaround.hpp>
 
@@ -32,69 +26,6 @@
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
     ///////////////////////////////////////////////////////////////////////////
-    //  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> {};
-
-    template <typename Expected, typename Attribute>
-    struct attribute_is_compatible<Expected, boost::optional<Attribute> >
-      : is_convertible<Attribute, Expected> {};
-
-    template <typename Container>
-    struct is_hold_any_container
-      : is_same<hold_any, typename traits::container_value<Container>::type> {};
-
-    template <typename Expected, typename Attribute, typename IsNotVariant>
-    struct compute_compatible_component_variant
-      : mpl::or_<
-            attribute_is_compatible<Expected, Attribute>
-          , is_same<hold_any, Expected> 
-          , mpl::eval_if<
-                traits::is_container<Expected>
-              , is_hold_any_container<Expected>
-              , mpl::false_>
-        > {};
-
-    template <typename Expected, typename Attribute>
-    struct compute_compatible_component_variant<Expected, Attribute, mpl::false_>
-    {
-        typedef typename traits::variant_type<Attribute>::type variant_type;
-        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 
-        iter;
-
-        typedef typename mpl::distance<
-            typename mpl::begin<types>::type, iter
-        >::type distance;
-
-        typedef typename mpl::not_<is_same<iter, end> >::type type;
-        enum { value = type::value };
-    };
-
-    template <typename Expected, typename Attribute>
-    struct compute_compatible_component
-      : compute_compatible_component_variant<Expected, Attribute
-          , typename spirit::traits::not_is_variant<Attribute>::type> {};
-
-    template <typename Expected>
-    struct compute_compatible_component<Expected, unused_type>
-      : mpl::false_ {};
-
-    template <typename Attribute>
-    struct compute_compatible_component<unused_type, Attribute>
-      : mpl::false_ {};
-
-    template <>
-    struct compute_compatible_component<unused_type, unused_type>
-      : mpl::false_ {};
-
-    ///////////////////////////////////////////////////////////////////////////
     //  execute a generator if the given Attribute type is compatible
     ///////////////////////////////////////////////////////////////////////////
 
@@ -146,7 +77,7 @@
     template <typename Component, typename Attribute, typename Expected>
     struct alternative_generate<Component, Attribute, Expected
       , typename enable_if<
-            compute_compatible_component<Expected, Attribute> >::type>
+            traits::compute_compatible_component<Expected, Attribute> >::type>
     {
         template <typename OutputIterator, typename Context, typename Delimiter>
         static bool
@@ -180,7 +111,7 @@
             component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
 #endif
             typedef
-                compute_compatible_component<Expected, Attribute>
+                traits::compute_compatible_component<Expected, Attribute>
             component_type;
 
             typedef typename component_type::distance distance_type;
@@ -197,10 +128,7 @@
                 return false;
 
             // returns true if any of the generators succeed
-            typedef
-                typename mpl::deref<typename component_type::iter>::type
-            compatible_type;
-
+            typedef typename component_type::compatible_type compatible_type;
             return component.generate(sink, ctx, d, get<compatible_type>(attr_));
         }
     };
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes.hpp	2010-03-27 22:06:01 EDT (Sat, 27 Mar 2010)
@@ -15,6 +15,7 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/has_semantic_action.hpp>
 #include <boost/spirit/home/support/attributes_fwd.hpp>
+#include <boost/spirit/home/support/detail/hold_any.hpp>
 #include <boost/spirit/home/support/detail/as_variant.hpp>
 #include <boost/optional/optional.hpp>
 #include <boost/fusion/include/transform.hpp>
@@ -32,6 +33,9 @@
 #include <boost/mpl/end.hpp>
 #include <boost/mpl/find_if.hpp>
 #include <boost/mpl/identity.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/or.hpp>
 #include <boost/proto/proto_fwd.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/variant.hpp>
@@ -76,6 +80,82 @@
     {};
 
     ///////////////////////////////////////////////////////////////////////////
+    // The compute_compatible_component_variant 
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        //  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> 
+        {};
+
+        template <typename Expected, typename Attribute>
+        struct attribute_is_compatible<Expected, boost::optional<Attribute> >
+          : is_convertible<Attribute, Expected> 
+        {};
+
+        template <typename Container>
+        struct is_hold_any_container
+          : is_same<hold_any, typename traits::container_value<Container>::type> 
+        {};
+    }
+
+    template <typename Expected, typename Attribute, typename IsNotVariant = mpl::false_>
+    struct compute_compatible_component_variant
+      : mpl::or_<
+            traits::detail::attribute_is_compatible<Expected, Attribute>
+          , is_same<hold_any, Expected> 
+          , mpl::eval_if<
+                is_container<Expected>
+              , traits::detail::is_hold_any_container<Expected>
+              , mpl::false_> > 
+    {};
+
+    template <typename Expected, typename Variant>
+    struct compute_compatible_component_variant<Expected, Variant, mpl::false_>
+    {
+        typedef typename traits::variant_type<Variant>::type variant_type;
+        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 
+        iter;
+
+        typedef typename mpl::distance<
+            typename mpl::begin<types>::type, iter
+        >::type distance;
+
+        // true_ if the attribute matches one of the types in the variant
+        typedef typename mpl::not_<is_same<iter, end> >::type type;
+        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 
+        compatible_type;
+    };
+
+    template <typename Expected, typename Attribute>
+    struct compute_compatible_component
+      : compute_compatible_component_variant<Expected, Attribute
+          , typename spirit::traits::not_is_variant<Attribute>::type> {};
+
+    template <typename Expected>
+    struct compute_compatible_component<Expected, unused_type>
+      : mpl::false_ {};
+
+    template <typename Attribute>
+    struct compute_compatible_component<unused_type, Attribute>
+      : mpl::false_ {};
+
+    template <>
+    struct compute_compatible_component<unused_type, unused_type>
+      : mpl::false_ {};
+
+    ///////////////////////////////////////////////////////////////////////////
     template <typename T>
     struct not_is_optional
       : mpl::true_