Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55034 - in trunk/boost/spirit/home/karma: . detail directive operator
From: hartmut.kaiser_at_[hidden]
Date: 2009-07-19 22:38:29


Author: hkaiser
Date: 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
New Revision: 55034
URL: http://svn.boost.org/trac/boost/changeset/55034

Log:
Spirit: improving overall performance
Text files modified:
   trunk/boost/spirit/home/karma/detail/output_iterator.hpp | 97 ++++++++++++++++++++++++++++++---------
   trunk/boost/spirit/home/karma/directive/center_alignment.hpp | 1
   trunk/boost/spirit/home/karma/directive/left_alignment.hpp | 1
   trunk/boost/spirit/home/karma/directive/maxwidth.hpp | 5 +
   trunk/boost/spirit/home/karma/directive/repeat.hpp | 22 +++++---
   trunk/boost/spirit/home/karma/directive/right_alignment.hpp | 1
   trunk/boost/spirit/home/karma/generate.hpp | 12 ++++
   trunk/boost/spirit/home/karma/generator.hpp | 7 ++
   trunk/boost/spirit/home/karma/operator/alternative.hpp | 2
   trunk/boost/spirit/home/karma/operator/and_predicate.hpp | 1
   trunk/boost/spirit/home/karma/operator/not_predicate.hpp | 1
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 23 +++++++++
   12 files changed, 139 insertions(+), 34 deletions(-)

Modified: trunk/boost/spirit/home/karma/detail/output_iterator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/output_iterator.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/output_iterator.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -236,25 +236,6 @@
     class output_iterator : boost::noncopyable
     {
     private:
- struct output_proxy
- {
- output_proxy(output_iterator& parent)
- : parent(parent)
- {}
-
- template <typename T>
- void operator=(T const& value)
- {
- parent.output(value);
- }
-
- private:
- output_iterator& parent;
-
- // suppress warning about assignment operator not being generated
- output_proxy& operator=(output_proxy const&);
- };
-
         // get the most derived type of this class
         typedef typename mpl::if_<
             traits::is_not_unused<Derived>, Derived, output_iterator
@@ -296,7 +277,7 @@
           , track_position_data(rhs.track_position_data)
         {}
 
- output_proxy operator*() { return output_proxy(*this); }
+ output_iterator& operator*() { return *this; }
         output_iterator& operator++()
         {
             if (NULL == buffer)
@@ -313,8 +294,8 @@
             return *this;
         }
 
- template <typename T>
- void output(T const& value)
+ template <typename T>
+ output_iterator& operator=(T const& value)
         {
             if (NULL != count) // count characters, if appropriate
                 count->output();
@@ -327,6 +308,8 @@
                 buffer->output(value);
             else
                 *sink = value;
+
+ return *this;
         }
 
         // return the current count in the output
@@ -376,6 +359,76 @@
         bool good() const { return this->sink.get_ostream().good(); }
     };
 
+// ///////////////////////////////////////////////////////////////////////////
+// template <typename OutputIterator, typename Derived = unused_type>
+// class plain_output_iterator : boost::noncopyable
+// {
+// private:
+// // get the most derived type of this class
+// typedef typename mpl::if_<
+// traits::is_not_unused<Derived>, Derived, plain_output_iterator
+// >::type most_derived_type;
+//
+// public:
+// typedef std::output_iterator_tag iterator_category;
+// typedef void value_type;
+// typedef void difference_type;
+// typedef void pointer;
+// typedef void reference;
+//
+// explicit plain_output_iterator(OutputIterator& sink_)
+// : sink(sink_)
+// {}
+// plain_output_iterator(plain_output_iterator const& rhs)
+// : sink(rhs.sink)
+// , track_position_data(rhs.track_position_data)
+// {}
+//
+// plain_output_iterator& operator*() { return *this; }
+//
+// template <typename T>
+// plain_output_iterator& operator=(T const& value)
+// {
+// // always track position in the output (this is needed by different
+// // generators, such as indent, pad, etc.)
+// track_position_data.output(value);
+//
+// // output value by forwarding to the underlying iterator
+// *sink = value;
+// return *this;
+// }
+// plain_output_iterator& operator++()
+// {
+// ++sink;
+// return *this;
+// }
+// plain_output_iterator operator++(int)
+// {
+// plain_output_iterator t(*this);
+// ++sink;
+// return t;
+// }
+//
+// // return the current count in the output
+// std::size_t get_out_count() const
+// {
+// return track_position_data.get_count();
+// }
+//
+// // plain output iterators are considered to be good all the time
+// bool good() const { return true; }
+//
+// protected:
+// // this is the wrapped user supplied output iterator
+// OutputIterator& sink;
+//
+// private:
+// position_sink track_position_data; // for position tracking
+//
+// // suppress warning about assignment operator not being generated
+// plain_output_iterator& operator=(plain_output_iterator const&);
+// };
+
     ///////////////////////////////////////////////////////////////////////////
     // Helper class for exception safe enabling of character counting in the
     // output iterator

Modified: trunk/boost/spirit/home/karma/directive/center_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/center_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/center_alignment.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -128,6 +128,7 @@
     struct simple_center_alignment
       : unary_generator<simple_center_alignment<Subject, Width> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>

Modified: trunk/boost/spirit/home/karma/directive/left_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/left_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/left_alignment.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -111,6 +111,7 @@
     struct simple_left_alignment
       : unary_generator<simple_left_alignment<Subject, Width> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>

Modified: trunk/boost/spirit/home/karma/directive/maxwidth.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/maxwidth.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/maxwidth.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -110,11 +110,11 @@
             // maxwidth
             bool r = false;
 
- {
+ {
                 detail::disable_counting<OutputIterator> nocounting(sink);
                 r = e.generate(sink, ctx, d, attr);
             } // re-enable counting
-
+
             return r && buffering.buffer_copy(maxwidth) &&
                    buffer_copy_rest(buffering, maxwidth, restdest);
         }
@@ -133,6 +133,7 @@
     struct maxwidth_width
       : unary_generator<maxwidth_width<Subject, Width, Rest> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>

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 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -124,6 +124,7 @@
     struct repeat_generator
       : unary_generator<repeat_generator<Subject, LoopIter> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>
@@ -158,19 +159,22 @@
             {
                 // inhibit (redirect) output, disable counting while buffering
                 detail::enable_buffering<OutputIterator> buffering(sink);
- detail::disable_counting<OutputIterator> nocounting(sink);
 
- // generate the minimal required amount of output
- for (/**/; !iter.got_min(i); ++i, traits::next(it))
                 {
- if (traits::compare(it, end) ||
- !subject.generate(sink, ctx, d, traits::deref(it)))
+ detail::disable_counting<OutputIterator> nocounting(sink);
+
+ // generate the minimal required amount of output
+ for (/**/; !iter.got_min(i); ++i, traits::next(it))
                     {
- // if we fail before reaching the minimum iteration
- // required, do not output anything and return false
- return false;
+ if (traits::compare(it, end) ||
+ !subject.generate(sink, ctx, d, traits::deref(it)))
+ {
+ // if we fail before reaching the minimum iteration
+ // required, do not output anything and return false
+ return false;
+ }
                     }
- }
+ } // re-enable counting
 
                 // copy the output generated so far to the target output iterator
                 buffering.buffer_copy();

Modified: trunk/boost/spirit/home/karma/directive/right_alignment.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/right_alignment.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/right_alignment.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -121,6 +121,7 @@
     struct simple_right_alignment
       : unary_generator<simple_right_alignment<Subject, Width> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>

Modified: trunk/boost/spirit/home/karma/generate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/generate.hpp (original)
+++ trunk/boost/spirit/home/karma/generate.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -40,7 +40,17 @@
         // then the expression (expr) is not a valid spirit karma expression.
         BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
 
- // wrap user supplied iterator into our own output iterator
+// typedef typename result_of::compile<
+// karma::domain, Expr, unused_type
+// >::type generator;
+//
+// // wrap user supplied iterator into our own output iterator
+// typedef typename mpl::if_<
+// traits::requires_buffering<generator>
+// , detail::output_iterator<OutputIterator>
+// , detail::plain_output_iterator<OutputIterator>
+// >::type output_iterator;
+
         detail::output_iterator<OutputIterator> sink(target_sink);
         return compile<karma::domain>(expr).generate(sink, unused, unused, unused);
     }

Modified: trunk/boost/spirit/home/karma/generator.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/generator.hpp (original)
+++ trunk/boost/spirit/home/karma/generator.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -20,6 +20,7 @@
     struct generator
     {
         struct generator_id;
+ typedef mpl::false_ requires_buffering;
         typedef Derived derived_type;
         typedef karma::domain domain;
 
@@ -110,6 +111,7 @@
 {
     namespace detail
     {
+ // generator tags
         BOOST_MPL_HAS_XXX_TRAIT_DEF(generator_id)
         BOOST_MPL_HAS_XXX_TRAIT_DEF(primitive_generator_id)
         BOOST_MPL_HAS_XXX_TRAIT_DEF(nary_generator_id)
@@ -117,6 +119,7 @@
         BOOST_MPL_HAS_XXX_TRAIT_DEF(binary_generator_id)
     }
 
+ // check for generator tags
     template <typename T>
     struct is_generator : detail::has_generator_id<T> {};
 
@@ -132,6 +135,10 @@
     template <typename T>
     struct is_binary_generator : detail::has_binary_generator_id<T> {};
 
+ // check for generator properties
+ template <typename T>
+ struct requires_buffering : T::requires_buffering {};
+
 }}}
 
 #endif

Modified: trunk/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/alternative.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/alternative.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -43,6 +43,8 @@
     template <typename Elements>
     struct alternative : nary_generator<alternative<Elements> >
     {
+ typedef mpl::true_ requires_buffering;
+
         template <typename Context, typename Unused = unused_type>
         struct attribute
         {

Modified: trunk/boost/spirit/home/karma/operator/and_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/and_predicate.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/and_predicate.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -34,6 +34,7 @@
     template <typename Subject>
     struct and_predicate : unary_generator<and_predicate<Subject> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Iterator>

Modified: trunk/boost/spirit/home/karma/operator/not_predicate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/not_predicate.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/not_predicate.hpp 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -34,6 +34,7 @@
     template <typename Subject>
     struct not_predicate : unary_generator<not_predicate<Subject> >
     {
+ typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
         template <typename Context, typename Iterator>

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 2009-07-19 22:38:27 EDT (Sun, 19 Jul 2009)
@@ -27,7 +27,9 @@
 #include <boost/fusion/include/for_each.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/mpl/not.hpp>
+#include <boost/mpl/find_if.hpp>
 
+///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -44,11 +46,32 @@
 }}
 
 ///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace traits
+{
+ // specialization for sequences
+ template <typename Sequence>
+ struct sequence_requires_buffering
+ {
+ typedef typename mpl::find_if<
+ Sequence, requires_buffering<mpl::_1>
+ >::type iterator;
+
+ typedef typename mpl::not_<
+ is_same<iterator, typename mpl::end<Sequence>::type>
+ >::type type;
+ };
+
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace karma
 {
     template <typename Elements>
     struct sequence : nary_generator<sequence<Elements> >
     {
+ typedef typename traits::sequence_requires_buffering<Elements>::type
+ requires_buffering;
+
         sequence(Elements const& elements)
           : elements(elements) {}
 


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