$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r68180 - in trunk/boost/spirit/home: karma/directive karma/operator qi/directive support
From: admin_at_[hidden]
Date: 2011-01-16 01:28:25
Author: wash
Date: 2011-01-16 01:28:23 EST (Sun, 16 Jan 2011)
New Revision: 68180
URL: http://svn.boost.org/trac/boost/changeset/68180
Log:
Workaround regressions introduced in Karma by r68177; add asserts to karma::as
and qi::as.
Text files modified: 
   trunk/boost/spirit/home/karma/directive/as.hpp      |     9 +++                                     
   trunk/boost/spirit/home/karma/operator/sequence.hpp |    40 +---------------                        
   trunk/boost/spirit/home/qi/directive/as.hpp         |     9 +++                                     
   trunk/boost/spirit/home/support/attributes.hpp      |    92 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/spirit/home/support/attributes_fwd.hpp  |    19 ++++++++                                
   trunk/boost/spirit/home/support/container.hpp       |    10 ++++                                    
   6 files changed, 141 insertions(+), 38 deletions(-)
Modified: trunk/boost/spirit/home/karma/directive/as.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/as.hpp	(original)
+++ trunk/boost/spirit/home/karma/directive/as.hpp	2011-01-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -21,6 +21,8 @@
 #include <boost/spirit/home/support/common_terminals.hpp>
 #include <boost/spirit/home/support/has_semantic_action.hpp>
 #include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/spirit/home/support/assert_msg.hpp>
+#include <boost/spirit/home/support/container.hpp>
 #include <boost/spirit/home/karma/detail/attributes.hpp>
 
 namespace boost { namespace spirit { namespace karma
@@ -28,7 +30,12 @@
     template <typename T>
     struct as
       : stateful_tag_type<T, tag::as>
-    {};
+    {
+        BOOST_SPIRIT_ASSERT_MSG(
+            (traits::is_container<T>::type::value),
+            error_type_must_be_a_container,
+            (T));
+    };
 }}}
 
 namespace boost { namespace spirit
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-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -25,6 +25,7 @@
 #include <boost/spirit/home/support/sequence_base_id.hpp>
 #include <boost/spirit/home/support/has_semantic_action.hpp>
 #include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/spirit/home/support/attributes.hpp>
 #include <boost/fusion/include/vector.hpp>
 #include <boost/fusion/include/as_vector.hpp>
 #include <boost/fusion/include/for_each.hpp>
@@ -90,41 +91,6 @@
 {
     namespace detail
     {
-        template <typename T>
-        struct attribute_size
-          : fusion::result_of::size<T>
-        {};
-
-        template <>
-        struct attribute_size<unused_type>
-          : mpl::int_<0>
-        {};
-
-        template <typename Attribute>
-        inline typename enable_if<
-            mpl::and_<
-                fusion::traits::is_sequence<Attribute>
-              , mpl::not_<traits::is_container<Attribute> > >
-          , std::size_t
-        >::type
-        attr_size(Attribute const& attr)
-        {
-            return fusion::size(attr);
-        }
-
-        template <typename Attribute>
-        inline typename enable_if<
-            traits::is_container<Attribute>, std::size_t
-        >::type
-        attr_size(Attribute const& attr)
-        {
-            return attr.size();
-        }
-
-        inline std::size_t attr_size(unused_type)
-        {
-            return 0;
-        }
 
         ///////////////////////////////////////////////////////////////////////
         // This is a wrapper for any iterator allowing to pass a reference of it
@@ -254,6 +220,8 @@
             bool r = spirit::any_if(elements, attr
                           , fail_function(sink, ctx, d), predicate());
 
+            typedef typename traits::attribute_size<Attribute>::type size_type;
+
             // fail generating if sequences have not the same (logical) length
             return !r && (!Strict::value || 
                 // This ignores container element count (which is not good), 
@@ -264,7 +232,7 @@
                 // is not optimal but much better than letting _all_ repetitive
                 // components fail.
                 Pred1::value ||
-                std::size_t(detail::attribute_size<attr_type_>::value) == detail::attr_size(attr_));
+                size_type(traits::sequence_size<attr_type_>::value) == traits::size(attr_));
         }
 
         // Special case when Attribute is an stl container and the sequence's
Modified: trunk/boost/spirit/home/qi/directive/as.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/as.hpp	(original)
+++ trunk/boost/spirit/home/qi/directive/as.hpp	2011-01-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -23,6 +23,8 @@
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/has_semantic_action.hpp>
 #include <boost/spirit/home/support/handles_container.hpp>
+#include <boost/spirit/home/support/assert_msg.hpp>
+#include <boost/spirit/home/support/container.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <string>
 
@@ -31,7 +33,12 @@
     template <typename T>
     struct as
       : stateful_tag_type<T, tag::as>
-    {};
+    {
+        BOOST_SPIRIT_ASSERT_MSG(
+            (traits::is_container<T>::type::value),
+            error_type_must_be_a_container,
+            (T));
+    };
 }}}
 
 namespace boost { namespace spirit
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-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -251,6 +251,98 @@
     template <typename Attribute, typename Enable/* = void*/>
     struct attribute_type : mpl::identity<Attribute> {};
 
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Retrieve the size of a fusion sequence (compile time)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct sequence_size
+      : fusion::result_of::size<T>
+    {};
+
+    template <>
+    struct sequence_size<unused_type>
+      : mpl::int_<0>
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Retrieve the size of an attribute (runtime)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Attribute, typename Enable/* = void*/>
+    struct attribute_size
+    {
+        typedef std::size_t type;
+
+        static type call(Attribute const&)
+        {
+            return 1;
+        }
+    };
+
+    template <typename Attribute>
+    struct attribute_size<Attribute
+      , typename enable_if<
+            mpl::and_<
+                fusion::traits::is_sequence<Attribute>
+              , mpl::not_<traits::is_container<Attribute> >
+            >
+        >::type
+    > {
+        typedef typename fusion::result_of::size<Attribute>::value_type type;
+
+        static type call(Attribute const& attr)
+        {
+            return fusion::size(attr);
+        }
+    };
+
+    template <typename Attribute>
+    struct attribute_size<Attribute
+      , typename enable_if<
+            mpl::and_<
+                traits::is_container<Attribute>
+              , mpl::not_<traits::is_iterator_range<Attribute> >
+            >
+        >::type
+    > {
+        typedef typename Attribute::size_type type;
+
+        static type call(Attribute const& attr)
+        {
+            return attr.size();
+        }
+    };
+
+    template <typename Iterator>
+    struct attribute_size<iterator_range<Iterator> >
+    {
+        typedef typename boost::detail::iterator_traits<Iterator>::
+            difference_type type;
+
+        static type call(iterator_range<Iterator> const& r)
+        {
+            return boost::detail::distance(r.begin(), r.end());
+        }
+    };
+
+    template <>
+    struct attribute_size<unused_type>
+    {
+        typedef std::size_t type;
+
+        static type call(unused_type)
+        {
+            return 0;
+        }
+    };
+
+    template <typename Attribute>
+    typename attribute_size<Attribute>::type
+    size(Attribute const& attr)
+    {
+        return attribute_size<Attribute>::call(attr);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // pass_attribute
     //
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-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -63,6 +63,22 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Attribute, typename Enable = void>
     struct attribute_type;
+    
+    ///////////////////////////////////////////////////////////////////////////
+    // Retrieve the size of a fusion sequence (compile time)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T>
+    struct sequence_size;
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Retrieve the size of an attribute (runtime)
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename Attribute, typename Enable = void>
+    struct attribute_size;
+
+    template <typename Attribute>
+    typename attribute_size<Attribute>::type
+    size(Attribute const& attr);
 
     ///////////////////////////////////////////////////////////////////////////
     // Determines how we pass attributes to semantic actions. This
@@ -175,6 +191,9 @@
 
     template <typename T, typename Enable = void>
     struct is_container;
+    
+    template <typename T, typename Enable = void>
+    struct is_iterator_range;
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename T, typename Attribute, typename Context = unused_type
Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp	(original)
+++ trunk/boost/spirit/home/support/container.hpp	2011-01-16 01:28:23 EST (Sun, 16 Jan 2011)
@@ -70,6 +70,16 @@
     {};
 
 #undef BOOST_SPIRIT_IS_CONTAINER
+    
+    template <typename T, typename Enable/* = void*/>
+    struct is_iterator_range
+      : mpl::false_
+    {};
+
+    template <typename T>
+    struct is_iterator_range<iterator_range<T> >
+      : mpl::true_
+    {};
 
     ///////////////////////////////////////////////////////////////////////////
     namespace detail