$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r58297 - in trunk/boost/spirit/home: qi/detail qi/directive qi/operator support
From: hartmut.kaiser_at_[hidden]
Date: 2009-12-11 14:50:16
Author: hkaiser
Date: 2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
New Revision: 58297
URL: http://svn.boost.org/trac/boost/changeset/58297
Log:
Spirit: added bool return value to push_back customization point
Text files modified: 
   trunk/boost/spirit/home/qi/detail/pass_container.hpp |     5 ++                                      
   trunk/boost/spirit/home/qi/directive/repeat.hpp      |    22 ++++++++---                             
   trunk/boost/spirit/home/qi/operator/kleene.hpp       |     7 ++-                                     
   trunk/boost/spirit/home/qi/operator/list.hpp         |    27 ++++++++------                          
   trunk/boost/spirit/home/qi/operator/plus.hpp         |    24 ++++++++-----                           
   trunk/boost/spirit/home/support/container.hpp        |    71 +++++++++++++++++++++------------------ 
   6 files changed, 92 insertions(+), 64 deletions(-)
Modified: trunk/boost/spirit/home/qi/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/pass_container.hpp	(original)
+++ trunk/boost/spirit/home/qi/detail/pass_container.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -70,11 +70,14 @@
             typename traits::container_value<Attr>::type val =
                 typename traits::container_value<Attr>::type();
 
+            iterator_type save = f.first;
             bool r = f(component, val);
             if (!r)
             {
                 // push the parsed value into our attribute
-                traits::push_back(attr, val);
+                r = !traits::push_back(attr, val);
+                if (r)
+                    f.first = save;
             }
             return r;
         }
Modified: trunk/boost/spirit/home/qi/directive/repeat.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/directive/repeat.hpp	(original)
+++ trunk/boost/spirit/home/qi/directive/repeat.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -161,31 +161,39 @@
             typename LoopIter::type i = iter.start();
 
             // parse the minimum required
-            { // this scope allows save and save_attr to be reclaimed immediately
-              // after we're done with the required minimum iteration.
+            if (!iter.got_min(i)) { 
+                // this scope allows save and save_attr to be reclaimed 
+                // immediately after we're done with the required minimum 
+                // iteration.
                 Iterator save = first;
                 Attribute save_attr; traits::swap_impl(save_attr, attr);
                 for (; !iter.got_min(i); ++i)
                 {
-                    if (!subject.parse(first, last, context, skipper, val))
+                    if (!subject.parse(save, last, context, skipper, val) ||
+                        !traits::push_back(attr, val))
                     {
                         // if we fail before reaching the minimum iteration
                         // required, restore the iterator and the attribute
                         // then return false
-                        first = save;
                         traits::swap_impl(save_attr, attr);
                         return false;
                     }
-                    traits::push_back(attr, val);
+
+                    first = save;
                     traits::clear(val);
                 }
             }
+
             // parse some more up to the maximum specified
+            Iterator save = first;
             for (; !iter.got_max(i); ++i)
             {
-                if (!subject.parse(first, last, context, skipper, val))
+                if (!subject.parse(save, last, context, skipper, val) ||
+                    !traits::push_back(attr, val))
+                {
                     break;
-                traits::push_back(attr, val);
+                }
+                first = save;
                 traits::clear(val);
             }
             return true;
Modified: trunk/boost/spirit/home/qi/operator/kleene.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/kleene.hpp	(original)
+++ trunk/boost/spirit/home/qi/operator/kleene.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -67,10 +67,11 @@
             value_type val = value_type();
 
             // Repeat while subject parses ok
-            while (subject.parse(first, last, context, skipper, val))
+            Iterator save = first;
+            while (subject.parse(save, last, context, skipper, val) &&
+                   traits::push_back(attr, val))    // push the parsed value into our attribute
             {
-                // push the parsed value into our attribute
-                traits::push_back(attr, val);
+                first = save;
                 traits::clear(val);
             }
             return true;
Modified: trunk/boost/spirit/home/qi/operator/list.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/list.hpp	(original)
+++ trunk/boost/spirit/home/qi/operator/list.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -64,20 +64,23 @@
                 value_type;
             value_type val = value_type();
 
-            if (left.parse(first, last, context, skipper, val))
+            Iterator save = first;
+            if (!left.parse(save, last, context, skipper, val) ||
+                !traits::push_back(attr, val))
             {
-                traits::push_back(attr, val);
-                Iterator i = first;
-                while (right.parse(i, last, context, skipper, unused)
-                 && (traits::clear(val), true)
-                 && left.parse(i, last, context, skipper, val))
-                {
-                    traits::push_back(attr, val);
-                    first = i;
-                }
-                return true;
+                return false;
             }
-            return false;
+            first = save;
+
+            while (right.parse(save, last, context, skipper, unused)
+             && (traits::clear(val), true)
+             && left.parse(save, last, context, skipper, val))
+            {
+                if (!traits::push_back(attr, val))
+                    break;
+                first = save;
+            }
+            return true;
         }
 
         template <typename Context>
Modified: trunk/boost/spirit/home/qi/operator/plus.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/operator/plus.hpp	(original)
+++ trunk/boost/spirit/home/qi/operator/plus.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -62,18 +62,24 @@
                 value_type;
             value_type val = value_type();
 
-            if (subject.parse(first, last, context, skipper, val))
+            Iterator save = first;
+            if (!subject.parse(save, last, context, skipper, val) ||
+                !traits::push_back(attr, val))
             {
-                traits::push_back(attr, val);
+                return false;
+            }
+            first = save;
+            traits::clear(val);
+
+            while (subject.parse(save, last, context, skipper, val))
+            {
+                if (!traits::push_back(attr, val))
+                    break;
+
+                first = save;
                 traits::clear(val);
-                while (subject.parse(first, last, context, skipper, val))
-                {
-                    traits::push_back(attr, val);
-                    traits::clear(val);
-                }
-                return true;
             }
-            return false;
+            return true;
         }
 
         template <typename Context>
Modified: trunk/boost/spirit/home/support/container.hpp
==============================================================================
--- trunk/boost/spirit/home/support/container.hpp	(original)
+++ trunk/boost/spirit/home/support/container.hpp	2009-12-11 14:50:15 EST (Fri, 11 Dec 2009)
@@ -48,25 +48,25 @@
             detail::has_reference<T>::value>
     {};
 
-   template <typename T>
-   struct is_container<T&> 
-     : is_container<T> 
-   {};
-
-   template <typename T>
-   struct is_container<optional<T> > 
-     : is_container<T> 
-   {};
+    template <typename T>
+    struct is_container<T&> 
+      : is_container<T> 
+    {};
+
+    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 ||                             \
-   /***/
+        is_container<BOOST_PP_CAT(T, N)>::value ||                            \
+    /***/
 
-   template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
-   struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> > 
-     : mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
-         , BOOST_SPIRIT_IS_CONTAINER, _) false> 
-   {};
+    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+    struct is_container<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
 
@@ -233,15 +233,16 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Container, typename T>
-    void push_back(Container& c, T const& val);
+    bool push_back(Container& c, T const& val);
 
     //[customization_push_back_default
     template <typename Container, typename T, typename Enable/* = void*/>
     struct push_back_container
     {
-        static void call(Container& c, T const& val)
+        static bool call(Container& c, T const& val)
         {
             c.insert(c.end(), val);
+            return true;
         }
     };
     //]
@@ -249,11 +250,11 @@
     template <typename Container, typename T>
     struct push_back_container<optional<Container>, T>
     {
-        static void call(optional<Container>& c, T const& val)
+        static bool call(optional<Container>& c, T const& val)
         {
             if (!c)
                 c = Container();
-            push_back(boost::get<Container>(c), val);
+            return push_back(boost::get<Container>(c), val);
         }
     };
 
@@ -262,25 +263,28 @@
         template <typename T>
         struct push_back_visitor : public static_visitor<>
         {
+            typedef bool result_type;
+
             push_back_visitor(T const& t) : t_(t) {}
 
             template <typename Container>
-            void push_back_impl(Container& c, mpl::true_) const
+            bool push_back_impl(Container& c, mpl::true_) const
             {
-                push_back(c, t_);
+                return push_back(c, t_);
             }
 
             template <typename T_>
-            void push_back_impl(T_&, mpl::false_) const
+            bool push_back_impl(T_&, mpl::false_) const
             {
                 // this variant doesn't hold a container
                 BOOST_ASSERT(false);
+                return false;
             }
 
             template <typename T_>
-            void operator()(T_& c) const
+            bool operator()(T_& c) const
             {
-                push_back_impl(c, typename is_container<T_>::type());
+                return push_back_impl(c, typename is_container<T_>::type());
             }
 
             T const& t_;
@@ -290,32 +294,35 @@
     template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T>
     struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T>
     {
-        static void call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
+        static bool call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
         {
-            apply_visitor(detail::push_back_visitor<T>(val), c);
+            return apply_visitor(detail::push_back_visitor<T>(val), c);
         }
     };
 
     template <typename Container, typename T>
-    void push_back(Container& c, T const& val)
+    bool push_back(Container& c, T const& val)
     {
-        push_back_container<Container, T>::call(c, val);
+        return push_back_container<Container, T>::call(c, val);
     }
 
     //[customization_push_back_unused
     template <typename Container>
-    void push_back(Container&, unused_type)
+    bool push_back(Container&, unused_type)
     {
+        return true;
     }
     //]
 
     template <typename T>
-    void push_back(unused_type, T const&)
+    bool push_back(unused_type, T const&)
     {
+        return true;
     }
 
-    inline void push_back(unused_type, unused_type)
+    inline bool push_back(unused_type, unused_type)
     {
+        return true;
     }
 
     ///////////////////////////////////////////////////////////////////////////