Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r58694 - in trunk/boost/spirit/home: karma lex/lexer lex/lexer/lexertl lex/qi qi qi/stream qi/stream/detail support/iterators support/iterators/detail
From: hartmut.kaiser_at_[hidden]
Date: 2010-01-04 18:41:03


Author: hkaiser
Date: 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
New Revision: 58694
URL: http://svn.boost.org/trac/boost/changeset/58694

Log:
Spirit: added concept checks for qi API functions, fixed qi::match functions, added basic_istream_iterator
Added:
   trunk/boost/spirit/home/support/iterators/detail/istream_policy.hpp (contents, props changed)
   trunk/boost/spirit/home/support/iterators/istream_iterator.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/karma/generate.hpp | 1
   trunk/boost/spirit/home/karma/generate_attr.hpp | 6 +-
   trunk/boost/spirit/home/lex/lexer/lexer.hpp | 2
   trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp | 15 ++++++++
   trunk/boost/spirit/home/lex/lexer/token_def.hpp | 2
   trunk/boost/spirit/home/lex/qi/plain_token.hpp | 2
   trunk/boost/spirit/home/qi/parse.hpp | 26 ++++++++++++++
   trunk/boost/spirit/home/qi/parse_attr.hpp | 12 ++++++
   trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp | 13 +++++--
   trunk/boost/spirit/home/qi/stream/match_manip.hpp | 3 +
   trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp | 70 ++++++++++++++++++++++++---------------
   trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp | 5 --
   trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp | 26 +++++++++-----
   trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp | 13 +++++-
   trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp | 27 +++++++++++----
   trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp | 9 +++-
   trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp | 65 ++++++++++++++++++++++++++----------
   trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp | 53 +++++++++++++++--------------
   trunk/boost/spirit/home/support/iterators/multi_pass.hpp | 6 +-
   trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp | 1
   20 files changed, 245 insertions(+), 112 deletions(-)

Modified: trunk/boost/spirit/home/karma/generate.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/generate.hpp (original)
+++ trunk/boost/spirit/home/karma/generate.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -59,6 +59,7 @@
         // If you got an error_invalid_expression error message here,
         // then the expression (expr) is not a valid spirit karma expression.
         BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
+
         return compile<karma::domain>(expr).generate(sink, unused, unused, 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 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -73,7 +73,7 @@
         // wrap user supplied iterator into our own output iterator
         detail::output_iterator<OutputIterator
           , mpl::int_<properties::value> > sink(target_sink);
- return generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
+ return karma::generate(sink, expr, BOOST_PP_ENUM_PARAMS(N, attr));
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -133,7 +133,7 @@
         detail::output_iterator<OutputIterator
           , mpl::int_<properties::value | delimiter_properties::value>
> sink(target_sink);
- return generate_delimited(sink, expr, delimiter, pre_delimit
+ return karma::generate_delimited(sink, expr, delimiter, pre_delimit
           , BOOST_PP_ENUM_PARAMS(N, attr));
     }
 
@@ -157,7 +157,7 @@
         detail::output_iterator<OutputIterator
           , mpl::int_<properties::value | delimiter_properties::value>
> sink(target_sink);
- return generate_delimited(sink, expr, delimiter
+ return karma::generate_delimited(sink, expr, delimiter
           , delimit_flag::dont_predelimit, BOOST_PP_ENUM_PARAMS(N, attr));
     }
 

Modified: trunk/boost/spirit/home/lex/lexer/lexer.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexer.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexer.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -86,7 +86,7 @@
                         boost::detail::iterator_traits<Iterator>::value_type
                     token_type;
 
- token_type &t = *first;
+ token_type const& t = *first;
                     if (token_is_valid(t) && t.state() == first.get_state()) {
                     // any of the token definitions matched
                         spirit::traits::assign_to(t, attr);

Modified: trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -345,6 +345,21 @@
         token_value_type& value() { return value_; }
         token_value_type const& value() const { return value_; }
 
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
+ // workaround for MSVC10 which has problems copying a default
+ // constructed iterator_range
+ token& operator= (token const& rhs)
+ {
+ if (this != &rhs)
+ {
+ this->base_type::operator=(rhs);
+ if (this->id_ != boost::lexer::npos && this->id_ != 0)
+ value_ = rhs.value_;
+ }
+ return *this;
+ }
+#endif
+
     protected:
         token_value_type value_; // token value, by default a pair of iterators
     };

Modified: trunk/boost/spirit/home/lex/lexer/token_def.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/token_def.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/token_def.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -96,7 +96,7 @@
                 // associate this token definition with a lexer instance.
                 BOOST_ASSERT(std::size_t(~0) != token_state_);
 
- token_type &t = *first;
+ token_type const& t = *first;
                 if (token_id_ == t.id() && token_state_ == t.state()) {
                     spirit::traits::assign_to(t, attr);
                     ++first;

Modified: trunk/boost/spirit/home/lex/qi/plain_token.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/qi/plain_token.hpp (original)
+++ trunk/boost/spirit/home/lex/qi/plain_token.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -81,7 +81,7 @@
                 token_type;
                 typedef typename token_type::id_type id_type;
 
- token_type &t = *first;
+ token_type const& t = *first;
                 if (id_type(id) == t.id()) {
                     spirit::traits::assign_to(t, attr);
                     ++first;

Modified: trunk/boost/spirit/home/qi/parse.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/parse.hpp (original)
+++ trunk/boost/spirit/home/qi/parse.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -13,6 +13,7 @@
 #endif
 
 #include <boost/spirit/home/qi/detail/parse.hpp>
+#include <boost/concept_check.hpp>
 
 namespace boost { namespace spirit { namespace qi
 {
@@ -24,6 +25,12 @@
       , Iterator last
       , Expr const& expr)
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         return detail::parse_impl<Expr>::call(first, last, expr);
     }
 
@@ -35,10 +42,17 @@
       , Expr const& expr
       , Attr& attr)
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         // Report invalid expression error as early as possible.
         // If you got an error_invalid_expression error message here,
         // then the expression (expr) is not a valid spirit qi expression.
         BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
+
         return compile<qi::domain>(expr).parse(first, last, unused, unused, attr);
     }
 
@@ -52,6 +66,12 @@
       , Skipper const& skipper
       , BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         return detail::phrase_parse_impl<Expr>::call(
             first, last, expr, skipper, post_skip);
     }
@@ -66,6 +86,12 @@
       , BOOST_SCOPED_ENUM(skip_flag) post_skip
       , Attr& attr)
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         // Report invalid expression error as early as possible.
         // If you got an error_invalid_expression error message here,
         // then either the expression (expr) or skipper is not a valid

Modified: trunk/boost/spirit/home/qi/parse_attr.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/parse_attr.hpp (original)
+++ trunk/boost/spirit/home/qi/parse_attr.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -46,6 +46,12 @@
       , Expr const& expr
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         // Report invalid expression error as early as possible.
         // If you got an error_invalid_expression error message here,
         // then the expression (expr) is not a valid spirit qi expression.
@@ -71,6 +77,12 @@
       , BOOST_SCOPED_ENUM(skip_flag) post_skip
       , BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
     {
+ // Make sure the iterator is at least a forward_iterator. If you got an
+ // compilation error here, then you are using an input_iterator while
+ // calling this function, you need to supply at least a
+ // forward_iterator instead.
+ BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
+
         // Report invalid expression error as early as possible.
         // If you got an error_invalid_expression error message here,
         // then either the expression (expr) or skipper is not a valid

Modified: trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp (original)
+++ trunk/boost/spirit/home/qi/stream/detail/match_manip.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -12,6 +12,7 @@
 #endif
 
 #include <boost/spirit/home/qi/parse.hpp>
+#include <boost/spirit/home/support/iterators/istream_iterator.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/mpl/bool.hpp>
 
@@ -152,7 +153,8 @@
     operator>>(std::basic_istream<Char, Traits> &is,
         match_manip<Expr, CopyExpr, CopyAttr> const& fm)
     {
- typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+ typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
+
         input_iterator f(is);
         input_iterator l;
         if (!qi::parse(f, l, fm.expr))
@@ -170,7 +172,8 @@
     operator>>(std::basic_istream<Char, Traits> &is,
         match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
     {
- typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+ typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
+
         input_iterator f(is);
         input_iterator l;
         if (!qi::parse(f, l, fm.expr, fm.attr))
@@ -188,7 +191,8 @@
     operator>>(std::basic_istream<Char, Traits> &is,
         match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
     {
- typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+ typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
+
         input_iterator f(is);
         input_iterator l;
         if (!qi::phrase_parse(
@@ -209,7 +213,8 @@
         std::basic_istream<Char, Traits> &is,
         match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
     {
- typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+ typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
+
         input_iterator f(is);
         input_iterator l;
         if (!qi::phrase_parse(

Modified: trunk/boost/spirit/home/qi/stream/match_manip.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/stream/match_manip.hpp (original)
+++ trunk/boost/spirit/home/qi/stream/match_manip.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -106,7 +106,8 @@
     inline std::basic_istream<Char, Traits>&
     operator>>(std::basic_istream<Char, Traits>& is, parser<Derived> const& p)
     {
- typedef std::istream_iterator<Char, Char, Traits> input_iterator;
+ typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
+
         input_iterator f(is);
         input_iterator l;
         if (!p.derived().parse(f, l, unused, unused, unused))

Modified: trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/combine_policies.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -111,13 +111,17 @@
         }
 
         // implement input policy functions by forwarding to the Input type
- template <typename MultiPass, typename TokenType>
- inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
- { return Input::advance_input(mp, curtok); }
+ template <typename MultiPass>
+ inline static void advance_input(MultiPass& mp)
+ { Input::advance_input(mp); }
 
- template <typename MultiPass, typename TokenType>
- inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
- { return Input::input_at_eof(mp, curtok); }
+ template <typename TokenType, typename MultiPass>
+ inline static TokenType const& get_input(MultiPass& mp)
+ { return Input::get_input<TokenType>(mp); }
+
+ template <typename MultiPass>
+ inline static bool input_at_eof(MultiPass const& mp)
+ { return Input::input_at_eof(mp); }
 
         template <typename MultiPass, typename TokenType>
         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
@@ -182,13 +186,17 @@
         }
 
         // implement input policy functions by forwarding to the Input type
- template <typename MultiPass, typename TokenType>
- inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
- { return Input::advance_input(mp, curtok); }
+ template <typename MultiPass>
+ inline static void advance_input(MultiPass& mp)
+ { Input::advance_input(mp); }
 
- template <typename MultiPass, typename TokenType>
- inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
- { return Input::input_at_eof(mp, curtok); }
+ template <typename TokenType, typename MultiPass>
+ inline static TokenType const& get_input(MultiPass& mp)
+ { return Input::get_input<TokenType>(mp); }
+
+ template <typename MultiPass>
+ inline static bool input_at_eof(MultiPass const& mp)
+ { return Input::input_at_eof(mp); }
 
         template <typename MultiPass, typename TokenType>
         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
@@ -266,13 +274,17 @@
         }
 
         // implement input policy functions by forwarding to the Input type
- template <typename MultiPass, typename TokenType>
- inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
- { return Input::advance_input(mp, curtok); }
+ template <typename MultiPass>
+ inline static void advance_input(MultiPass& mp)
+ { Input::advance_input(mp); }
 
- template <typename MultiPass, typename TokenType>
- inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
- { return Input::input_at_eof(mp, curtok); }
+ template <typename TokenType, typename MultiPass>
+ inline static TokenType const& get_input(MultiPass& mp)
+ { return Input::get_input<TokenType>(mp); }
+
+ template <typename MultiPass>
+ inline static bool input_at_eof(MultiPass const& mp)
+ { return Input::input_at_eof(mp); }
 
         template <typename MultiPass, typename TokenType>
         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
@@ -359,13 +371,17 @@
         }
 
         // implement input policy functions by forwarding to the Input type
- template <typename MultiPass, typename TokenType>
- inline static TokenType& advance_input(MultiPass& mp, TokenType& curtok)
- { return Input::advance_input(mp, curtok); }
+ template <typename MultiPass>
+ inline static void advance_input(MultiPass& mp)
+ { Input::advance_input(mp); }
 
- template <typename MultiPass, typename TokenType>
- inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
- { return Input::input_at_eof(mp, curtok); }
+ template <typename TokenType, typename MultiPass>
+ inline static TokenType const& get_input(MultiPass& mp)
+ { return Input::get_input<TokenType>(mp); }
+
+ template <typename MultiPass>
+ inline static bool input_at_eof(MultiPass const& mp)
+ { return Input::input_at_eof(mp); }
 
         template <typename MultiPass, typename TokenType>
         inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
@@ -403,7 +419,7 @@
       , typename Storage>
     struct multi_pass_shared : Ownership, Checking, Input, Storage
     {
- explicit multi_pass_shared(T const& input) : Input(input) {}
+ explicit multi_pass_shared(T& input) : Input(input) {}
     };
 
     ///////////////////////////////////////////////////////////////////////////
@@ -438,7 +454,7 @@
               , input_policy, storage_policy> unique_base_type;
 
             unique() {}
- explicit unique(T const& input) : unique_base_type(input) {}
+ explicit unique(T& input) : unique_base_type(input) {}
         };
 
         ///////////////////////////////////////////////////////////////////////
@@ -460,7 +476,7 @@
             typedef multi_pass_shared<T, ownership_policy, checking_policy
               , input_policy, storage_policy> shared_base_type;
 
- explicit shared(T const& input)
+ explicit shared(T& input)
               : shared_base_type(input), inhibit_clear_queue_(false) {}
 
             // This is needed for the correct implementation of expectation

Modified: trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/fixed_size_queue_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -59,10 +59,7 @@
                 {
                     return MultiPass::get_input(mp);
                 }
- else
- {
- return *mp.queuePosition;
- }
+ return *mp.queuePosition;
             }
 
             // This is called when the iterator is incremented. It's a

Modified: trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/functor_input_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -58,21 +58,29 @@
 
         public:
             // get the next token
+ template <typename ValueType, typename MultiPass>
+ static ValueType const& get_input(MultiPass& mp)
+ {
+ value_type& curtok = mp.shared()->curtok;
+ if (!input_is_valid(mp, curtok))
+ curtok = mp.ftor();
+ return curtok;
+ }
+
             template <typename MultiPass>
- static void advance_input(MultiPass& mp, value_type& t)
+ static void advance_input(MultiPass& mp)
             {
                 // if mp.shared is NULL then this instance of the multi_pass
- // represents a end iterator, so no advance functionality is
- // needed
- if (0 != mp.shared())
- t = mp.ftor();
+ // represents a end iterator
+ BOOST_ASSERT(0 != mp.shared());
+ mp.shared()->curtok = mp.ftor();
             }
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const& mp, value_type const& t)
+ static bool input_at_eof(MultiPass const& mp)
             {
- return t == mp.ftor.eof;
+ return mp.shared()->curtok == mp.ftor.eof;
             }
 
             template <typename MultiPass>
@@ -95,9 +103,9 @@
         template <typename Functor>
         struct shared
         {
- explicit shared(Functor const& x) {}
+ explicit shared(Functor const& x) : curtok(0) {}
 
- // no shared data elements
+ result_type curtok;
         };
     };
 

Modified: trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -16,6 +16,7 @@
 {
     namespace input_iterator_is_valid_test_
     {
+ ///////////////////////////////////////////////////////////////////////
         template <typename Token>
         inline bool token_is_valid(Token const& c)
         {
@@ -65,15 +66,21 @@
             template <typename MultiPass>
             static void destroy(MultiPass&) {}
 
+ template <typename ValueType, typename MultiPass>
+ static ValueType const& get_input(MultiPass& mp)
+ {
+ return *mp.shared()->input_;
+ }
+
             template <typename MultiPass>
- static value_type& advance_input(MultiPass& mp, value_type& t)
+ static void advance_input(MultiPass& mp)
             {
- return t = *mp.shared()->input_++;
+ ++mp.shared()->input_;
             }
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const& mp, value_type const&)
+ static bool input_at_eof(MultiPass const& mp)
             {
                 static T const end_iter;
                 return mp.shared()->input_ == end_iter;

Added: trunk/boost/spirit/home/support/iterators/detail/istream_policy.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/detail/istream_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -0,0 +1,106 @@
+// Copyright (c) 2001 Daniel C. Nuffer
+// Copyright (c) 2001-2010 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ISTREAM_POLICY_JAN_04_2010_0130PM)
+#define BOOST_SPIRIT_ISTREAM_POLICY_JAN_04_2010_0130PM
+
+#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
+#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
+
+namespace boost { namespace spirit { namespace iterator_policies
+{
+ ///////////////////////////////////////////////////////////////////////////
+ // class istream
+ // Implementation of the InputPolicy used by multi_pass
+ //
+ // The istream encapsulates an std::basic_istream
+ ///////////////////////////////////////////////////////////////////////////
+ struct istream
+ {
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T>
+ class unique // : public detail::default_input_policy
+ {
+ private:
+ typedef typename T::char_type result_type;
+
+ public:
+ typedef typename T::off_type difference_type;
+ typedef typename T::off_type distance_type;
+ typedef result_type const* pointer;
+ typedef result_type const& reference;
+ typedef result_type value_type;
+
+ protected:
+ unique() {}
+ explicit unique(T&) {}
+
+ void swap(unique&) {}
+
+ public:
+ template <typename MultiPass>
+ static void destroy(MultiPass&) {}
+
+ template <typename ValueType, typename MultiPass>
+ static ValueType const& get_input(MultiPass& mp)
+ {
+ if (!mp.shared()->initialized_)
+ advance_input(mp);
+ return mp.shared()->curtok_;
+ }
+
+ template <typename MultiPass>
+ static void advance_input(MultiPass& mp)
+ {
+ mp.shared()->read_one();
+ }
+
+ // test, whether we reached the end of the underlying stream
+ template <typename MultiPass>
+ static bool input_at_eof(MultiPass const& mp)
+ {
+ return mp.shared()->eof_reached_;
+ }
+
+ template <typename MultiPass>
+ static bool input_is_valid(MultiPass const& mp, value_type const& t)
+ {
+ return mp.shared()->initialized_;
+ }
+
+ // no unique data elements
+ };
+
+ ///////////////////////////////////////////////////////////////////////
+ template <typename T>
+ struct shared
+ {
+ private:
+ typedef typename T::char_type result_type;
+
+ public:
+ explicit shared(T& input)
+ : input_(input), curtok_(-1)
+ , initialized_(false), eof_reached_(false)
+ {}
+
+ void read_one()
+ {
+ if (!(input_ >> curtok_))
+ eof_reached_ = true;
+ initialized_ = true;
+ }
+
+ T& input_;
+ result_type curtok_;
+ bool initialized_;
+ bool eof_reached_;
+ };
+ };
+
+}}}
+
+#endif

Modified: trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -20,12 +20,13 @@
     ///////////////////////////////////////////////////////////////////////////
     struct lex_input
     {
+ typedef int value_type;
+
         ///////////////////////////////////////////////////////////////////////
         template <typename T>
         class unique : public detail::default_input_policy
         {
         public:
- typedef int value_type;
             typedef std::ptrdiff_t difference_type;
             typedef std::ptrdiff_t distance_type;
             typedef int* pointer;
@@ -37,17 +38,29 @@
 
         public:
             template <typename MultiPass>
- static value_type& advance_input(MultiPass& mp, value_type& t)
+ static value_type const& get_input(MultiPass& mp)
+ {
+ value_type& curtok = mp.shared()->curtok;
+ if (-1 == curtok)
+ {
+ extern int yylex();
+ curtok = yylex();
+ }
+ return curtok;
+ }
+
+ template <typename MultiPass>
+ static void advance_input(MultiPass& mp)
             {
                 extern int yylex();
- return t = yylex();
+ mp.shared()->curtok = yylex();
             }
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const&, value_type const& t)
+ static bool input_at_eof(MultiPass const&)
             {
- return 0 == t;
+ return mp.shared()->curtok == 0;
             }
 
             template <typename MultiPass>
@@ -61,9 +74,9 @@
         template <typename T>
         struct shared
         {
- explicit shared(T) {}
+ explicit shared(T) : curtok(-1) {}
 
- // no shared data elements
+ value_type curtok;
         };
     };
 

Modified: trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/multi_pass.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -67,10 +67,13 @@
         void swap(default_input_policy&) {}
 
         template <typename MultiPass, typename TokenType>
- static TokenType& advance_input(MultiPass& mp, TokenType& curtok);
+ static void advance_input(MultiPass& mp);
 
- template <typename MultiPass, typename TokenType>
- static bool input_at_eof(MultiPass const& mp, TokenType& curtok);
+ template <typename TokenType, typename MultiPass>
+ static TokenType const& get_input(MultiPass& mp);
+
+ template <typename MultiPass>
+ static bool input_at_eof(MultiPass const& mp);
 
         template <typename MultiPass, typename TokenType>
         static bool input_is_valid(MultiPass& mp, TokenType& curtok);

Modified: trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -64,8 +64,8 @@
             typedef result_type value_type;
             typedef std::ptrdiff_t difference_type;
             typedef std::ptrdiff_t distance_type;
- typedef result_type* pointer;
- typedef result_type& reference;
+ typedef result_type const* pointer;
+ typedef result_type const& reference;
 
         protected:
             unique() {}
@@ -75,20 +75,27 @@
             void swap(unique&) {}
 
             // get the next token
+ template <typename ValueType, typename MultiPass>
+ static ValueType const& get_input(MultiPass& mp)
+ {
+ value_type& curtok = mp.shared()->curtok;
+ using namespace split_functor_input_is_valid_test_;
+ if (!token_is_valid(curtok))
+ functor_type::get_next(mp, curtok);
+ return curtok;
+ }
+
             template <typename MultiPass>
- static value_type& advance_input(MultiPass& mp, value_type& t)
+ static void advance_input(MultiPass& mp)
             {
- // passing a refernec to the current token instance as a
- // parameter helps generating better code if compared to
- // assigning the result of the functor to this instance
- return functor_type::get_next(mp, t);
+ functor_type::get_next(mp, mp.shared()->curtok);
             }
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const&, value_type const& t)
+ static bool input_at_eof(MultiPass const& mp)
             {
- return t == functor_type::eof;
+ return mp.shared()->curtok == functor_type::eof;
             }
 
             template <typename MultiPass>
@@ -126,25 +133,39 @@
             typedef result_type value_type;
             typedef std::ptrdiff_t difference_type;
             typedef std::ptrdiff_t distance_type;
- typedef result_type* pointer;
- typedef result_type& reference;
+ typedef result_type const* pointer;
+ typedef result_type const& reference;
 
         public:
             // get the next token
+ template <typename ValueType, typename MultiPass>
+ static ValueType const& get_input(MultiPass& mp)
+ {
+ value_type& curtok = mp.shared()->curtok;
+ using namespace split_functor_input_is_valid_test_;
+ if (!token_is_valid(curtok))
+ functor_type::get_next(mp, curtok);
+ return curtok;
+ }
+
+ template <typename MultiPass>
+ static void advance_input(MultiPass& mp)
+ {
+ mp.ftor.get_next(mp, mp.shared()->curtok);
+ }
+
             template <typename MultiPass>
- static value_type& advance_input(MultiPass& mp, value_type& t)
+ static bool input_is_valid(MultiPass const&, value_type const& t)
             {
- // passing a refernec to the current token instance as a
- // parameter helps generating better code if compared to
- // assigning the result of the functor to this instance
- return mp.ftor.get_next(mp, t);
+ using namespace split_functor_input_is_valid_test_;
+ return token_is_valid(t);
             }
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const& mp, value_type const& t)
+ static bool input_at_eof(MultiPass const& mp)
             {
- return t == mp.ftor.eof;
+ return mp.shared()->curtok == mp.ftor.eof;
             }
 
             typename Functor::first_type& get_functor() const
@@ -159,9 +180,15 @@
         template <typename Functor>
         struct shared
         {
- explicit shared(Functor const& x) : ftor(x.second) {}
+ protected:
+ typedef typename Functor::first_type functor_type;
+ typedef typename functor_type::result_type result_type;
+
+ public:
+ explicit shared(Functor const& x) : ftor(x.second), curtok(0) {}
 
             mutable typename Functor::second_type ftor;
+ result_type curtok;
 
         private:
             // silence MSVC warning C4512: assignment operator could not be generated

Modified: trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -35,7 +35,7 @@
             typedef std::vector<Value> queue_type;
 
         protected:
- unique() : queued_position(1) {}
+ unique() : queued_position(0) {}
 
             unique(unique const& x)
               : queued_position(x.queued_position) {}
@@ -53,13 +53,23 @@
             dereference(MultiPass const& mp)
             {
                 queue_type& queue = mp.shared()->queued_elements;
+ typename queue_type::size_type size = queue.size();
 
- BOOST_ASSERT(mp.queued_position > 0 && mp.queued_position <= queue.size());
+ BOOST_ASSERT(mp.queued_position <= size);
 
- Value& v(queue[mp.queued_position-1]);
- if (!MultiPass::input_is_valid(mp, v))
- return MultiPass::advance_input(mp, v);
- return v;
+ if (mp.queued_position == size)
+ {
+ // check if this is the only iterator
+ if (size >= threshold && MultiPass::is_unique(mp))
+ {
+ // free up the memory used by the queue.
+ queue.clear();
+ mp.queued_position = 0;
+ }
+ return MultiPass::get_input<Value>(mp);
+ }
+
+ return queue[mp.queued_position];
             }
 
             // This is called when the iterator is incremented. It's a template
@@ -71,12 +81,12 @@
                 queue_type& queue = mp.shared()->queued_elements;
                 typename queue_type::size_type size = queue.size();
 
- BOOST_ASSERT(mp.queued_position > 0 && mp.queued_position <= size);
+ BOOST_ASSERT(mp.queued_position <= size);
 
- // do not increment iterator as long as the current token is
- // invalid
- if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
- return;
+// // do not increment iterator as long as the current token is
+// // invalid
+// if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
+// return;
 
                 if (mp.queued_position == size)
                 {
@@ -86,21 +96,15 @@
                         // free up the memory used by the queue. we avoid
                         // clearing the queue on every increment, though,
                         // because this would be too time consuming
-
- // erase all but first item in queue
- queue.erase(queue.begin()+1, queue.end());
+ queue.clear();
                         mp.queued_position = 0;
-
- // reuse first entry in the queue and initialize
- // it from the input
                     }
                     else
                     {
- // create a new entry in the queue and initialize
- // it from the input
- queue.push_back(Value(0));
+ queue.push_back(MultiPass::get_input<Value>(mp));
+ ++mp.queued_position;
                     }
- MultiPass::advance_input(mp, queue[mp.queued_position++]);
+ MultiPass::advance_input(mp);
                 }
                 else
                 {
@@ -121,10 +125,8 @@
             template <typename MultiPass>
             static bool is_eof(MultiPass const& mp)
             {
- queue_type& queue = mp.shared()->queued_elements;
- return 0 != mp.queued_position &&
- mp.queued_position == queue.size() &&
- MultiPass::input_at_eof(mp, queue[mp.queued_position-1]);
+ return mp.queued_position == mp.shared()->queued_elements.size()
+ && MultiPass::input_at_eof(mp);
             }
 
             // called by operator==
@@ -155,7 +157,6 @@
             shared()
             {
                 queued_elements.reserve(threshold);
- queued_elements.push_back(Value(0));
             }
 
             typedef std::vector<Value> queue_type;

Added: trunk/boost/spirit/home/support/iterators/istream_iterator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/home/support/iterators/istream_iterator.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -0,0 +1,74 @@
+// Copyright (c) 2001-2010 Hartmut Kaiser
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(BOOST_SPIRIT_ISTREAM_ITERATOR_JAN_03_2010_0522PM)
+#define BOOST_SPIRIT_ISTREAM_ITERATOR_JAN_03_2010_0522PM
+
+#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp>
+#if defined(BOOST_SPIRIT_DEBUG)
+#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp>
+#else
+#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
+#endif
+#include <boost/spirit/home/support/iterators/detail/istream_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp>
+#include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
+#include <boost/spirit/home/support/iterators/multi_pass.hpp>
+
+namespace boost { namespace spirit
+{
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Elem, typename Traits = std::char_traits<Elem> >
+ class basic_istream_iterator :
+ public multi_pass<
+ std::basic_istream<Elem, Traits>
+ , iterator_policies::default_policy<
+ iterator_policies::ref_counted
+#if defined(BOOST_SPIRIT_DEBUG)
+ , iterator_policies::buf_id_check
+#else
+ , iterator_policies::no_check
+#endif
+ , iterator_policies::istream
+ , iterator_policies::split_std_deque>
+ >
+ {
+ private:
+ typedef multi_pass<
+ std::basic_istream<Elem, Traits>
+ , iterator_policies::default_policy<
+ iterator_policies::ref_counted
+#if defined(BOOST_SPIRIT_DEBUG)
+ , iterator_policies::buf_id_check
+#else
+ , iterator_policies::no_check
+#endif
+ , iterator_policies::istream
+ , iterator_policies::split_std_deque>
+ > base_type;
+
+ public:
+ basic_istream_iterator()
+ : base_type() {}
+
+ explicit basic_istream_iterator(std::basic_istream<Elem, Traits>& x)
+ : base_type(x) {}
+
+ basic_istream_iterator(basic_istream_iterator const& x)
+ : base_type(x) {}
+
+#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+ basic_istream_iterator(int) // workaround for a bug in the library
+ : base_type() {} // shipped with gcc 3.1
+#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
+
+ // default generated operators, destructor and assignment operator are ok.
+ };
+
+ typedef basic_istream_iterator<char> istream_iterator;
+
+}}
+
+#endif

Modified: trunk/boost/spirit/home/support/iterators/multi_pass.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/multi_pass.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/multi_pass.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -64,7 +64,7 @@
         // the base class). This is fully intended behavior as some policies
         // rely on the fact that their shared part is initialized before their
         // unique part. Please ignore the warnings, these are harmless.
- explicit multi_pass(T const& input)
+ explicit multi_pass(T& input)
           : member_base(new shared_data_type(input)), policies_base_type(input) {}
 
         multi_pass(multi_pass const& x)
@@ -202,14 +202,14 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename Policies, typename T>
     inline multi_pass<T, Policies>
- make_multi_pass(T const& i)
+ make_multi_pass(T& i)
     {
         return multi_pass<T, Policies>(i);
     }
 
     template <typename T>
     inline multi_pass<T>
- make_default_multi_pass(T const& i)
+ make_default_multi_pass(T& i)
     {
         return multi_pass<T>(i);
     }

Modified: trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp (original)
+++ trunk/boost/spirit/home/support/iterators/multi_pass_fwd.hpp 2010-01-04 18:41:01 EST (Mon, 04 Jan 2010)
@@ -18,6 +18,7 @@
     {
         // input policies
         struct input_iterator;
+ struct istream;
         struct lex_input;
         struct functor_input;
         struct split_functor_input;


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