Initial commit

This commit is contained in:
Bassem Girgis
2018-12-20 17:34:07 -06:00
parent 7a2d899662
commit 81b4b9e273
34743 changed files with 5940233 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <exception> // for std::exception
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class illegal_backtracking
// thrown by buf_id_check CheckingPolicy if an instance of an iterator is
// used after another one has invalidated the queue
///////////////////////////////////////////////////////////////////////////
class illegal_backtracking : public std::exception
{
public:
illegal_backtracking() throw() {}
~illegal_backtracking() throw() {}
char const* what() const throw()
{
return "boost::spirit::multi_pass::illegal_backtracking";
}
};
///////////////////////////////////////////////////////////////////////////////
// class buf_id_check
// Implementation of the CheckingPolicy used by multi_pass
// This policy is most effective when used together with the std_deque
// StoragePolicy.
//
// If used with the fixed_size_queue StoragePolicy, it will not detect
// iterator dereferences that are out of the range of the queue.
///////////////////////////////////////////////////////////////////////////////
struct buf_id_check
{
///////////////////////////////////////////////////////////////////////
struct unique //: detail::default_checking_policy
{
unique() : buf_id(0) {}
unique(unique const& x) : buf_id(x.buf_id) {}
void swap(unique& x)
{
boost::swap(buf_id, x.buf_id);
}
// called to verify that everything is ok.
template <typename MultiPass>
static void docheck(MultiPass const& mp)
{
if (mp.buf_id != mp.shared()->shared_buf_id)
boost::throw_exception(illegal_backtracking());
}
// called from multi_pass::clear_queue, so we can increment the count
template <typename MultiPass>
static void clear_queue(MultiPass& mp)
{
++mp.shared()->shared_buf_id;
++mp.buf_id;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
protected:
unsigned long buf_id;
};
///////////////////////////////////////////////////////////////////////
struct shared
{
shared() : shared_buf_id(0) {}
unsigned long shared_buf_id;
};
};
}}}
#endif

View File

@@ -0,0 +1,128 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM)
#define BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class input_iterator
//
// Implementation of the InputPolicy used by multi_pass, this is different
// from the input_iterator policy only as it is buffering the last input
// character to allow returning it by reference. This is needed for
// wrapping iterators not buffering the last item (such as the
// std::istreambuf_iterator). Unfortunately there is no way to
// automatically figure this out at compile time.
//
// The buffering_input_iterator encapsulates an input iterator of type T
///////////////////////////////////////////////////////////////////////////
struct buffering_input_iterator
{
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique // : public detail::default_input_policy
{
private:
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
public:
typedef
typename boost::detail::iterator_traits<T>::difference_type
difference_type;
typedef
typename boost::detail::iterator_traits<T>::difference_type
distance_type;
typedef
typename boost::detail::iterator_traits<T>::pointer
pointer;
typedef result_type& reference;
typedef result_type value_type;
protected:
unique() {}
explicit unique(T x) {}
void swap(unique&) {}
public:
template <typename MultiPass>
static void destroy(MultiPass&) {}
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
return mp.shared()->get_input();
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
BOOST_ASSERT(0 != mp.shared());
mp.shared()->advance_input();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
static T const end_iter;
return mp.shared()->input_ == end_iter;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, value_type const& t)
{
return mp.shared()->input_is_valid_;
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
explicit shared(T const& input)
: input_(input), curtok_(0), input_is_valid_(false) {}
void advance_input()
{
++input_;
input_is_valid_ = false;
}
result_type& get_input()
{
if (!input_is_valid_) {
curtok_ = *input_;
input_is_valid_ = true;
}
return curtok_;
}
T input_;
result_type curtok_;
bool input_is_valid_;
};
};
}}}
#endif

View File

@@ -0,0 +1,520 @@
// Copyright (c) 2001-2012 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_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
#define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
#include <boost/config.hpp>
#include <boost/type_traits/is_empty.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// The purpose of the multi_pass_unique template is to eliminate
// empty policy classes (policies not containing any data items) from the
// multiple inheritance chain. This is necessary since some compilers
// fail to apply the empty base optimization if multiple inheritance is
// involved.
// Additionally this can be used to combine separate policies into one
// single multi_pass_policy as required by the multi_pass template
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// select the correct derived classes based on if a policy is empty
template <typename T
, typename Ownership, typename Checking, typename Input, typename Storage
, bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
, bool CheckingIsEmpty = boost::is_empty<Checking>::value
, bool InputIsEmpty = boost::is_empty<Input>::value>
struct multi_pass_unique;
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, false, false>
: Ownership, Checking, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Checking::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, false, true>
: Ownership, Checking, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Checking::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(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)
{ return Input::input_is_valid(mp, curtok); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, true, false>
: Ownership, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, false, true, true>
: Ownership, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Ownership::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Ownership::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(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)
{ return Input::input_is_valid(mp, curtok); }
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, false, false>
: Checking, Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Checking::swap(x);
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, false, true>
: Checking, Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Checking::destroy(mp);
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Checking::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(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)
{ return Input::input_is_valid(mp, curtok); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, true, false>
: Input, Storage
{
multi_pass_unique() {}
multi_pass_unique(T& x) : Input(x) {}
multi_pass_unique(T const& x) : Input(x) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Input::swap(x);
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Ownership, typename Checking
, typename Input, typename Storage>
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
, true, true, true>
: Storage
{
multi_pass_unique() {}
multi_pass_unique(T const&) {}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
Input::destroy(mp);
Storage::destroy(mp);
}
void swap(multi_pass_unique& x)
{
this->Storage::swap(x);
}
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{
Checking::clear_queue(mp);
Storage::clear_queue(mp);
}
// implement input policy functions by forwarding to the Input type
template <typename MultiPass>
inline static void advance_input(MultiPass& mp)
{ Input::advance_input(mp); }
template <typename MultiPass>
inline static typename MultiPass::reference get_input(MultiPass& mp)
{ return Input::get_input(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)
{ return Input::input_is_valid(mp, curtok); }
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void docheck(MultiPass const& mp)
{ Checking::docheck(mp); }
// ownership policy functions are forwarded to the Ownership type
template <typename MultiPass>
inline static void clone(MultiPass& mp)
{ Ownership::clone(mp); }
template <typename MultiPass>
inline static bool release(MultiPass& mp)
{ return Ownership::release(mp); }
template <typename MultiPass>
inline static bool is_unique(MultiPass const& mp)
{ return Ownership::is_unique(mp); }
};
///////////////////////////////////////////////////////////////////////////
// the multi_pass_shared structure is used to combine the shared data items
// of all policies into one single structure
///////////////////////////////////////////////////////////////////////////
template<typename T, typename Ownership, typename Checking, typename Input
, typename Storage>
struct multi_pass_shared : Ownership, Checking, Input, Storage
{
explicit multi_pass_shared(T& input) : Input(input) {}
explicit multi_pass_shared(T const& input) : Input(input) {}
};
///////////////////////////////////////////////////////////////////////////
// This is a default implementation of a policy class as required by the
// multi_pass template, combining 4 separate policies into one. Any other
// multi_pass policy class needs to follow the scheme as shown below.
template<typename Ownership, typename Checking, typename Input
, typename Storage>
struct default_policy
{
typedef Ownership ownership_policy;
typedef Checking checking_policy;
typedef Input input_policy;
typedef Storage storage_policy;
///////////////////////////////////////////////////////////////////////
template <typename T>
struct unique : multi_pass_unique<T
, typename Ownership::unique, typename Checking::unique
, typename Input::BOOST_NESTED_TEMPLATE unique<T>
, typename Storage::BOOST_NESTED_TEMPLATE unique<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
{
typedef typename Ownership::unique ownership_policy;
typedef typename Checking::unique checking_policy;
typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
input_policy;
typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
typename input_policy::value_type> storage_policy;
typedef multi_pass_unique<T, ownership_policy, checking_policy
, input_policy, storage_policy> unique_base_type;
unique() {}
explicit unique(T& input) : unique_base_type(input) {}
explicit unique(T const& input) : unique_base_type(input) {}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared : multi_pass_shared<T
, typename Ownership::shared, typename Checking::shared
, typename Input::BOOST_NESTED_TEMPLATE shared<T>
, typename Storage::BOOST_NESTED_TEMPLATE shared<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
{
typedef typename Ownership::shared ownership_policy;
typedef typename Checking::shared checking_policy;
typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
input_policy;
typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
storage_policy;
typedef multi_pass_shared<T, ownership_policy, checking_policy
, input_policy, storage_policy> shared_base_type;
explicit shared(T& input)
: shared_base_type(input), inhibit_clear_queue_(false) {}
explicit shared(T const& input)
: shared_base_type(input), inhibit_clear_queue_(false) {}
// This is needed for the correct implementation of expectation
// points. Normally expectation points flush any multi_pass
// iterator they may act on, but if the corresponding error handler
// is of type 'retry' no flushing of the internal buffers should be
// executed (even if explicitly requested).
bool inhibit_clear_queue_;
};
};
}}}
#endif

View File

@@ -0,0 +1,62 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM
#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 first_owner
// Implementation of an OwnershipPolicy used by multi_pass
// This ownership policy dictates that the first iterator created will
// determine the lifespan of the shared components. This works well for
// spirit, since no dynamic allocation of iterators is done, and all
// copies are make on the stack.
//
// There is a caveat about using this policy together with the std_deque
// StoragePolicy. Since first_owner always returns false from unique(),
// std_deque will only release the queued data if clear_queue() is called.
///////////////////////////////////////////////////////////////////////////
struct first_owner
{
///////////////////////////////////////////////////////////////////////
struct unique : detail::default_ownership_policy
{
unique() : first(true) {}
unique(unique const&) : first(false) {}
// return true to indicate deletion of resources
template <typename MultiPass>
static bool release(MultiPass& mp)
{
return mp.first;
}
// use swap from default policy
// if we're the first, we still remain the first, even if assigned
// to, so don't swap first. swap is only called from operator=
template <typename MultiPass>
static bool is_unique(MultiPass const&)
{
return false; // no way to know, so always return false
}
protected:
bool first;
};
////////////////////////////////////////////////////////////////////////
struct shared {}; // no shared data
};
}}}
#endif

View File

@@ -0,0 +1,392 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM)
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM
#include <cstdlib>
#include <iterator>
#include <cstddef>
#include <boost/config.hpp>
#include <boost/assert.hpp> // for BOOST_ASSERT
#include <boost/iterator_adaptors.hpp>
///////////////////////////////////////////////////////////////////////////////
// Make sure we're using a decent version of the Boost.IteratorAdaptors lib
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!"
#endif
///////////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_ASSERT_FSQ_SIZE \
BOOST_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1)) \
/**/
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Queue, typename T, typename Pointer>
class fsq_iterator
: public boost::iterator_facade<
fsq_iterator<Queue, T, Pointer>, T,
std::random_access_iterator_tag
>
{
public:
typedef typename Queue::position_type position_type;
typedef boost::iterator_facade<
fsq_iterator<Queue, T, Pointer>, T,
std::random_access_iterator_tag
> base_type;
fsq_iterator() {}
fsq_iterator(position_type const &p_) : p(p_) {}
position_type &get_position() { return p; }
position_type const &get_position() const { return p; }
private:
friend class boost::iterator_core_access;
typename base_type::reference dereference() const
{
return p.self->m_queue[p.pos];
}
void increment()
{
++p.pos;
if (p.pos == Queue::MAX_SIZE+1)
p.pos = 0;
}
void decrement()
{
if (p.pos == 0)
p.pos = Queue::MAX_SIZE;
else
--p.pos;
}
bool is_eof() const
{
return p.self == 0 || p.pos == p.self->size();
}
template <typename Q, typename T_, typename P>
bool equal(fsq_iterator<Q, T_, P> const &x) const
{
if (is_eof())
return x.is_eof();
if (x.is_eof())
return false;
position_type const &rhs_pos = x.get_position();
return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
}
template <typename Q, typename T_, typename P>
typename base_type::difference_type distance_to(
fsq_iterator<Q, T_, P> const &x) const
{
typedef typename base_type::difference_type difference_type;
position_type const &p2 = x.get_position();
std::size_t pos1 = p.pos;
std::size_t pos2 = p2.pos;
// Undefined behavior if the iterators come from different
// containers
BOOST_ASSERT(p.self == p2.self);
if (pos1 < p.self->m_head)
pos1 += Queue::MAX_SIZE;
if (pos2 < p2.self->m_head)
pos2 += Queue::MAX_SIZE;
if (pos2 > pos1)
return difference_type(pos2 - pos1);
else
return -difference_type(pos1 - pos2);
}
void advance(typename base_type::difference_type n)
{
// Notice that we don't care values of n that can
// wrap around more than one time, since it would
// be undefined behavior anyway (going outside
// the begin/end range). Negative wrapping is a bit
// cumbersome because we don't want to case p.pos
// to signed.
if (n < 0)
{
n = -n;
if (p.pos < (std::size_t)n)
p.pos = Queue::MAX_SIZE+1 - (n - p.pos);
else
p.pos -= n;
}
else
{
p.pos += n;
if (p.pos >= Queue::MAX_SIZE+1)
p.pos -= Queue::MAX_SIZE+1;
}
}
private:
position_type p;
};
///////////////////////////////////////////////////////////////////////////
template <typename T, std::size_t N>
class fixed_size_queue
{
private:
struct position
{
fixed_size_queue* self;
std::size_t pos;
position() : self(0), pos(0) {}
// The const_cast here is just to avoid to have two different
// position structures for the const and non-const case.
// The const semantic is guaranteed by the iterator itself
position(const fixed_size_queue* s, std::size_t p)
: self(const_cast<fixed_size_queue*>(s)), pos(p)
{}
bool is_initialized() const { return self != 0; }
void set_queue(fixed_size_queue* q) { self = q; }
};
public:
// Declare the iterators
typedef fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator;
typedef
fsq_iterator<fixed_size_queue<T, N>, T const, T const*>
const_iterator;
typedef position position_type;
friend class fsq_iterator<fixed_size_queue<T, N>, T, T*>;
friend class fsq_iterator<fixed_size_queue<T, N>, T const, T const*>;
fixed_size_queue();
fixed_size_queue(const fixed_size_queue& x);
fixed_size_queue& operator=(const fixed_size_queue& x);
~fixed_size_queue();
void push_back(const T& e);
void push_front(const T& e);
void serve(T& e);
void pop_front();
bool empty() const
{
return m_size == 0;
}
bool full() const
{
return m_size == N;
}
iterator begin()
{
return iterator(position(this, m_head));
}
const_iterator begin() const
{
return const_iterator(position(this, m_head));
}
iterator end()
{
return iterator(position(0, m_tail));
}
const_iterator end() const
{
return const_iterator(position(0, m_tail));
}
std::size_t size() const
{
return m_size;
}
T& front()
{
return m_queue[m_head];
}
const T& front() const
{
return m_queue[m_head];
}
private:
// Redefine the template parameters to avoid using partial template
// specialization on the iterator policy to extract N.
BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N);
std::size_t m_head;
std::size_t m_tail;
std::size_t m_size;
T m_queue[N+1];
};
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::fixed_size_queue()
: m_head(0)
, m_tail(0)
, m_size(0)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x)
: m_head(x.m_head)
, m_tail(x.m_tail)
, m_size(x.m_size)
{
copy(x.begin(), x.end(), begin());
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline fixed_size_queue<T, N>&
fixed_size_queue<T, N>::operator=(const fixed_size_queue& x)
{
if (this != &x)
{
m_head = x.m_head;
m_tail = x.m_tail;
m_size = x.m_size;
copy(x.begin(), x.end(), begin());
}
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
return *this;
}
template <typename T, std::size_t N>
inline
fixed_size_queue<T, N>::~fixed_size_queue()
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::push_back(const T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
BOOST_ASSERT(!full());
m_queue[m_tail] = e;
++m_size;
++m_tail;
if (m_tail == N+1)
m_tail = 0;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::push_front(const T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
BOOST_ASSERT(!full());
if (m_head == 0)
m_head = N;
else
--m_head;
m_queue[m_head] = e;
++m_size;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::serve(T& e)
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
e = m_queue[m_head];
pop_front();
}
template <typename T, std::size_t N>
inline void
fixed_size_queue<T, N>::pop_front()
{
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
++m_head;
if (m_head == N+1)
m_head = 0;
--m_size;
BOOST_ASSERT(m_size <= N+1);
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
BOOST_ASSERT(m_head <= N+1);
BOOST_ASSERT(m_tail <= N+1);
}
}}}
#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE
#endif

View File

@@ -0,0 +1,128 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM)
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp>
#include <boost/assert.hpp>
#include <cstdlib>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class fixed_size_queue
// Implementation of the StoragePolicy used by multi_pass
// fixed_size_queue keeps a circular buffer (implemented by
// boost::spirit::fixed_size_queue class) that is size N+1 and stores N
// elements.
//
// It is up to the user to ensure that there is enough look ahead for
// their grammar. Currently there is no way to tell if an iterator is
// pointing to forgotten data. The leading iterator will put an item in
// the queue and remove one when it is incremented. No dynamic allocation
// is done, except on creation of the queue (fixed_size_queue constructor).
///////////////////////////////////////////////////////////////////////////
template <std::size_t N>
struct fixed_size_queue
{
///////////////////////////////////////////////////////////////////////
template <typename Value>
class unique : public detail::default_storage_policy
{
private:
typedef detail::fixed_size_queue<Value, N> queue_type;
protected:
unique() {}
unique(unique const& x)
: queued_position(x.queued_position) {}
void swap(unique& x)
{
boost::swap(queued_position, x.queued_position);
}
// This is called when the iterator is dereferenced. It's a
// template method so we can recover the type of the multi_pass
// iterator and access the m_input data member.
template <typename MultiPass>
static typename MultiPass::reference
dereference(MultiPass const& mp)
{
if (!mp.queued_position.get_position().is_initialized())
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
if (mp.queued_position == mp.shared()->queued_elements.end())
return MultiPass::get_input(mp);
return *mp.queued_position;
}
// This is called when the iterator is incremented. It's a
// template method so we can recover the type of the multi_pass
// iterator and access the m_input data member.
template <typename MultiPass>
static void increment(MultiPass& mp)
{
if (!mp.queued_position.get_position().is_initialized())
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
if (mp.queued_position == mp.shared()->queued_elements.end())
{
// don't let the queue get larger than N
if (mp.shared()->queued_elements.size() >= N)
mp.shared()->queued_elements.pop_front();
mp.shared()->queued_elements.push_back(
MultiPass::get_input(mp));
MultiPass::advance_input(mp);
}
++mp.queued_position;
}
// clear_queue is a no-op
// called to determine whether the iterator is an eof iterator
template <typename MultiPass>
static bool is_eof(MultiPass const& mp)
{
return mp.queued_position == mp.shared()->queued_elements.end() &&
MultiPass::input_at_eof(mp);
}
// called by operator==
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position == x.queued_position;
}
// called by operator<
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position < x.queued_position;
}
protected:
mutable typename queue_type::iterator queued_position;
};
///////////////////////////////////////////////////////////////////////
template <typename Value>
struct shared
{
typedef detail::fixed_size_queue<Value, N> queue_type;
queue_type queued_elements;
};
};
}}}
#endif

View File

@@ -0,0 +1,114 @@
// Copyright (c) 2001-2011 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M)
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace is_valid_test_
{
template <typename Token>
inline bool token_is_valid(Token const&)
{
return true;
}
}
///////////////////////////////////////////////////////////////////////////
// class functor_input
// Implementation of the InputPolicy used by multi_pass
// functor_input gets tokens from a functor
//
// Note: the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined
// to represent EOF that is called eof.
//
///////////////////////////////////////////////////////////////////////////
struct functor_input
{
///////////////////////////////////////////////////////////////////////
template <typename Functor>
class unique : public detail::default_input_policy
{
private:
typedef typename Functor::result_type result_type;
protected:
unique() {}
explicit unique(Functor const& x) : ftor(x) {}
void swap(unique& x)
{
boost::swap(ftor, x.ftor);
}
public:
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;
public:
// get the next token
template <typename MultiPass>
static typename MultiPass::reference 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)
{
// if mp.shared is NULL then this instance of the multi_pass
// 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)
{
return mp.shared()->curtok == mp.ftor.eof;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
using namespace is_valid_test_;
return token_is_valid(t);
}
Functor& get_functor() const
{
return ftor;
}
protected:
mutable Functor ftor;
};
///////////////////////////////////////////////////////////////////////
template <typename Functor>
struct shared
{
explicit shared(Functor const&) : curtok(0) {}
typename Functor::result_type curtok;
};
};
}}}
#endif

View File

@@ -0,0 +1,111 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM)
#define BOOST_SPIRIT_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace input_iterator_is_valid_test_
{
///////////////////////////////////////////////////////////////////////
template <typename Token>
inline bool token_is_valid(Token const& c)
{
return c ? true : false;
}
}
///////////////////////////////////////////////////////////////////////////
// class input_iterator
// Implementation of the InputPolicy used by multi_pass
//
// The input_iterator encapsulates an input iterator of type T
///////////////////////////////////////////////////////////////////////////
struct input_iterator
{
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique // : public detail::default_input_policy
{
private:
typedef
typename boost::detail::iterator_traits<T>::value_type
result_type;
public:
typedef
typename boost::detail::iterator_traits<T>::difference_type
difference_type;
typedef
typename boost::detail::iterator_traits<T>::difference_type
distance_type;
typedef
typename boost::detail::iterator_traits<T>::pointer
pointer;
typedef
typename boost::detail::iterator_traits<T>::reference
reference;
typedef result_type value_type;
protected:
unique() {}
explicit unique(T x) {}
void swap(unique&) {}
public:
template <typename MultiPass>
static void destroy(MultiPass&) {}
template <typename MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
return *mp.shared()->input_;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
++mp.shared()->input_;
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
static T const end_iter;
return mp.shared()->input_ == end_iter;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, value_type const& t)
{
using namespace input_iterator_is_valid_test_;
return token_is_valid(t);
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
explicit shared(T const& input) : input_(input) {}
T input_;
};
};
}}}
#endif

View File

@@ -0,0 +1,124 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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 MultiPass>
static typename MultiPass::reference get_input(MultiPass& mp)
{
if (!mp.shared()->initialized_)
mp.shared()->read_one();
return mp.shared()->curtok_;
}
template <typename MultiPass>
static void advance_input(MultiPass& mp)
{
// We invalidate the currently cached input character to avoid
// reading more input from the underlying iterator than
// required. Without this we would always read ahead one
// character, even if this character never gets consumed by the
// client.
mp.shared()->peek_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&)
{
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)
{
peek_one(); // istreams may be at eof right in the beginning
}
void read_one()
{
if (!(input_ >> curtok_)) {
initialized_ = false;
eof_reached_ = true;
}
else {
initialized_ = true;
}
}
void peek_one()
{
input_.peek(); // try for eof
initialized_ = false;
eof_reached_ = input_.eof();
}
T& input_;
result_type curtok_;
bool initialized_;
bool eof_reached_;
};
};
}}}
#endif

View File

@@ -0,0 +1,86 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM)
#define BOOST_SPIRIT_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM
#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 lex_input
// Implementation of the InputPolicy used by multi_pass
//
// The lex_input class gets tokens (integers) from yylex()
///////////////////////////////////////////////////////////////////////////
struct lex_input
{
typedef int value_type;
///////////////////////////////////////////////////////////////////////
template <typename T>
class unique : public detail::default_input_policy
{
public:
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef int* pointer;
typedef int& reference;
protected:
unique() {}
explicit unique(T) {}
public:
template <typename MultiPass>
static typename MultiPass::reference 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();
mp.shared()->curtok = yylex();
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const& mp)
{
return mp.shared()->curtok == 0;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
return -1 != t;
}
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
explicit shared(T) : curtok(-1) {}
value_type curtok;
};
};
}}}
#endif

View File

@@ -0,0 +1,109 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM)
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM
#include <boost/config.hpp>
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/iterator.hpp>
#include <boost/mpl/bool.hpp>
#include <iterator>
#include <algorithm>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// Default implementations of the different policies to be used with a
// multi_pass iterator
///////////////////////////////////////////////////////////////////////////
struct default_input_policy
{
default_input_policy() {}
template <typename Functor>
default_input_policy(Functor const&) {}
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_input_policy&) {}
template <typename MultiPass, typename TokenType>
static void advance_input(MultiPass& mp);
template <typename MultiPass>
static typename MultiPass::reference 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);
};
struct default_ownership_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_ownership_policy&) {}
template <typename MultiPass>
static void clone(MultiPass&) {}
template <typename MultiPass>
static bool release(MultiPass& mp);
template <typename MultiPass>
static bool is_unique(MultiPass const& mp);
};
struct default_storage_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_storage_policy&) {}
template <typename MultiPass>
static typename MultiPass::reference dereference(MultiPass const& mp);
template <typename MultiPass>
static void increment(MultiPass&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
template <typename MultiPass>
static bool is_eof(MultiPass const& mp);
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x);
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x);
};
struct default_checking_policy
{
template <typename MultiPass>
static void destroy(MultiPass&) {}
void swap(default_checking_policy&) {}
template <typename MultiPass>
static void docheck(MultiPass const&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
};
}}}
#endif

View File

@@ -0,0 +1,31 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM)
#define BOOST_SPIRIT_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM
#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 no_check
// Implementation of the CheckingPolicy used by multi_pass
// It does not do anything :-)
///////////////////////////////////////////////////////////////////////////
struct no_check
{
///////////////////////////////////////////////////////////////////////
struct unique : public detail::default_checking_policy {};
///////////////////////////////////////////////////////////////////////
struct shared {};
};
}}}
#endif

View File

@@ -0,0 +1,79 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM)
#define BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#if defined(BOOST_HAS_THREADS)
#include <boost/detail/atomic_count.hpp>
#endif
#include <cstdlib>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class ref_counted
// Implementation of an OwnershipPolicy used by multi_pass.
//
// Implementation modified from RefCounted class from the Loki library by
// Andrei Alexandrescu.
///////////////////////////////////////////////////////////////////////////
struct ref_counted
{
///////////////////////////////////////////////////////////////////////
struct unique // : detail::default_ownership_policy
{
void swap(unique&) {}
// clone is called when a copy of the iterator is made, so
// increment the ref-count.
template <typename MultiPass>
static void clone(MultiPass& mp)
{
if (0 != mp.shared())
++mp.shared()->count;
}
// called when a copy is deleted. Decrement the ref-count. Return
// value of true indicates that the last copy has been released.
template <typename MultiPass>
static bool release(MultiPass& mp)
{
return 0 != mp.shared() && 0 == --mp.shared()->count;
}
// returns true if there is only one iterator in existence.
// std_deque StoragePolicy will free it's buffered data if this
// returns true.
template <typename MultiPass>
static bool is_unique(MultiPass const& mp)
{
return 0 == mp.shared() || 1 == mp.shared()->count;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
};
////////////////////////////////////////////////////////////////////////
struct shared
{
shared() : count(1) {}
#if defined(BOOST_HAS_THREADS)
boost::detail::atomic_count count;
#else
std::size_t count;
#endif
};
};
}}}
#endif

View File

@@ -0,0 +1,201 @@
// Copyright (c) 2001-2011 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM)
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
#include <boost/type_traits/is_empty.hpp>
namespace boost { namespace spirit { namespace iterator_policies
{
namespace split_functor_input_is_valid_test_
{
template <typename Token>
inline bool token_is_valid(Token const&)
{
return true;
}
}
///////////////////////////////////////////////////////////////////////////
// class split_functor_input
// Implementation of the InputPolicy used by multi_pass
// split_functor_input gets tokens from a functor
//
// This policy should be used when the functor holds two parts of data: a
// unique part (unique for each instance of the iterator) and a shared
// part (to be shared between the different copies of the same iterator).
// Using this policy allows to merge the shared part of the functor with
// the shared part of the iterator data, saving one pointer and one
// allocation per iterator instance.
//
// The Functor template parameter of this policy is expected to be a
// std::pair<unique, shared>, where 'unique' and 'shared' represent the
// respective parts of the functor itself.
//
// Note: the unique part of the functor must have a typedef for result_type
// It also must have a static variable of type result_type defined
// to represent EOF that is called eof.
//
///////////////////////////////////////////////////////////////////////////
struct split_functor_input
{
///////////////////////////////////////////////////////////////////////
template <typename Functor
, bool FunctorIsEmpty = is_empty<typename Functor::first_type>::value>
class unique;
// the unique part of the functor is empty, do not include the functor
// as a member at all to avoid unnecessary padding bytes to be included
// into the generated structure
template <typename Functor>
class unique<Functor, true> // : public detail::default_input_policy
{
protected:
typedef typename Functor::first_type functor_type;
typedef typename functor_type::result_type result_type;
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef result_type const* pointer;
typedef result_type const& reference;
protected:
unique() {}
explicit unique(Functor const&) {}
public:
void swap(unique&) {}
// get the next token
template <typename MultiPass>
static typename MultiPass::reference 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)
{
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& mp)
{
return mp.shared()->curtok == functor_type::eof;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const&, value_type const& t)
{
using namespace split_functor_input_is_valid_test_;
return token_is_valid(t);
}
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
functor_type::destroy(mp);
}
};
// the unique part of the functor is non-empty
template <typename Functor>
class unique<Functor, false> : public unique<Functor, true>
{
protected:
typedef typename Functor::first_type functor_type;
typedef typename functor_type::result_type result_type;
protected:
unique() {}
explicit unique(Functor const& x) : ftor(x.first) {}
void swap(unique& x)
{
boost::swap(ftor, x.ftor);
}
public:
typedef result_type value_type;
typedef std::ptrdiff_t difference_type;
typedef std::ptrdiff_t distance_type;
typedef result_type const* pointer;
typedef result_type const& reference;
public:
// get the next token
template <typename MultiPass>
static typename MultiPass::reference 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 bool input_is_valid(MultiPass const&, value_type const& 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)
{
return mp.shared()->curtok == mp.ftor.eof;
}
typename Functor::first_type& get_functor() const
{
return ftor;
}
mutable functor_type ftor;
};
///////////////////////////////////////////////////////////////////////
template <typename Functor>
struct shared
{
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
shared& operator= (shared const&);
};
};
}}}
#endif

View File

@@ -0,0 +1,170 @@
// Copyright (c) 2001 Daniel C. Nuffer
// Copyright (c) 2001-2011 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_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/assert.hpp>
#include <vector>
namespace boost { namespace spirit { namespace iterator_policies
{
///////////////////////////////////////////////////////////////////////////
// class split_std_deque
//
// Implementation of the StoragePolicy used by multi_pass
// This stores all data in a std::vector (despite its name), and keeps an
// offset to the current position. It stores all the data unless there is
// only one iterator using the queue.
//
///////////////////////////////////////////////////////////////////////////
struct split_std_deque
{
enum { threshold = 16 };
///////////////////////////////////////////////////////////////////////
template <typename Value>
class unique //: public detail::default_storage_policy
{
private:
typedef std::vector<Value> queue_type;
protected:
unique() : queued_position(0) {}
unique(unique const& x)
: queued_position(x.queued_position) {}
void swap(unique& x)
{
boost::swap(queued_position, x.queued_position);
}
// This is called when the iterator is dereferenced. It's a
// template method so we can recover the type of the multi_pass
// iterator and call advance_input and input_is_valid.
template <typename MultiPass>
static typename MultiPass::reference
dereference(MultiPass const& mp)
{
queue_type& queue = mp.shared()->queued_elements;
typename queue_type::size_type size = queue.size();
BOOST_ASSERT(mp.queued_position <= size);
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(mp);
}
return queue[mp.queued_position];
}
// This is called when the iterator is incremented. It's a template
// method so we can recover the type of the multi_pass iterator
// and call is_unique and advance_input.
template <typename MultiPass>
static void increment(MultiPass& mp)
{
queue_type& queue = mp.shared()->queued_elements;
typename queue_type::size_type size = queue.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;
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. we avoid
// clearing the queue on every increment, though,
// because this would be too time consuming
queue.clear();
mp.queued_position = 0;
}
else
{
queue.push_back(MultiPass::get_input(mp));
++mp.queued_position;
}
MultiPass::advance_input(mp);
}
else
{
++mp.queued_position;
}
}
// called to forcibly clear the queue
template <typename MultiPass>
static void clear_queue(MultiPass& mp)
{
mp.shared()->queued_elements.clear();
mp.queued_position = 0;
}
// called to determine whether the iterator is an eof iterator
template <typename MultiPass>
static bool is_eof(MultiPass const& mp)
{
return mp.queued_position == mp.shared()->queued_elements.size()
&& MultiPass::input_at_eof(mp);
}
// called by operator==
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position == x.queued_position;
}
// called by operator<
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x)
{
return mp.queued_position < x.queued_position;
}
template <typename MultiPass>
static void destroy(MultiPass&) {}
protected:
mutable typename queue_type::size_type queued_position;
};
///////////////////////////////////////////////////////////////////////
template <typename Value>
struct shared
{
shared()
{
queued_elements.reserve(threshold);
}
typedef std::vector<Value> queue_type;
queue_type queued_elements;
};
}; // split_std_deque
}}}
#endif

View File

@@ -0,0 +1,80 @@
// Copyright (c) 2001-2011 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)
basic_istream_iterator operator= (base_type const& rhs)
{
this->base_type::operator=(rhs);
return *this;
}
// default generated operators, destructor and assignment operator are ok.
};
typedef basic_istream_iterator<char> istream_iterator;
}}
#endif

View File

@@ -0,0 +1,180 @@
/*==============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2010 Bryce Lelbach
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_SUPPORT_LINE_POS_ITERATOR)
#define BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit
{
//[line_pos_iterator_class
/*`The `line_pos_iterator` is a lightweight line position iterator.
This iterator adapter only stores the current line number, nothing else.
Unlike __classic__'s `position_iterator`, it does not store the
column number and does not need an end iterator. The current column can
be computed, if needed. */
//`[heading Class Reference]
template <class Iterator>
class line_pos_iterator : public boost::iterator_adaptor<
line_pos_iterator<Iterator> // Derived
, Iterator // Base
, boost::use_default // Value
, boost::forward_traversal_tag // CategoryOrTraversal
> {
public:
line_pos_iterator();
explicit line_pos_iterator(Iterator);
std::size_t position() const;
private:
friend class boost::iterator_core_access;
void increment();
std::size_t line; // The line position.
typename std::iterator_traits<Iterator>::value_type prev;
};
//]
template <class Iterator>
line_pos_iterator<Iterator>::line_pos_iterator() :
line_pos_iterator::iterator_adaptor_(), line(1), prev(0) { }
template <class Iterator>
line_pos_iterator<Iterator>::line_pos_iterator(Iterator base) :
line_pos_iterator::iterator_adaptor_(base), line(1), prev(0) { }
template <class Iterator>
std::size_t line_pos_iterator<Iterator>::position() const
{
return line;
}
template<class Iterator>
void line_pos_iterator<Iterator>::increment()
{
typename std::iterator_traits<Iterator>::reference
ref = *(this->base());
switch (ref) {
case '\r':
if (prev != '\n')
++line;
break;
case '\n':
if (prev != '\r')
++line;
break;
default:
break;
}
prev = ref;
++this->base_reference();
}
//[line_pos_iterator_utilities
//`[heading get_line]
template <class Iterator>
inline std::size_t get_line(Iterator);
/*`Get the line position. Returns -1 if Iterator is not a
`line_pos_iterator`. */
//`[heading get_line_start]
template <class Iterator>
inline Iterator get_line_start(Iterator lower_bound, Iterator current);
/*`Get an iterator to the beginning of the line. Applicable to any
iterator. */
//`[heading get_current_line]
template <class Iterator>
inline iterator_range<Iterator>
get_current_line(Iterator lower_bound, Iterator current,
Iterator upper_bound);
/*`Get an `iterator_range` containing the current line. Applicable to any
iterator. */
//`[heading get_column]
template <class Iterator>
inline std::size_t get_column(Iterator lower_bound, Iterator current,
std::size_t tabs = 4);
/*`Get the current column. Applicable to any iterator. */
//]
template <class Iterator>
inline std::size_t get_line(Iterator)
{
return -1;
}
template <class Iterator>
inline std::size_t get_line(line_pos_iterator<Iterator> i)
{
return i.position();
}
template <class Iterator>
inline Iterator get_line_start(Iterator lower_bound, Iterator current)
{
Iterator latest = lower_bound;
for (Iterator i = lower_bound; i != current; ++i) {
switch (*i) {
case '\r':
case '\n':
latest = i;
}
}
return latest;
}
template <class Iterator>
inline iterator_range<Iterator>
get_current_line(Iterator lower_bound,
Iterator current,
Iterator upper_bound)
{
Iterator first = get_line_start(lower_bound, current);
Iterator last = get_line_start(current, upper_bound);
if (last == current)
last = upper_bound;
return iterator_range<Iterator>(first, last);
}
template <class Iterator>
inline std::size_t get_column(Iterator lower_bound,
Iterator current,
std::size_t tabs)
{
std::size_t column = 1;
Iterator first = get_line_start(lower_bound, current);
for (Iterator i = first; i != current; ++i) {
switch (*i) {
case '\t':
column += tabs - (column - 1) % tabs;
break;
default:
++column;
}
}
return column;
}
}}
#endif // BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR

View File

@@ -0,0 +1,69 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2011 Hartmut Kaiser
// http://spirit.sourceforge.net/
//
// 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_ITERATOR_LOOK_AHEAD_MAR_16_2007_1253PM)
#define BOOST_SPIRIT_ITERATOR_LOOK_AHEAD_MAR_16_2007_1253PM
#include <boost/spirit/home/support/iterators/detail/first_owner_policy.hpp>
#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
#include <boost/spirit/home/support/iterators/detail/fixed_size_queue_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
{
///////////////////////////////////////////////////////////////////////////
// this could be a template typedef, since such a thing doesn't
// exist in C++, we'll use inheritance to accomplish the same thing.
///////////////////////////////////////////////////////////////////////////
template <typename T, std::size_t N>
class look_ahead :
public multi_pass<T
, iterator_policies::default_policy<
iterator_policies::first_owner
, iterator_policies::no_check
, iterator_policies::input_iterator
, iterator_policies::fixed_size_queue<N> >
>
{
private:
typedef multi_pass<T
, iterator_policies::default_policy<
iterator_policies::first_owner
, iterator_policies::no_check
, iterator_policies::input_iterator
, iterator_policies::fixed_size_queue<N> >
> base_type;
public:
look_ahead()
: base_type() {}
explicit look_ahead(T x)
: base_type(x) {}
look_ahead(look_ahead const& x)
: base_type(x) {}
#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
look_ahead(int) // workaround for a bug in the library
: base_type() {} // shipped with gcc 3.1
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
look_ahead operator= (base_type const& rhs)
{
this->base_type::operator=(rhs);
return *this;
}
// default generated operators destructor and assignment operator are ok.
};
}}
#endif

View File

@@ -0,0 +1,245 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2011 Hartmut Kaiser
// http://spirit.sourceforge.net/
//
// 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_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
#include <boost/config.hpp>
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
#include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
#include <boost/limits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/base_from_member.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// The default multi_pass instantiation uses a ref-counted std_deque scheme.
///////////////////////////////////////////////////////////////////////////
template<typename T, typename Policies>
class multi_pass
: private boost::base_from_member<
typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
, public Policies::BOOST_NESTED_TEMPLATE unique<T>
{
private:
// unique and shared data types
typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T>
policies_base_type;
typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T>
shared_data_type;
typedef boost::base_from_member<shared_data_type*> member_base;
// define the types the standard embedded iterator typedefs are taken
// from
typedef typename policies_base_type::input_policy iterator_type;
public:
// standard iterator typedefs
typedef std::forward_iterator_tag iterator_category;
typedef typename iterator_type::value_type value_type;
typedef typename iterator_type::difference_type difference_type;
typedef typename iterator_type::distance_type distance_type;
typedef typename iterator_type::reference reference;
typedef typename iterator_type::pointer pointer;
multi_pass() : member_base(static_cast<shared_data_type*>(0)) {}
explicit multi_pass(T& input)
: member_base(new shared_data_type(input)), policies_base_type(input) {}
explicit multi_pass(T const& input)
: member_base(new shared_data_type(input)), policies_base_type(input) {}
multi_pass(multi_pass const& x)
: member_base(x.member), policies_base_type(x)
{
policies_base_type::clone(*this);
}
#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
// The standard library shipped with gcc-3.1 has a bug in
// bits/basic_string.tcc. It tries to use iter::iter(0) to
// construct an iterator. Ironically, this happens in sanity
// checking code that isn't required by the standard.
// The workaround is to provide an additional constructor that
// ignores its int argument and behaves like the default constructor.
multi_pass(int) : member_base(static_cast<shared_data_type*>(0)) {}
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
~multi_pass()
{
if (policies_base_type::release(*this)) {
policies_base_type::destroy(*this);
delete this->member;
}
}
multi_pass& operator=(multi_pass const& x)
{
if (this != &x) {
multi_pass temp(x);
temp.swap(*this);
}
return *this;
}
void swap(multi_pass& x)
{
boost::swap(this->member, x.member);
this->policies_base_type::swap(x);
}
reference operator*() const
{
policies_base_type::docheck(*this);
return policies_base_type::dereference(*this);
}
pointer operator->() const
{
return &(operator*());
}
multi_pass& operator++()
{
policies_base_type::docheck(*this);
policies_base_type::increment(*this);
return *this;
}
multi_pass operator++(int)
{
multi_pass tmp(*this);
++*this;
return tmp;
}
void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode =
traits::clear_mode::clear_if_enabled)
{
if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
policies_base_type::clear_queue(*this);
}
bool inhibit_clear_queue() const
{
return this->member->inhibit_clear_queue_;
}
void inhibit_clear_queue(bool flag)
{
this->member->inhibit_clear_queue_ = flag;
}
bool operator==(multi_pass const& y) const
{
if (is_eof())
return y.is_eof();
if (y.is_eof())
return false;
return policies_base_type::equal_to(*this, y);
}
bool operator<(multi_pass const& y) const
{
return policies_base_type::less_than(*this, y);
}
bool operator!=(multi_pass const& y)
{
return !(*this == y);
}
bool operator>(multi_pass const& y)
{
return y < *this;
}
bool operator>=(multi_pass const& y)
{
return !(*this < y);
}
bool operator<=(multi_pass const& y)
{
return !(y < *this);
}
// allow access to base member
shared_data_type* shared() const { return this->member; }
private: // helper functions
bool is_eof() const
{
return (0 == this->member) || policies_base_type::is_eof(*this);
}
};
///////////////////////////////////////////////////////////////////////////
// Generator function
///////////////////////////////////////////////////////////////////////////
template <typename Policies, typename T>
inline multi_pass<T, Policies>
make_multi_pass(T& i)
{
return multi_pass<T, Policies>(i);
}
template <typename Policies, typename T>
inline multi_pass<T, Policies>
make_multi_pass(T const& i)
{
return multi_pass<T, Policies>(i);
}
///////////////////////////////////////////////////////////////////////////
template <typename T>
inline multi_pass<T>
make_default_multi_pass(T& i)
{
return multi_pass<T>(i);
}
template <typename T>
inline multi_pass<T>
make_default_multi_pass(T const& i)
{
return multi_pass<T>(i);
}
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Policies>
inline void
swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
{
x.swap(y);
}
///////////////////////////////////////////////////////////////////////////
// define special functions allowing to integrate any multi_pass iterator
// with expectation points
namespace traits
{
template <typename T, typename Policies>
void clear_queue(multi_pass<T, Policies>& mp
, BOOST_SCOPED_ENUM(traits::clear_mode) mode)
{
mp.clear_queue(mode);
}
template <typename T, typename Policies>
void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
{
mp.inhibit_clear_queue(flag);
}
template <typename T, typename Policies>
bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
{
return mp.inhibit_clear_queue();
}
}
}} // namespace boost::spirit
#endif

View File

@@ -0,0 +1,91 @@
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
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_ITERATOR_MULTI_PASS_FWD_APR_18_2008_1102AM)
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_FWD_APR_18_2008_1102AM
#include <cstddef>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/swap.hpp>
namespace boost { namespace spirit {
namespace iterator_policies
{
// input policies
struct input_iterator;
struct buffering_input_iterator;
struct istream;
struct lex_input;
struct functor_input;
struct split_functor_input;
// ownership policies
struct ref_counted;
struct first_owner;
// checking policies
class illegal_backtracking;
struct buf_id_check;
struct no_check;
// storage policies
struct split_std_deque;
template<std::size_t N> struct fixed_size_queue;
// policy combiner
#if defined(BOOST_SPIRIT_DEBUG)
template<typename Ownership = ref_counted
, typename Checking = buf_id_check
, typename Input = buffering_input_iterator
, typename Storage = split_std_deque>
struct default_policy;
#else
template<typename Ownership = ref_counted
, typename Checking = no_check
, typename Input = buffering_input_iterator
, typename Storage = split_std_deque>
struct default_policy;
#endif
}
template <typename T
, typename Policies = iterator_policies::default_policy<> >
class multi_pass;
template <typename T, typename Policies>
void swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y);
}} // namespace boost::spirit
namespace boost { namespace spirit { namespace traits
{
// declare special functions allowing to integrate any multi_pass iterator
// with expectation points
// multi_pass iterators require special handling (for the non-specialized
// versions of these functions see support/multi_pass_wrapper.hpp)
template <typename T, typename Policies>
void clear_queue(multi_pass<T, Policies>&
, BOOST_SCOPED_ENUM(clear_mode) mode = clear_mode::clear_if_enabled);
template <typename T, typename Policies>
void inhibit_clear_queue(multi_pass<T, Policies>&, bool);
template <typename T, typename Policies>
bool inhibit_clear_queue(multi_pass<T, Policies>&);
// Helper template to recognize a multi_pass iterator. This specialization
// will be instantiated for any multi_pass iterator.
template <typename T, typename Policies>
struct is_multi_pass<multi_pass<T, Policies> > : mpl::true_ {};
}}}
#endif

View File

@@ -0,0 +1,16 @@
// Copyright (c) 2001-2011 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_OSTREAM_ITERATOR_JAN_13_2010_0211PM)
#define BOOST_SPIRIT_OSTREAM_ITERATOR_JAN_13_2010_0211PM
#include <boost/spirit/home/karma/stream/ostream_iterator.hpp>
namespace boost { namespace spirit
{
typedef karma::ostream_iterator<char, char> ostream_iterator;
}}
#endif