Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_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)
{
spirit::detail::swap(buf_id, x.buf_id);
}
// called to verify that everything is ok.
template <typename MultiPass>
static void check(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,480 @@
// Copyright (c) 2001-2008, 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/type_traits/is_empty.hpp>
namespace boost { namespace spirit { namespace multi_pass_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 a compiler is not
// allowed to apply the empty base optimization if multiple inheritance is
// involved (or at least most compilers fail to apply it).
// Additionally this can be used to combine separate policies into one
// single multi_pass_policy as required by the multi_pass template
///////////////////////////////////////////////////////////////////////////
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
// without partial template specialization there is nothing much to do in
// terms of empty base optimization anyways...
template <typename T, typename Ownership, typename Checking,
typename Input, typename Storage>
struct multi_pass_unique
: Ownership, Checking, Input, Storage
{
multi_pass_unique() {}
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);
}
};
#else
///////////////////////////////////////////////////////////////////////////
// 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 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 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& 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->Storage::swap(x);
}
// 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, typename TokenType>
inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
{ return Input::input_at_eof(mp, curtok); }
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 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);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void check(MultiPass const& mp)
{ Checking::check(mp); }
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{ Checking::clear_queue(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& 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->Storage::swap(x);
}
// 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, typename TokenType>
inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
{ return Input::input_at_eof(mp, curtok); }
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 check(MultiPass const& mp)
{ Checking::check(mp); }
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{ Checking::clear_queue(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 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);
}
// 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& 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->Storage::swap(x);
}
// 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, typename TokenType>
inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
{ return Input::input_at_eof(mp, curtok); }
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 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);
}
// checking policy functions are forwarded to the Checking type
template <typename MultiPass>
inline static void check(MultiPass const& mp)
{ Checking::check(mp); }
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{ Checking::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, 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);
}
// 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, typename TokenType>
inline static bool input_at_eof(MultiPass const& mp, TokenType& curtok)
{ return Input::input_at_eof(mp, curtok); }
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 check(MultiPass const& mp)
{ Checking::check(mp); }
template <typename MultiPass>
inline static void clear_queue(MultiPass& mp)
{ Checking::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); }
};
#endif
///////////////////////////////////////////////////////////////////////////
// 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 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 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 const& input) : shared_base_type(input) {}
};
};
}}}
#endif

View File

@@ -0,0 +1,70 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_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,388 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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_adaptor<
fsq_iterator<Queue, T, Pointer>, Pointer, T,
std::random_access_iterator_tag
>
{
public:
typedef typename Queue::position_type position_type;
typedef boost::iterator_adaptor<
fsq_iterator<Queue, T, Pointer>, Pointer, T,
std::random_access_iterator_tag
> base_type;
fsq_iterator() {}
fsq_iterator(position_type const &p_) : p(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;
}
template <
typename OtherDerived, typename OtherIterator,
typename V, typename C, typename R, typename D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D>
const &x) const
{
position_type const &rhs_pos =
static_cast<OtherDerived const &>(x).get_position();
return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
}
template <
typename OtherDerived, typename OtherIterator,
typename V, typename C, typename R, typename D
>
typename base_type::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D>
const &x) const
{
typedef typename base_type::difference_type difference_type;
position_type const &p2 =
static_cast<OtherDerived const &>(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)
{}
};
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(this, m_tail));
}
const_iterator end() const
{
return const_iterator(position(this, 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,127 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_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)
: queuePosition(x.queuePosition)
{}
void swap(unique& x)
{
spirit::detail::swap(queuePosition, x.queuePosition);
}
// 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.queuePosition == mp.shared->queuedElements.end())
{
return MultiPass::get_input(mp);
}
else
{
return *mp.queuePosition;
}
}
// 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.queuePosition == mp.shared->queuedElements.end())
{
// don't let the queue get larger than N
if (mp.shared->queuedElements.size() >= N)
mp.shared->queuedElements.pop_front();
mp.shared->queuedElements.push_back(MultiPass::get_input(mp));
MultiPass::advance_input(mp);
}
++mp.queuePosition;
}
// 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.queuePosition == mp.shared->queuedElements.end() &&
MultiPass::input_at_eof(mp);
}
// called by operator==
template <typename MultiPass>
static bool equal_to(MultiPass const& mp, MultiPass const& x)
{
return mp.queuePosition == x.queuePosition;
}
// called by operator<
template <typename MultiPass>
static bool less_than(MultiPass const& mp, MultiPass const& x)
{
return mp.queuePosition < x.queuePosition;
}
protected:
mutable typename queue_type::iterator queuePosition;
};
///////////////////////////////////////////////////////////////////////
template <typename Value>
struct shared
{
typedef detail::fixed_size_queue<Value, N> queue_type;
queue_type queuedElements;
};
};
}}}
#endif

View File

@@ -0,0 +1,106 @@
// Copyright (c) 2001-2008, 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 multi_pass_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)
{
spirit::detail::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 void advance_input(MultiPass& mp, value_type& t)
{
// 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();
}
// 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)
{
return t == mp.ftor.eof;
}
template <typename MultiPass>
static bool input_is_valid(MultiPass const& mp, 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& x) {}
// no shared data elements
};
};
}}}
#endif

View File

@@ -0,0 +1,108 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_policies
{
namespace input_iterator_is_valid_test_
{
template <typename Token>
inline bool token_is_valid(Token const&)
{
return true;
}
}
///////////////////////////////////////////////////////////////////////////
// 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>::distance_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) : input(x) {}
void swap(unique& x)
{
spirit::detail::swap(input, x.input);
}
public:
template <typename MultiPass>
static void advance_input(MultiPass& mp, value_type& t)
{
// 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.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&)
{
return mp.input == T();
}
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);
}
protected:
T input;
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
explicit shared(T) {}
// no shared data elements
};
};
}}}
#endif

View File

@@ -0,0 +1,79 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_policies
{
///////////////////////////////////////////////////////////////////////////////
// class lex_input
// Implementation of the InputPolicy used by multi_pass
//
// The lex_input class gets tokens (integers) from yylex()
///////////////////////////////////////////////////////////////////////////
struct lex_input
{
///////////////////////////////////////////////////////////////////////
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;
typedef int& reference;
protected:
unique() {}
explicit unique(T) {}
public:
template <typename MultiPass>
static void advance_input(MultiPass& mp, value_type& t)
{
// 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)
{
extern int yylex();
t = 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)
{
return 0 == t;
}
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) {}
// no shared data elements
};
};
}}}
#endif

View File

@@ -0,0 +1,137 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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/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
{
///////////////////////////////////////////////////////////////////////////
template <typename T>
inline void swap(T& t1, T& t2)
{
using std::swap;
using boost::spirit::swap;
swap(t1, t2);
}
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
///////////////////////////////////////////////////////////////////////////
// Meta-function to generate a std::iterator<> base class for multi_pass.
// This is used mainly to improve conformance of compilers not supporting
// PTS and thus relying on inheritance to recognize an iterator.
//
// We are using boost::iterator<> because it offers an automatic
// workaround for broken std::iterator<> implementations.
///////////////////////////////////////////////////////////////////////////
template <typename T, typename InputPolicy>
struct iterator_base_creator
{
typedef typename InputPolicy::BOOST_NESTED_TEMPLATE unique<T> input_type;
typedef boost::iterator <
std::forward_iterator_tag,
typename input_type::value_type,
typename input_type::difference_type,
typename input_type::pointer,
typename input_type::reference
> type;
};
#endif
///////////////////////////////////////////////////////////////////////////
// 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 TokenType& advance_input(MultiPass& mp, TokenType& curtok);
template <typename MultiPass, typename TokenType>
static bool input_at_eof(MultiPass const& mp, TokenType& curtok);
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 check(MultiPass const&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
};
}}}
#endif

View File

@@ -0,0 +1,44 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_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
{
void swap(unique&) {}
template <typename MultiPass>
static void check(MultiPass const&) {}
template <typename MultiPass>
static void clear_queue(MultiPass&) {}
template <typename MultiPass>
static void destroy(MultiPass&) {}
};
///////////////////////////////////////////////////////////////////////
struct shared
{};
};
}}}
#endif

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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>
#include <cstdlib>
namespace boost { namespace spirit { namespace multi_pass_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) {}
std::size_t count;
};
};
}}}
#endif

View File

@@ -0,0 +1,172 @@
// Copyright (c) 2001-2008, 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 multi_pass_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 hold 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
// 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* pointer;
typedef result_type& reference;
protected:
unique() {}
explicit unique(Functor const&) {}
public:
void swap(unique&) {}
// get the next token
template <typename MultiPass>
static value_type& advance_input(MultiPass& mp, value_type& t)
{
// passing 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);
}
// test, whether we reached the end of the underlying stream
template <typename MultiPass>
static bool input_at_eof(MultiPass const&, value_type const& t)
{
return t == 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)
{
spirit::detail::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 value_type& advance_input(MultiPass& mp, value_type& t)
{
// passing 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);
}
// 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)
{
return t == mp.ftor.eof;
}
typename Functor::first_type& get_functor() const
{
return ftor;
}
mutable functor_type ftor;
};
///////////////////////////////////////////////////////////////////////
template <typename Functor>
struct shared
{
explicit shared(Functor const& x) : ftor(x.second) {}
mutable typename Functor::second_type ftor;
};
};
}}}
#endif

View File

@@ -0,0 +1,170 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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 multi_pass_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)
{
spirit::detail::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;
if (0 == mp.queued_position)
{
if (queue.empty())
{
queue.push_back(Value());
return MultiPass::advance_input(mp, queue[mp.queued_position++]);
}
return queue[mp.queued_position++];
}
else if (!MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
{
MultiPass::advance_input(mp, queue[mp.queued_position-1]);
}
return queue[mp.queued_position-1];
}
// 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(0 != size && 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. 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());
mp.queued_position = 0;
// reuse first entry in the queue and initialize
// it from the input
MultiPass::advance_input(mp, queue[mp.queued_position++]);
}
else
{
// create a new entry in the queue and initialize
// it from the input
queue.push_back(Value());
MultiPass::advance_input(mp, queue[mp.queued_position++]);
}
}
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)
{
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]);
}
// 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,62 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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/input_iterator_policy.hpp>
#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/fixed_size_queue_policy.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,
multi_pass_policies::input_iterator,
multi_pass_policies::first_owner,
multi_pass_policies::no_check,
multi_pass_policies::fixed_size_queue<N>
>
{
private:
typedef multi_pass<
T,
multi_pass_policies::input_iterator,
multi_pass_policies::first_owner,
multi_pass_policies::no_check,
multi_pass_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)
// default generated operators destructor and assignment operator are ok.
};
}}
#endif

View File

@@ -0,0 +1,205 @@
// Copyright (c) 2001, Daniel C. Nuffer
// Copyright (c) 2001-2008, 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/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>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// The default multi_pass instantiation uses a ref-counted std_deque scheme.
///////////////////////////////////////////////////////////////////////////
template<typename T, typename Policies>
class multi_pass
: public Policies::BOOST_NESTED_TEMPLATE unique<T>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
, typename iterator_base_creator<T, typename Policies::input_policy>::type
#endif
{
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;
// define the types the standard embedded iterator typedefs are taken
// from
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
typedef typename iterator_base_creator<Input, T>::type iterator_type;
#else
typedef typename policies_base_type::input_policy iterator_type;
#endif
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()
: shared(0)
{}
explicit multi_pass(T input)
: shared(new shared_data_type(input)), policies_base_type(input)
{}
#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)
: shared(0)
{}
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
~multi_pass()
{
if (policies_base_type::release(*this)) {
policies_base_type::destroy(*this);
delete shared;
}
}
multi_pass(multi_pass const& x)
: shared(x.shared), policies_base_type(x)
{
policies_base_type::clone(*this);
}
multi_pass& operator=(multi_pass const& x)
{
if (this != &x) {
multi_pass temp(x);
temp.swap(*this);
}
return *this;
}
void swap(multi_pass& x)
{
spirit::detail::swap(shared, x.shared);
this->policies_base_type::swap(x);
}
reference operator*() const
{
policies_base_type::check(*this);
return policies_base_type::dereference(*this);
}
pointer operator->() const
{
return &(operator*());
}
multi_pass& operator++()
{
policies_base_type::check(*this);
policies_base_type::increment(*this);
return *this;
}
multi_pass operator++(int)
{
multi_pass tmp(*this);
++*this;
return tmp;
}
void clear_queue()
{
policies_base_type::clear_queue(*this);
}
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);
}
private: // helper functions
bool is_eof() const
{
return (0 == shared) || policies_base_type::is_eof(*this);
}
public:
shared_data_type *shared;
};
template <typename T, typename Policies>
inline bool
operator!=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
{
return !(x == y);
}
template <typename T, typename Policies>
inline bool
operator>(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
{
return y < x;
}
template <typename T, typename Policies>
inline bool
operator>=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
{
return !(x < y);
}
template <typename T, typename Policies>
inline bool
operator<=(multi_pass<T, Policies> const& x, multi_pass<T, Policies> const& y)
{
return !(y < x);
}
///////////////////////////////////////////////////////////////////////////
// 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 T, typename Policies>
inline void
swap(multi_pass<T, Policies> &x,
multi_pass<T, Policies> &y)
{
x.swap(y);
}
}} // namespace boost::spirit
#endif

View File

@@ -0,0 +1,51 @@
/*=============================================================================
Copyright (c) 2007 Tobias Schwinger
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>
namespace boost { namespace spirit {
namespace multi_pass_policies
{
// input policies
struct input_iterator;
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 std_deque;
template<std::size_t N> struct fixed_size_queue;
}
template <typename T, typename Policies>
class multi_pass;
template <typename T, typename Policies>
void swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y);
namespace detail
{
template <typename T> void swap(T& t1, T& t2);
}
}} // namespace boost::spirit
#endif