|
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