Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r55064 - in trunk/boost/spirit/home/karma: . action auxiliary binary detail directive nonterminal operator stream
From: hartmut.kaiser_at_[hidden]
Date: 2009-07-21 10:42:59


Author: hkaiser
Date: 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
New Revision: 55064
URL: http://svn.boost.org/trac/boost/changeset/55064

Log:
Spirit: Added output iterator composition
Text files modified:
   trunk/boost/spirit/home/karma/action/action.hpp | 5
   trunk/boost/spirit/home/karma/auxiliary/eps.hpp | 2
   trunk/boost/spirit/home/karma/auxiliary/lazy.hpp | 4
   trunk/boost/spirit/home/karma/binary/binary.hpp | 2
   trunk/boost/spirit/home/karma/binary/padding.hpp | 5
   trunk/boost/spirit/home/karma/detail/alternative_function.hpp | 5
   trunk/boost/spirit/home/karma/detail/output_iterator.hpp | 321 +++++++++++++++++++++++----------------
   trunk/boost/spirit/home/karma/detail/string_generate.hpp | 51 +++--
   trunk/boost/spirit/home/karma/directive/center_alignment.hpp | 10 +
   trunk/boost/spirit/home/karma/directive/delimit.hpp | 4
   trunk/boost/spirit/home/karma/directive/left_alignment.hpp | 10 +
   trunk/boost/spirit/home/karma/directive/maxwidth.hpp | 6
   trunk/boost/spirit/home/karma/directive/repeat.hpp | 5
   trunk/boost/spirit/home/karma/directive/right_alignment.hpp | 10 +
   trunk/boost/spirit/home/karma/directive/verbatim.hpp | 1
   trunk/boost/spirit/home/karma/generate.hpp | 66 +++++--
   trunk/boost/spirit/home/karma/generate_attr.hpp | 39 +++
   trunk/boost/spirit/home/karma/generator.hpp | 20 ++
   trunk/boost/spirit/home/karma/nonterminal/grammar.hpp | 4
   trunk/boost/spirit/home/karma/nonterminal/rule.hpp | 6
   trunk/boost/spirit/home/karma/operator/alternative.hpp | 2
   trunk/boost/spirit/home/karma/operator/and_predicate.hpp | 4
   trunk/boost/spirit/home/karma/operator/kleene.hpp | 1
   trunk/boost/spirit/home/karma/operator/list.hpp | 4
   trunk/boost/spirit/home/karma/operator/not_predicate.hpp | 5
   trunk/boost/spirit/home/karma/operator/optional.hpp | 1
   trunk/boost/spirit/home/karma/operator/plus.hpp | 1
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 52 +++--
   trunk/boost/spirit/home/karma/reference.hpp | 2
   trunk/boost/spirit/home/karma/stream/format_manip.hpp | 5
   trunk/boost/spirit/home/karma/stream/stream.hpp | 14
   31 files changed, 433 insertions(+), 234 deletions(-)

Modified: trunk/boost/spirit/home/karma/action/action.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/action/action.hpp (original)
+++ trunk/boost/spirit/home/karma/action/action.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -33,6 +33,9 @@
     template <typename Subject, typename Action>
     struct action : unary_generator<action<Subject, Action> >
     {
+ typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
+
         template <typename Context, typename Unused>
         struct attribute
           : traits::attribute_of<Subject, Context, Unused>
@@ -69,7 +72,7 @@
             return subject.what(context);
         }
 
- Subject subject;
+ subject_type subject;
         Action f;
     };
 

Modified: trunk/boost/spirit/home/karma/auxiliary/eps.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/auxiliary/eps.hpp (original)
+++ trunk/boost/spirit/home/karma/auxiliary/eps.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -68,7 +68,7 @@
         }
     };
 
- struct semantic_predicate
+ struct semantic_predicate : primitive_generator<semantic_predicate>
     {
         template <typename Context, typename Unused>
         struct attribute

Modified: trunk/boost/spirit/home/karma/auxiliary/lazy.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/auxiliary/lazy.hpp (original)
+++ trunk/boost/spirit/home/karma/auxiliary/lazy.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -47,6 +47,8 @@
     template <typename Function, typename Modifiers>
     struct lazy_generator : generator<lazy_generator<Function, Modifiers> >
     {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {
@@ -108,6 +110,8 @@
     struct lazy_directive
       : unary_generator<lazy_directive<Function, Subject, Modifiers> >
     {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
         typedef Subject subject_type;
 
         template <typename Context, typename Unused>

Modified: trunk/boost/spirit/home/karma/binary/binary.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/binary/binary.hpp (original)
+++ trunk/boost/spirit/home/karma/binary/binary.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -223,7 +223,7 @@
     template <BOOST_SCOPED_ENUM(boost::integer::endianness) endian, int bits
       , bool no_attribute>
     struct literal_binary_generator
- : primitive_generator<literal_binary_generator<endian, bits> >
+ : primitive_generator<literal_binary_generator<endian, bits, no_attribute> >
     {
         typedef boost::integer::endian<
             endian, typename karma::detail::integer<bits>::type, bits

Modified: trunk/boost/spirit/home/karma/binary/padding.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/binary/padding.hpp (original)
+++ trunk/boost/spirit/home/karma/binary/padding.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -44,8 +44,11 @@
     using boost::spirit::pad;
     using boost::spirit::pad_type;
 
- struct binary_padding_generator
+ struct binary_padding_generator
+ : primitive_generator<binary_padding_generator>
     {
+ typedef mpl::int_<generator_properties::tracking> properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

Modified: trunk/boost/spirit/home/karma/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/alternative_function.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/alternative_function.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -21,6 +21,7 @@
 #include <boost/mpl/distance.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 #include <boost/variant.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -32,7 +33,9 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Expected, typename Attribute, typename IsNotVariant>
     struct compute_compatible_component_variant
- : mpl::or_<is_same<Expected, Attribute>, is_same<Expected, hold_any> > {};
+ : mpl::or_<
+ is_convertible<Attribute, Expected>
+ , is_same<hold_any, Expected> > {};
 
     template <typename Expected, typename Attribute>
     struct compute_compatible_component_variant<Expected, Attribute, mpl::false_>

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -55,6 +55,39 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ struct position_policy
+ {
+ position_policy() {}
+ position_policy(position_policy const& rhs)
+ : track_position_data(rhs.track_position_data) {}
+
+ template <typename T>
+ void output(T const& value)
+ {
+ // track position in the output
+ track_position_data.output(value);
+ }
+
+ // return the current count in the output
+ std::size_t get_out_count() const
+ {
+ return track_position_data.get_count();
+ }
+
+ private:
+ position_sink track_position_data; // for position tracking
+ };
+
+ struct no_position_policy
+ {
+ no_position_policy() {}
+ no_position_policy(no_position_policy const& rhs) {}
+
+ template <typename T>
+ void output(T const& value) {}
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // This class is used to count the number of characters streamed into the
     // output.
     ///////////////////////////////////////////////////////////////////////////
@@ -95,6 +128,44 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ template <typename OutputIterator>
+ struct counting_policy
+ {
+ public:
+ counting_policy() : count(NULL) {}
+ counting_policy(counting_policy const& rhs) : count(rhs.count) {}
+
+ // functions related to counting
+ counting_sink<OutputIterator>* chain_counting(
+ counting_sink<OutputIterator>* count_data)
+ {
+ counting_sink<OutputIterator>* prev_count = count;
+ count = count_data;
+ return prev_count;
+ }
+
+ template <typename T>
+ void output(T const&)
+ {
+ // count characters, if appropriate
+ if (NULL != count)
+ count->output();
+ }
+
+ private:
+ counting_sink<OutputIterator>* count; // for counting
+ };
+
+ struct no_counting_policy
+ {
+ no_counting_policy() {}
+ no_counting_policy(no_counting_policy const& rhs) {}
+
+ template <typename T>
+ void output(T const& value) {}
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // The following classes are used to intercept the output into a buffer
     // allowing to do things like alignment, character escaping etc.
     //
@@ -216,9 +287,107 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ template <typename OutputIterator>
+ struct buffering_policy
+ {
+ public:
+ buffering_policy() : buffer(NULL) {}
+ buffering_policy(buffering_policy const& rhs) : buffer(rhs.buffer) {}
+
+ // functions related to counting
+ buffer_sink<OutputIterator>* chain_buffering(
+ buffer_sink<OutputIterator>* buffer_data)
+ {
+ buffer_sink<OutputIterator>* prev_buffer = buffer;
+ buffer = buffer_data;
+ return prev_buffer;
+ }
+
+ template <typename T>
+ void output(T const& value)
+ {
+ // count characters, if appropriate
+ if (NULL != buffer)
+ buffer->output(value);
+ }
+
+ bool has_buffer() const { return NULL != buffer; }
+
+ private:
+ buffer_sink<OutputIterator>* buffer;
+ };
+
+ struct no_buffering_policy
+ {
+ no_buffering_policy() {}
+ no_buffering_policy(no_counting_policy const& rhs) {}
+
+ template <typename T>
+ void output(T const& value) {}
+
+ bool has_buffer() const { return false; }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // forward declaration only
+ template <typename OutputIterator>
+ struct enable_buffering;
+
+ template <typename OutputIterator, typename Properties
+ , typename Derived = unused_type>
+ class output_iterator;
+
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator> struct enable_buffering;
+ template <typename Buffering, typename Counting, typename Tracking>
+ struct output_iterator_base : Buffering, Counting, Tracking
+ {
+ typedef Buffering buffering_policy;
+ typedef Counting counting_policy;
+ typedef Tracking tracking_policy;
+
+ output_iterator_base() {}
+ output_iterator_base(output_iterator_base const& rhs)
+ : buffering_policy(rhs), counting_policy(rhs), tracking_policy(rhs)
+ {}
+
+ template <typename T>
+ void output(T const& value)
+ {
+ this->counting_policy::output(value);
+ this->tracking_policy::output(value);
+ this->buffering_policy::output(value);
+ }
+ };
+
+ template <typename OutputIterator, typename Properties, typename Derived>
+ struct make_output_iterator
+ {
+ // get the most derived type of this class
+ typedef typename mpl::if_<
+ traits::is_not_unused<Derived>, Derived
+ , output_iterator<OutputIterator, Properties, Derived>
+ >::type most_derived_type;
+
+ enum { properties = Properties::value };
+
+ typedef typename mpl::if_c<
+ properties & generator_properties::tracking ? true : false
+ , position_policy, no_position_policy
+ >::type tracking_type;
+
+ typedef typename mpl::if_c<
+ properties & generator_properties::buffering ? true : false
+ , buffering_policy<most_derived_type>, no_buffering_policy
+ >::type buffering_type;
+
+ typedef typename mpl::if_c<
+ properties & generator_properties::counting ? true : false
+ , counting_policy<most_derived_type>, no_counting_policy
+ >::type counting_type;
+
+ typedef output_iterator_base<
+ buffering_type, counting_type, tracking_type> type;
+ };
 
     ///////////////////////////////////////////////////////////////////////////
     // Karma uses an output iterator wrapper for all output operations. This
@@ -232,33 +401,15 @@
     // supplied iterator. But it is possible to enable additional functionality
     // on demand, such as counting, buffering, and position tracking.
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Derived = unused_type>
- class output_iterator : boost::noncopyable
+ template <typename OutputIterator, typename Properties, typename Derived>
+ class output_iterator
+ : public make_output_iterator<OutputIterator, Properties, Derived>::type
+ , boost::noncopyable
     {
     private:
- // get the most derived type of this class
- typedef typename mpl::if_<
- traits::is_not_unused<Derived>, Derived, output_iterator
- >::type most_derived_type;
-
- public:
- // functions related to counting
- counting_sink<most_derived_type>* chain_counting(
- counting_sink<most_derived_type>* count_data)
- {
- counting_sink<most_derived_type>* prev_count = count;
- count = count_data;
- return prev_count;
- }
-
- // functions related to buffering
- buffer_sink<most_derived_type>* chain_buffering(
- buffer_sink<most_derived_type>* buffer_data)
- {
- buffer_sink<most_derived_type>* prev_buffer = buffer;
- buffer = buffer_data;
- return prev_buffer;
- }
+ // base iterator type
+ typedef typename make_output_iterator<
+ OutputIterator, Properties, Derived>::type base_iterator;
 
     public:
         typedef std::output_iterator_tag iterator_category;
@@ -269,24 +420,21 @@
 
         explicit output_iterator(OutputIterator& sink_)
           : sink(sink_)
- , count(NULL), buffer(NULL)
         {}
         output_iterator(output_iterator const& rhs)
- : sink(rhs.sink)
- , count(rhs.count), buffer(rhs.buffer)
- , track_position_data(rhs.track_position_data)
+ : sink(rhs.sink), base_iterator(rhs)
         {}
 
         output_iterator& operator*() { return *this; }
         output_iterator& operator++()
         {
- if (NULL == buffer)
+ if (!this->base_iterator::has_buffer())
                 ++sink; // increment only if not buffering
             return *this;
         }
         output_iterator operator++(int)
         {
- if (NULL == buffer) {
+ if (!this->base_iterator::has_buffer()) {
                 output_iterator t(*this);
                 ++sink;
                 return t;
@@ -295,27 +443,11 @@
         }
 
         template <typename T>
- output_iterator& operator=(T const& value)
+ void operator=(T const& value)
         {
- if (NULL != count) // count characters, if appropriate
- count->output();
-
- // always track position in the output (this is needed by different
- // generators, such as indent, pad, etc.)
- track_position_data.output(value);
-
- if (NULL != buffer) // buffer output, if appropriate
- buffer->output(value);
- else
+ this->base_iterator::output(value);
+ if (!this->base_iterator::has_buffer())
                 *sink = value;
-
- return *this;
- }
-
- // 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
@@ -326,24 +458,19 @@
         OutputIterator& sink;
 
     private:
- // these are the hooks providing optional functionality
- counting_sink<most_derived_type>* count; // for counting
- buffer_sink<most_derived_type>* buffer; // for buffering
- position_sink track_position_data; // for position tracking
-
         // suppress warning about assignment operator not being generated
         output_iterator& operator=(output_iterator const&);
     };
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename T, typename Elem, typename Traits>
- class output_iterator<ostream_iterator<T, Elem, Traits> >
- : public output_iterator<ostream_iterator<T, Elem, Traits>
- , output_iterator<ostream_iterator<T, Elem, Traits> > >
+ template <typename T, typename Elem, typename Traits, typename Properties>
+ class output_iterator<ostream_iterator<T, Elem, Traits>, Properties>
+ : public output_iterator<ostream_iterator<T, Elem, Traits>, Properties
+ , output_iterator<ostream_iterator<T, Elem, Traits>, Properties> >
     {
     private:
- typedef output_iterator<ostream_iterator<T, Elem, Traits>
- , output_iterator<ostream_iterator<T, Elem, Traits> >
+ typedef output_iterator<ostream_iterator<T, Elem, Traits>, Properties
+ , output_iterator<ostream_iterator<T, Elem, Traits>, Properties>
> base_type;
         typedef ostream_iterator<T, Elem, Traits> base_iterator_type;
         typedef std::basic_ostream<Elem, Traits> ostream_type;
@@ -359,76 +486,6 @@
         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/detail/string_generate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/string_generate.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/string_generate.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -24,61 +24,64 @@
     {
         for (Char ch = *str; ch != 0; ch = *++str)
         {
- if (!detail::generate_to(sink, ch))
- return false;
+ *sink = ch;
+ ++sink;
         }
- return true;
+ return detail::sink_is_good(sink);
     }
 
     ///////////////////////////////////////////////////////////////////////////
     // generate a string given by a std::string
- template <
- typename OutputIterator, typename Char, typename Traits
+ template <typename OutputIterator, typename Char, typename Traits
       , typename Allocator>
     inline bool string_generate(OutputIterator& sink
       , std::basic_string<Char, Traits, Allocator> const& str)
     {
- BOOST_FOREACH(Char ch, str)
- {
- if (!detail::generate_to(sink, ch))
- return false;
- }
- return true;
+ return string_generate(sink, str.c_str());
     }
 
     ///////////////////////////////////////////////////////////////////////////
     // generate a string given by a pointer, converting according using a
     // given character class and case tag
- template <
- typename OutputIterator, typename Char, typename CharEncoding
+ template <typename OutputIterator, typename Char, typename CharEncoding
       , typename Tag>
     inline bool string_generate(OutputIterator& sink, Char const* str
       , CharEncoding ce, Tag tag)
     {
         for (Char ch = *str; ch != 0; ch = *++str)
         {
- if (!detail::generate_to(sink, ch, ce, tag))
- return false;
+ *sink = spirit::char_class::convert<CharEncoding>::to(Tag(), ch);
+ ++sink;
         }
- return true;
+ return detail::sink_is_good(sink);
+ }
+
+ template <typename OutputIterator, typename Char>
+ inline bool string_generate(OutputIterator& sink, Char const* str
+ , unused_type, unused_type)
+ {
+ return string_generate(sink, str);
     }
 
     ///////////////////////////////////////////////////////////////////////////
     // generate a string given by a std::string, converting according using a
     // given character class and case tag
- template <
- typename OutputIterator, typename Char, typename CharEncoding
+ template <typename OutputIterator, typename Char, typename CharEncoding
       , typename Tag, typename Traits, typename Allocator>
     inline bool string_generate(OutputIterator& sink
       , std::basic_string<Char, Traits, Allocator> const& str
       , CharEncoding ce, Tag tag)
     {
- BOOST_FOREACH(Char ch, str)
- {
- if (!detail::generate_to(sink, ch, ce, tag))
- return false;
- }
- return true;
+ return string_generate(sink, str.c_str(), ce, tag);
+ }
+
+ template <typename OutputIterator, typename Char, typename Traits
+ , typename Allocator>
+ inline bool string_generate(OutputIterator& sink
+ , std::basic_string<Char, Traits, Allocator> const& str
+ , unused_type, unused_type)
+ {
+ return string_generate(sink, str.c_str());
     }
 
 }}}}

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -128,9 +128,12 @@
     struct simple_center_alignment
       : unary_generator<simple_center_alignment<Subject, Width> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {
@@ -175,6 +178,11 @@
         typedef Subject subject_type;
         typedef Padding padding_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer |
+ subject_type::properties::value | padding_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

Modified: trunk/boost/spirit/home/karma/directive/delimit.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/delimit.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/delimit.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -58,6 +58,8 @@
     {
         typedef Subject subject_type;
 
+ typedef typename subject_type::properties properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {
@@ -102,6 +104,8 @@
         typedef Subject subject_type;
         typedef Delimiter delimiter_type;
 
+ typedef typename subject_type::properties properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -111,9 +111,12 @@
     struct simple_left_alignment
       : unary_generator<simple_left_alignment<Subject, Width> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::counting | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {
@@ -158,6 +161,11 @@
         typedef Subject subject_type;
         typedef Padding padding_type;
 
+ typedef mpl::int_<
+ generator_properties::counting |
+ subject_type::properties::value | padding_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -109,7 +109,6 @@
             // output to the target output iterator applying the given
             // maxwidth
             bool r = false;
-
             {
                 detail::disable_counting<OutputIterator> nocounting(sink);
                 r = e.generate(sink, ctx, d, attr);
@@ -133,9 +132,12 @@
     struct maxwidth_width
       : unary_generator<maxwidth_width<Subject, Width, Rest> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -124,9 +124,12 @@
     struct repeat_generator
       : unary_generator<repeat_generator<Subject, LoopIter> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -121,9 +121,12 @@
     struct simple_right_alignment
       : unary_generator<simple_right_alignment<Subject, Width> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {
@@ -168,6 +171,11 @@
         typedef Subject subject_type;
         typedef Padding padding_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer |
+ subject_type::properties::value | padding_type::properties::value
+ > properties;
+
         template <typename Context, typename Unused>
         struct attribute
         {

Modified: trunk/boost/spirit/home/karma/directive/verbatim.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/directive/verbatim.hpp (original)
+++ trunk/boost/spirit/home/karma/directive/verbatim.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -44,6 +44,7 @@
     struct verbatim_generator : unary_generator<verbatim_generator<Subject> >
     {
         typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
 
         template <typename Context, typename Unused>
         struct attribute

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -40,25 +40,20 @@
         // then the expression (expr) is not a valid spirit karma expression.
         BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
 
-// 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;
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
 
- detail::output_iterator<OutputIterator> sink(target_sink);
+ // wrap user supplied iterator into our own output iterator
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value> > sink(target_sink);
         return compile<karma::domain>(expr).generate(sink, unused, unused, unused);
     }
 
- template <typename OutputIterator, typename Expr>
+ template <typename OutputIterator, typename Properties, typename Expr>
     inline bool
     generate(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr)
     {
         // Report invalid expression error as early as possible.
@@ -81,15 +76,21 @@
         // then the expression (expr) is not a valid spirit karma expression.
         BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
 
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value> > sink(target_sink);
         return compile<karma::domain>(expr).generate(sink, unused, unused, attr);
     }
 
- template <typename OutputIterator, typename Expr, typename Attr>
+ template <typename OutputIterator, typename Properties, typename Expr
+ , typename Attr>
     inline bool
     generate(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr
       , Attr const& attr)
     {
@@ -101,10 +102,11 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Expr, typename Delimiter>
+ template <typename OutputIterator, typename Properties, typename Expr
+ , typename Delimiter>
     inline bool
     generate_delimited(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr
       , Delimiter const& delimiter
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit =
@@ -139,17 +141,26 @@
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit =
             delimit_flag::dont_predelimit)
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Delimiter>::type
+ > delimiter_properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value | delimiter_properties::value>
+ > sink(target_sink);
         return generate_delimited(sink, expr, delimiter, pre_delimit);
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Expr, typename Delimiter
- , typename Attribute>
+ template <typename OutputIterator, typename Properties, typename Expr
+ , typename Delimiter, typename Attribute>
     inline bool
     generate_delimited(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr
       , Delimiter const& delimiter
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
@@ -186,8 +197,17 @@
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
       , Attribute const& attr)
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Delimiter>::type
+ > delimiter_properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value | delimiter_properties::value>
+ > sink(target_sink);
         return generate_delimited(sink, expr, delimiter, pre_delimit, attr);
     }
 

Modified: trunk/boost/spirit/home/karma/generate_attr.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/generate_attr.hpp (original)
+++ trunk/boost/spirit/home/karma/generate_attr.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -37,11 +37,11 @@
 namespace boost { namespace spirit { namespace karma
 {
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Expr
+ template <typename OutputIterator, typename Properties, typename Expr
       , BOOST_PP_ENUM_PARAMS(N, typename A)>
     inline bool
     generate(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
     {
@@ -66,17 +66,22 @@
       , Expr const& expr
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value> > sink(target_sink);
         return generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename OutputIterator, typename Expr, typename Delimiter
- , BOOST_PP_ENUM_PARAMS(N, typename A)>
+ template <typename OutputIterator, typename Properties, typename Expr
+ , typename Delimiter, BOOST_PP_ENUM_PARAMS(N, typename A)>
     inline bool
     generate_delimited(
- detail::output_iterator<OutputIterator>& sink
+ detail::output_iterator<OutputIterator, Properties>& sink
       , Expr const& expr
       , Delimiter const& delimiter
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
@@ -117,8 +122,17 @@
       , BOOST_SCOPED_ENUM(delimit_flag) pre_delimit
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Delimiter>::type
+ > delimiter_properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value | delimiter_properties::value>
+ > sink(target_sink);
         return generate_delimited(sink, expr, delimiter, pre_delimit
           , BOOST_PP_ENUM_PARAMS(N, attr));
     }
@@ -132,8 +146,17 @@
       , Delimiter const& delimiter
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& attr))
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Expr>::type
+ > properties;
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Delimiter>::type
+ > delimiter_properties;
+
         // wrap user supplied iterator into our own output iterator
- detail::output_iterator<OutputIterator> sink(target_sink);
+ detail::output_iterator<OutputIterator
+ , mpl::int_<properties::value | delimiter_properties::value>
+ > sink(target_sink);
         return generate_delimited(sink, expr, delimiter
           , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
     }

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -12,15 +12,29 @@
 #endif
 
 #include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 
 namespace boost { namespace spirit { namespace karma
 {
+ BOOST_SCOPED_ENUM_START(generator_properties)
+ {
+ no_properties = 0,
+ buffering = 0x01, // generator requires buffering
+ counting = 0x02, // generator requires counting
+ tracking = 0x04, // generator requires position tracking
+
+ countingbuffer = 0x03, // buffering | counting
+ all_properties = 0x07 // buffering | counting | tracking
+ };
+ BOOST_SCOPED_ENUM_END
+
     template <typename Derived>
     struct generator
     {
         struct generator_id;
-// typedef mpl::true_ requires_buffering;
+ typedef mpl::int_<generator_properties::no_properties> properties;
         typedef Derived derived_type;
         typedef karma::domain domain;
 
@@ -136,8 +150,8 @@
     struct is_binary_generator : detail::has_binary_generator_id<T> {};
 
     // check for generator properties
-// template <typename T>
-// struct requires_buffering : T::requires_buffering {};
+ template <typename T>
+ struct properties : T::properties {};
 
 }}}
 

Modified: trunk/boost/spirit/home/karma/nonterminal/grammar.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/grammar.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/grammar.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -38,6 +38,7 @@
     {
         typedef OutputIterator iterator_type;
         typedef rule<OutputIterator, T1, T2, T3> start_type;
+ typedef typename start_type::properties properties;
         typedef typename start_type::sig_type sig_type;
         typedef typename start_type::locals_type locals_type;
         typedef typename start_type::delimiter_type delimiter_type;
@@ -47,7 +48,8 @@
         static size_t const params_size = start_type::params_size;
 
         // the output iterator is always wrapped by karma
- typedef detail::output_iterator<OutputIterator> output_iterator;
+ typedef detail::output_iterator<OutputIterator, properties>
+ output_iterator;
 
         grammar(start_type const& start
               , std::string const& name_ = "unnamed-grammar")

Modified: trunk/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/nonterminal/rule.hpp (original)
+++ trunk/boost/spirit/home/karma/nonterminal/rule.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -59,6 +59,8 @@
     template <typename Rule, typename Params>
     struct parameterized_rule : generator<parameterized_rule<Rule, Params> >
     {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
         parameterized_rule(Rule const& rule, Params const& params)
           : ref(rule), params(params) {}
 
@@ -99,6 +101,7 @@
>
       , generator<rule<OutputIterator, T1, T2, T3> >
     {
+ typedef mpl::int_<generator_properties::all_properties> properties;
         typedef rule<OutputIterator, T1, T2, T3> this_type;
         typedef reference<this_type const> reference_;
         typedef typename proto::terminal<reference_>::type terminal;
@@ -106,7 +109,8 @@
         typedef mpl::vector<T1, T2, T3> template_params;
 
         // the output iterator is always wrapped by karma
- typedef detail::output_iterator<OutputIterator> output_iterator;
+ typedef detail::output_iterator<OutputIterator, properties>
+ output_iterator;
 
         // locals_type is a sequence of types to be used as local variables
         typedef typename fusion::result_of::as_vector<

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -43,7 +43,7 @@
     template <typename Elements>
     struct alternative : nary_generator<alternative<Elements> >
     {
-// typedef mpl::true_ requires_buffering;
+ typedef mpl::int_<generator_properties::all_properties> properties;
 
         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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -34,8 +34,10 @@
     template <typename Subject>
     struct and_predicate : unary_generator<and_predicate<Subject> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
 
         template <typename Context, typename Iterator>
         struct attribute

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 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -39,6 +39,7 @@
     struct kleene : unary_generator<kleene<Subject> >
     {
         typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
 
         template <typename Context, typename Unused>
         struct attribute

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 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -34,6 +34,10 @@
         typedef Left left_type;
         typedef Right right_type;
 
+ typedef mpl::int_<
+ left_type::properties::value | right_type::properties::value
+ > properties;
+
         template <typename Context, typename Iterator>
         struct attribute
         {

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -34,9 +34,12 @@
     template <typename Subject>
     struct not_predicate : unary_generator<not_predicate<Subject> >
     {
-// typedef mpl::true_ requires_buffering;
         typedef Subject subject_type;
 
+ typedef mpl::int_<
+ generator_properties::countingbuffer | subject_type::properties::value
+ > properties;
+
         template <typename Context, typename Iterator>
         struct attribute
         {

Modified: trunk/boost/spirit/home/karma/operator/optional.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/optional.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/optional.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -80,6 +80,7 @@
     struct optional : unary_generator<optional<Subject> >
     {
         typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
 
         template <typename Context, typename Unused>
         struct attribute

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 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -39,6 +39,7 @@
     struct plus : unary_generator<plus<Subject> >
     {
         typedef Subject subject_type;
+ typedef typename subject_type::properties properties;
 
         template <typename Context, typename Unused>
         struct attribute

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-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -26,8 +26,10 @@
 #include <boost/fusion/include/as_vector.hpp>
 #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>
+#include <boost/mpl/bitor.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/fusion/include/transform.hpp>
+#include <boost/mpl/accumulate.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit
@@ -46,22 +48,33 @@
 }}
 
 ///////////////////////////////////////////////////////////////////////////////
-// 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 traits
+{
+ // specialization for sequences
+ template <typename Sequence>
+ struct sequence_properties
+ {
+ struct element_properties
+ {
+ template <typename T>
+ struct result;
+
+ template <typename F, typename Element>
+ struct result<F(Element)>
+ {
+ typedef properties<Element> type;
+ };
+ };
+
+ typedef typename mpl::accumulate<
+ typename fusion::result_of::transform<
+ Sequence, element_properties>::type
+ , mpl::int_<karma::generator_properties::no_properties>
+ , mpl::bitor_<mpl::_2, mpl::_1>
+ >::type type;
+ };
+
+}}}
 
 ///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace karma
@@ -69,8 +82,7 @@
     template <typename Elements>
     struct sequence : nary_generator<sequence<Elements> >
     {
-// typedef typename traits::sequence_requires_buffering<Elements>::type
-// requires_buffering;
+ typedef typename traits::sequence_properties<Elements>::type properties;
 
         sequence(Elements const& elements)
           : elements(elements) {}

Modified: trunk/boost/spirit/home/karma/reference.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/reference.hpp (original)
+++ trunk/boost/spirit/home/karma/reference.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -24,6 +24,8 @@
     template <typename Subject>
     struct reference : generator<reference<Subject> >
     {
+ typedef mpl::int_<generator_properties::all_properties> properties;
+
         reference(Subject& subject)
           : ref(subject) {}
 

Modified: trunk/boost/spirit/home/karma/stream/format_manip.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/stream/format_manip.hpp (original)
+++ trunk/boost/spirit/home/karma/stream/format_manip.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -93,10 +93,13 @@
     inline std::basic_ostream<Char, Traits> &
     operator<< (std::basic_ostream<Char, Traits> &os, generator<Derived> const& g)
     {
+ typedef traits::properties<
+ typename result_of::compile<karma::domain, Derived>::type
+ > properties;
         typedef karma::detail::ostream_iterator<Char, Char, Traits> outiter_type;
 
         outiter_type target_sink(os);
- karma::detail::output_iterator<outiter_type> sink(target_sink);
+ karma::detail::output_iterator<outiter_type, properties> sink(target_sink);
 
         if (!g.derived().generate(sink, unused, unused, unused))
         {

Modified: trunk/boost/spirit/home/karma/stream/stream.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/stream/stream.hpp (original)
+++ trunk/boost/spirit/home/karma/stream/stream.hpp 2009-07-21 10:42:55 EDT (Tue, 21 Jul 2009)
@@ -111,16 +111,16 @@
         // this is a special overload to detect if the output iterator has been
         // generated by a format_manip object.
         template <
- typename T, typename Traits, typename Context, typename Delimiter
- , typename Attribute
+ typename T, typename Traits, typename Properties, typename Context
+ , typename Delimiter, typename Attribute
>
         static bool generate(
             karma::detail::output_iterator<
- karma::detail::ostream_iterator<T, Char, Traits>
+ karma::detail::ostream_iterator<T, Char, Traits>, Properties
>& sink, Context&, Delimiter const& d, Attribute const& attr)
         {
             typedef karma::detail::output_iterator<
- karma::detail::ostream_iterator<T, Char, Traits>
+ karma::detail::ostream_iterator<T, Char, Traits>, Properties
> output_iterator;
             typedef karma::detail::iterator_sink<
                 output_iterator, Char, CharEncoding, Tag
@@ -195,15 +195,15 @@
         // this is a special overload to detect if the output iterator has been
         // generated by a format_manip object.
         template <
- typename T1, typename Traits
+ typename T1, typename Traits, typename Properties
           , typename Context, typename Delimiter, typename Attribute>
         bool generate(
             karma::detail::output_iterator<
- karma::detail::ostream_iterator<T1, Char, Traits>
+ karma::detail::ostream_iterator<T1, Char, Traits>, Properties
>& sink, Context&, Delimiter const& d, Attribute const&)
         {
             typedef karma::detail::output_iterator<
- karma::detail::ostream_iterator<T1, Char, Traits>
+ karma::detail::ostream_iterator<T1, Char, Traits>, Properties
> output_iterator;
             typedef karma::detail::iterator_sink<
                 output_iterator, Char, CharEncoding, Tag


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