Boost logo

Boost-Commit :

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


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