|
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