Boost logo

Boost-Commit :

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


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