$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r69091 - in trunk/boost/spirit/home/karma: . detail directive operator
From: hartmut.kaiser_at_[hidden]
Date: 2011-02-20 14:26:27
Author: hkaiser
Date: 2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
New Revision: 69091
URL: http://svn.boost.org/trac/boost/changeset/69091
Log:
Spirit: fixed karma::repeat to use the new attribute propagation scheme as well
Text files modified: 
   trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp |    17 +++++++--                               
   trunk/boost/spirit/home/karma/directive/repeat.hpp         |    72 ++++++++++++++++++++++++--------------- 
   trunk/boost/spirit/home/karma/operator/kleene.hpp          |     6 ++-                                     
   trunk/boost/spirit/home/karma/operator/list.hpp            |     5 +-                                      
   trunk/boost/spirit/home/karma/operator/plus.hpp            |     6 ++-                                     
   trunk/boost/spirit/home/karma/operator/sequence.hpp        |    11 +++--                                   
   trunk/boost/spirit/home/karma/phoenix_attributes.hpp       |    14 +++++++                                 
   7 files changed, 88 insertions(+), 43 deletions(-)
Modified: trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp	(original)
+++ trunk/boost/spirit/home/karma/detail/indirect_iterator.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -64,17 +64,21 @@
     private:
         Iterator* iter_;
     };
+}}}}
 
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
     template <typename Iterator>
     struct make_indirect_iterator
     {
-        typedef indirect_iterator<Iterator> type;
+        typedef karma::detail::indirect_iterator<Iterator> type;
     };
 
     template <typename Iterator>
-    struct make_indirect_iterator<indirect_iterator<Iterator> >
+    struct make_indirect_iterator<karma::detail::indirect_iterator<Iterator> >
     {
-        typedef indirect_iterator<Iterator> type;
+        typedef karma::detail::indirect_iterator<Iterator> type;
     };
 
     template <>
@@ -82,6 +86,11 @@
     {
         typedef unused_type const* type;
     };
-}}}}
+
+    template <typename Iterator>
+    struct make_indirect_iterator<Iterator const&>
+      : make_indirect_iterator<Iterator const>
+    {};
+}}}
 
 #endif
Modified: trunk/boost/spirit/home/karma/directive/repeat.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/repeat.hpp	(original)
+++ trunk/boost/spirit/home/karma/directive/repeat.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -143,36 +143,36 @@
     {
     private:
         // iterate over the given container until its exhausted or the embedded
-        // (left) generator succeeds
-        template <
-            typename OutputIterator, typename Context, typename Delimiter
-          , typename Iterator, typename Attribute>
-        bool generate_subject(OutputIterator& sink, Context& ctx
-          , Delimiter const& d, Iterator& it, Iterator& end, Attribute const&) const
+        // generator succeeds
+        template <typename F, typename Attribute>
+        bool generate_subject(F f, Attribute const&, mpl::false_) const
         {
             // Failing subject generators are just skipped. This allows to 
             // selectively generate items in the provided attribute.
-            while (!traits::compare(it, end))
+            while (!f.is_at_end())
             {
-                if (subject.generate(sink, ctx, d, traits::deref(it)))
+                bool r = !f(subject);
+                if (r) 
                     return true;
-                if (Strict::value)
-                    return false;
-                traits::next(it);
+                if (!f.is_at_end())
+                    f.next();
             }
             return false;
         }
 
-        template <
-            typename OutputIterator, typename Context, typename Delimiter
-          , typename Iterator>
-        bool generate_subject(OutputIterator& sink, Context& ctx
-          , Delimiter const& d, Iterator&, Iterator&, unused_type) const
-        {
-            // There is no way to distinguish a failed generator from a 
-            // generator to be skipped. We assume the user takes responsibility
-            // for ending the loop if no attribute is specified.
-            return subject.generate(sink, ctx, d, unused);
+        template <typename F, typename Attribute>
+        bool generate_subject(F f, Attribute const&, mpl::true_) const
+        {
+            return !f(subject);
+        }
+
+        // There is no way to distinguish a failed generator from a 
+        // generator to be skipped. We assume the user takes responsibility
+        // for ending the loop if no attribute is specified.
+        template <typename F>
+        bool generate_subject(F f, unused_type, mpl::false_) const
+        {
+            return !f(subject);
         }
 
     public:
@@ -198,18 +198,33 @@
         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
           , Attribute const& attr) const
         {
+            typedef detail::fail_function<
+                OutputIterator, Context, Delimiter
+            > fail_function;
+
             typedef typename traits::container_iterator<
                 typename add_const<Attribute>::type
             >::type iterator_type;
 
+            typedef 
+                typename traits::make_indirect_iterator<iterator_type>::type 
+            indirect_iterator_type;
+
+            typedef detail::pass_container<
+                fail_function, Attribute, indirect_iterator_type, Strict>
+            pass_container;
+
             iterator_type it = traits::begin(attr);
             iterator_type end = traits::end(attr);
-            typename LoopIter::type i = iter.start();
+
+            pass_container pass(fail_function(sink, ctx, d), 
+                indirect_iterator_type(it), indirect_iterator_type(end));
 
             // generate the minimal required amount of output
-            for (/**/; !iter.got_min(i); ++i, traits::next(it))
+            typename LoopIter::type i = iter.start();
+            for (/**/; !pass.is_at_end() && !iter.got_min(i); ++i)
             {
-                if (!generate_subject(sink, ctx, d, it, end, attr))
+                if (!generate_subject(pass, attr, Strict()))
                 {
                     // if we fail before reaching the minimum iteration
                     // required, do not output anything and return false
@@ -217,11 +232,13 @@
                 }
             }
 
+            if (pass.is_at_end() && !iter.got_min(i))
+                return false;   // insufficient attribute elements
+
             // generate some more up to the maximum specified
-            for (/**/; detail::sink_is_good(sink) && !iter.got_max(i); 
-                 ++i, traits::next(it))
+            for (/**/; !pass.is_at_end() && !iter.got_max(i); ++i)
             {
-                if (!generate_subject(sink, ctx, d, it, end, attr))
+                if (!generate_subject(pass, attr, Strict()))
                     break;
             }
             return detail::sink_is_good(sink);
@@ -348,7 +365,6 @@
             return result_type(subject, fusion::at_c<0>(term.args));
         }
     };
-
 }}}
 
 namespace boost { namespace spirit { namespace traits
Modified: trunk/boost/spirit/home/karma/operator/kleene.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/kleene.hpp	(original)
+++ trunk/boost/spirit/home/karma/operator/kleene.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -106,8 +106,10 @@
             typedef typename traits::container_iterator<
                 typename add_const<Attribute>::type
             >::type iterator_type;
-            typedef typename detail::make_indirect_iterator<iterator_type>::type 
-                indirect_iterator_type;
+
+            typedef 
+                typename traits::make_indirect_iterator<iterator_type>::type 
+            indirect_iterator_type;
             typedef detail::pass_container<
                 fail_function, Attribute, indirect_iterator_type, Strict>
             pass_container;
Modified: trunk/boost/spirit/home/karma/operator/list.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/list.hpp	(original)
+++ trunk/boost/spirit/home/karma/operator/list.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -112,8 +112,9 @@
             typedef typename traits::container_iterator<
                 typename add_const<Attribute>::type
             >::type iterator_type;
+
             typedef 
-                typename detail::make_indirect_iterator<iterator_type>::type 
+                typename traits::make_indirect_iterator<iterator_type>::type 
             indirect_iterator_type;
             typedef detail::pass_container<
                 fail_function, Attribute, indirect_iterator_type, Strict>
@@ -142,7 +143,7 @@
                     }
                     buffering.buffer_copy();
                 }
-                return true;
+                return detail::sink_is_good(sink);
             }
             return false;
         }
Modified: trunk/boost/spirit/home/karma/operator/plus.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/plus.hpp	(original)
+++ trunk/boost/spirit/home/karma/operator/plus.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -118,8 +118,10 @@
             typedef typename traits::container_iterator<
                 typename add_const<Attribute>::type
             >::type iterator_type;
-            typedef typename detail::make_indirect_iterator<iterator_type>::type 
-                indirect_iterator_type;
+
+            typedef 
+                typename traits::make_indirect_iterator<iterator_type>::type 
+            indirect_iterator_type;
             typedef detail::pass_container<
                 fail_function, Attribute, indirect_iterator_type, Strict>
             pass_container;
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-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -177,10 +177,13 @@
             typedef detail::fail_function<
                 OutputIterator, Context, Delimiter> fail_function;
 
-            typedef typename traits::container_iterator<Attribute const>::type 
-                iterator_type;
-            typedef typename detail::make_indirect_iterator<iterator_type>::type 
-                indirect_iterator_type;
+            typedef typename traits::container_iterator<
+                typename add_const<Attribute>::type
+            >::type iterator_type;
+
+            typedef 
+                typename traits::make_indirect_iterator<iterator_type>::type 
+            indirect_iterator_type;
             typedef detail::pass_container<
                 fail_function, Attribute, indirect_iterator_type, Strict>
             pass_container;
Modified: trunk/boost/spirit/home/karma/phoenix_attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/phoenix_attributes.hpp	(original)
+++ trunk/boost/spirit/home/karma/phoenix_attributes.hpp	2011-02-20 14:26:24 EST (Sun, 20 Feb 2011)
@@ -16,6 +16,7 @@
 #if SPIRIT_VERSION >= 0x2020
 
 #include <boost/spirit/home/karma/detail/attributes.hpp>
+#include <boost/spirit/home/karma/detail/indirect_iterator.hpp>
 #include <boost/spirit/home/support/container.hpp>
 
 #include <boost/spirit/include/phoenix_core.hpp>
@@ -90,6 +91,18 @@
         }
     };
 
+    template <typename Eval>
+    struct container_value<phoenix::actor<Eval> >
+    {
+        typedef phoenix::actor<Eval> const& type;
+    };
+
+    template <typename Eval>
+    struct make_indirect_iterator<phoenix::actor<Eval> const>
+    {
+        typedef phoenix::actor<Eval> const& type;
+    };
+
     ///////////////////////////////////////////////////////////////////////////
     // Handle Phoenix actors as attributes, just invoke the function object
     // and deal with the result as the attribute.
@@ -105,7 +118,6 @@
             return f(unused, context);
         }
     };
-
 }}}
 
 #endif