$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53605 - in trunk: boost/spirit/home/karma/detail boost/spirit/home/support libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2009-06-03 14:37:56
Author: hkaiser
Date: 2009-06-03 14:37:55 EDT (Wed, 03 Jun 2009)
New Revision: 53605
URL: http://svn.boost.org/trac/boost/changeset/53605
Log:
Spirit: fixed a problem in attribute handling for Karma sequences taking a std vector as its attribute
Text files modified: 
   trunk/boost/spirit/home/karma/detail/alternative_function.hpp |     9 +----                                   
   trunk/boost/spirit/home/karma/detail/pass_container.hpp       |    64 +++++++++++++++++++-------------------- 
   trunk/boost/spirit/home/support/container.hpp                 |    54 ++++++++++-----------------------       
   trunk/libs/spirit/test/karma/alternative.cpp                  |     3 +                                       
   4 files changed, 52 insertions(+), 78 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	2009-06-03 14:37:55 EDT (Wed, 03 Jun 2009)
@@ -30,11 +30,7 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Expected, typename Attribute, typename IsNotVariant>
     struct compute_compatible_component_variant
-    {
-        typedef mpl::int_<-1> distance;
-        typedef typename is_same<Expected, Attribute>::type type;
-        enum { value = type::value };
-    };
+      : is_same<Expected, Attribute> {};
 
     template <typename Expected, typename Attribute>
     struct compute_compatible_component_variant<Expected, Attribute, mpl::false_>
@@ -57,8 +53,7 @@
     template <typename Expected, typename Attribute>
     struct compute_compatible_component
       : compute_compatible_component_variant<Expected, Attribute
-          , typename spirit::traits::not_is_variant<Attribute>::type>
-    {};
+          , typename spirit::traits::not_is_variant<Attribute>::type> {};
 
     template <typename Expected>
     struct compute_compatible_component<Expected, unused_type>
Modified: trunk/boost/spirit/home/karma/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/pass_container.hpp	(original)
+++ trunk/boost/spirit/home/karma/detail/pass_container.hpp	2009-06-03 14:37:55 EDT (Wed, 03 Jun 2009)
@@ -21,6 +21,7 @@
 #include <boost/mpl/or.hpp>
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/repeat.hpp>
+#include <boost/range/iterator_range.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
@@ -39,6 +40,10 @@
           , is_same<typename LHSAttribute::value_type, hold_any>
         > {};
 
+    template <typename RHS, typename T>
+    struct has_same_elements<RHS, optional<T>, true>
+      : mpl::or_<is_convertible<T, RHS>, is_same<T, hold_any> > {};
+
 #define BOOST_SPIRIT_IS_CONVERTIBLE(z, N, data)                               \
         is_convertible<BOOST_PP_CAT(T, N), RHS>::value ||                     \
         is_same<BOOST_PP_CAT(T, N), hold_any>::value ||                       \
@@ -68,8 +73,7 @@
         // this is for the case when the current element expects an attribute
         // which is taken from the next entry in the container
         template <typename Component>
-//        bool dispatch_attribute_element(Component const& component, mpl::false_) const
-        bool dispatch_attribute(Component const& component, mpl::true_) const
+        bool dispatch_attribute_element(Component const& component, mpl::false_) const
         {
             // get the next value to generate from container
             if (!traits::compare(iter, traits::end(attr)) &&
@@ -83,38 +87,32 @@
             return true;
         }
 
-//        // this is for the case when the current element expects an attribute
-//        // which is a container itself, this element will get the rest of the 
-//        // attribute container
-//        template <typename Component>
-//        bool dispatch_attribute_element(Component const& component, mpl::true_) const
-//        {
-//            typedef typename 
-//                traits::attribute_of<Component, context_type>::type
-//            attribute_type;
-//            typedef typename 
-//                traits::container_type<attribute_type>::type
-//            container_type;
-// 
+       // this is for the case when the current element expects an attribute
+       // which is a container itself, this element will get the rest of the 
+       // attribute container
+       template <typename Component>
+       bool dispatch_attribute_element(Component const& component, mpl::true_) const
+       {
 //            bool result = f(component, container_type(iter, traits::end(attr)));
-//            if (result)
-//                iter = traits::end(attr);     // adjust current iter to the end 
-//            return result;
-//        }
-// 
-//        // This handles the distinction between elements in a sequence expecting
-//        // containers themselves and elements expecting non-containers as their 
-//        // attribute. Note: is_container treats optional<T>, where T is a 
-//        // container as a container as well.
-//        template <typename Component>
-//        bool dispatch_attribute(Component const& component, mpl::true_) const
-//        {
-//            typedef traits::is_container<
-//                typename traits::attribute_of<Component, context_type>::type
-//            > predicate;
-// 
-//            return dispatch_attribute_element(component, predicate());
-//        }
+           bool result = f(component, make_iterator_range(iter, traits::end(attr)));
+           if (result)
+               iter = traits::end(attr);     // adjust current iter to the end 
+           return result;
+       }
+
+       // This handles the distinction between elements in a sequence expecting
+       // containers themselves and elements expecting non-containers as their 
+       // attribute. Note: is_container treats optional<T>, where T is a 
+       // container as a container as well.
+       template <typename Component>
+       bool dispatch_attribute(Component const& component, mpl::true_) const
+       {
+           typedef traits::is_container<
+               typename traits::attribute_of<Component, context_type>::type
+           > predicate;
+
+           return dispatch_attribute_element(component, predicate());
+       }
 
         // this is for the case when the current element doesn't expect an 
         // attribute
Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp	(original)
+++ trunk/boost/spirit/home/support/container.hpp	2009-06-03 14:37:55 EDT (Wed, 03 Jun 2009)
@@ -18,9 +18,9 @@
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/optional.hpp>
-//#include <boost/variant.hpp>
-//#include <boost/preprocessor/cat.hpp>
-//#include <boost/preprocessor/repeat.hpp>
+#include <boost/variant.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repeat.hpp>
 
 namespace boost { namespace spirit { namespace traits
 {
@@ -48,42 +48,20 @@
         >
     {};
 
-//    template <typename T>
-//    struct is_container<optional<T> > 
-//      : is_container<T> {};
-
-//#define BOOST_SPIRIT_IS_CONTAINER(z, N, data)                                 
-//        is_container<BOOST_PP_CAT(T, N)>::value ||                            
-//    /***/
-
-//    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-//    struct is_container<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > 
-//      : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
-//          , BOOST_SPIRIT_IS_CONTAINER, _) false> {};
+   template <typename T>
+   struct is_container<optional<T> > 
+     : is_container<T> {};
+
+#define BOOST_SPIRIT_IS_CONTAINER(z, N, data)                                 \
+       is_container<BOOST_PP_CAT(T, N)>::value ||                             \
+   /***/
+
+   template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+   struct is_container<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > 
+     : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
+         , BOOST_SPIRIT_IS_CONTAINER, _) false> {};
 
-//#undef BOOST_SPIRIT_IS_CONTAINER
-
-    ///////////////////////////////////////////////////////////////////////////
-//    template <typename T>
-//    struct container_type 
-//    {
-//        typedef T type;
-//    };
-
-//    template <typename T>
-//    struct container_type<optional<T> > 
-//      : container_type<T> {};
-
-//    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-//    struct container_type<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > 
-//    {
-//        typedef typename 
-//            boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types 
-//        types;
-
-//        typedef typename mpl::find_if<types, is_container<mpl::_1> >::type iter;
-//        typedef typename mpl::deref<iter>::type type;
-//    };
+#undef BOOST_SPIRIT_IS_CONTAINER
 
     ///////////////////////////////////////////////////////////////////////////
     namespace result_of
Modified: trunk/libs/spirit/test/karma/alternative.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/alternative.cpp	(original)
+++ trunk/libs/spirit/test/karma/alternative.cpp	2009-06-03 14:37:55 EDT (Wed, 03 Jun 2009)
@@ -8,6 +8,7 @@
 #include <boost/config/warning_disable.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
+#include <boost/spirit/include/karma_auxiliary.hpp>
 #include <boost/spirit/include/karma_char.hpp>
 #include <boost/spirit/include/karma_string.hpp>
 #include <boost/spirit/include/karma_numeric.hpp>
@@ -111,6 +112,8 @@
     {
         std::vector<int> v;
         BOOST_TEST(test("[]", '[' << (int_ % ", ") << ']' | "[]", v));
+        BOOST_TEST(test("[]", '[' << -(int_ % ", ") << ']', v));
+        BOOST_TEST(test("[]", '[' << ((int_ % ", ") | eps) << ']', v));
 
         v.push_back(5);
         v.push_back(5);