Added thirdparty: boost library

This commit is contained in:
Viacheslav Demydiuk
2024-01-06 19:55:56 +02:00
parent bf49f439e1
commit bccd1e7051
15683 changed files with 3239840 additions and 0 deletions
@@ -0,0 +1,91 @@
// 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/core/invoke_swap.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 BOOST_SYMBOL_VISIBLE illegal_backtracking : public std::exception
{
public:
illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW {}
~illegal_backtracking() BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE {}
char const* what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
{
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::core::invoke_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
@@ -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/assert.hpp>
#include <iterator> // for std::iterator_traits
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 std::iterator_traits<T>::value_type
result_type;
public:
typedef
typename std::iterator_traits<T>::difference_type
difference_type;
typedef
typename std::iterator_traits<T>::difference_type
distance_type;
typedef
typename std::iterator_traits<T>::pointer
pointer;
typedef result_type& 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)
{
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&)
{
return mp.shared()->input_is_valid_;
}
// no unique data elements
};
///////////////////////////////////////////////////////////////////////
template <typename T>
struct shared
{
typedef
typename std::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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,129 @@
// 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/core/invoke_swap.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::core::invoke_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
@@ -0,0 +1,115 @@
// 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/core/invoke_swap.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::core::invoke_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
@@ -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/assert.hpp>
#include <iterator> // for std::iterator_traits
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 std::iterator_traits<T>::value_type
result_type;
public:
typedef
typename std::iterator_traits<T>::difference_type
difference_type;
typedef
typename std::iterator_traits<T>::difference_type
distance_type;
typedef
typename std::iterator_traits<T>::pointer
pointer;
typedef
typename std::iterator_traits<T>::reference
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)
{
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&, 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
@@ -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
@@ -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
@@ -0,0 +1,108 @@
// 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/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
@@ -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
@@ -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
@@ -0,0 +1,198 @@
// 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/core/invoke_swap.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::core::invoke_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;
};
};
}}}
#endif
@@ -0,0 +1,171 @@
// 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/core/invoke_swap.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::core::invoke_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
@@ -0,0 +1,77 @@
// 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) {}
#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
@@ -0,0 +1,250 @@
/*==============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2010 Bryce Lelbach
Copyright (c) 2014 Tomoki Imai
Copyright (c) 2023 Kniazev Nikita
Copyright (c) 2023 Tobias Loew
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_core.hpp>
#include <iterator>
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.
NOTE: line counting considers position inside multicharacter line-breaks
(such as CRLF and LFCR) as being on the next line already. */
//`[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 line_start = 1);
std::size_t position() const;
private:
friend class boost::iterator_core_access;
void increment();
std::size_t line; // The line position.
bool prev_n;
bool prev_r;
};
//]
template <class Iterator>
line_pos_iterator<Iterator>::line_pos_iterator() :
line_pos_iterator::iterator_adaptor_(), line(1), prev_n(), prev_r() { }
template <class Iterator>
line_pos_iterator<Iterator>::line_pos_iterator(Iterator base, std::size_t line_start /* = 1 */ ) :
line_pos_iterator::iterator_adaptor_(base), line(line_start), prev_n(), prev_r() { }
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
ch = *(this->base());
int newline = ((ch == '\n') & !prev_r) | ((ch == '\r') & !prev_n);
line += newline;
prev_r = (ch == '\r') & newline;
prev_n = (ch == '\n') & newline;
++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_line_end]
template <class Iterator>
inline Iterator get_line_end(Iterator current, Iterator upper_bound);
/*`Get an iterator to the end 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();
}
namespace detail {
// get_line_start for forward iterators: forward linear search starting from lower-bound
// complexity: linear in length of [lower_bound, current)
template <class Iterator>
inline Iterator get_line_start(Iterator lower_bound,
Iterator current,
std::forward_iterator_tag)
{
Iterator latest = lower_bound;
for (Iterator it = lower_bound; it != current; ) {
if ((*it == '\r') || (*it == '\n')) {
latest = ++it;
}
else {
++it;
}
}
return latest;
}
// get_line_start for forward iterators: backward linear search starting from current
// complexity: linear in avarage line-length
template <class Iterator>
inline Iterator get_line_start(Iterator lower_bound,
Iterator current,
std::bidirectional_iterator_tag)
{
while (current != lower_bound) {
--current;
if ((*current == '\r') || (*current == '\n')) {
return ++current;
}
}
return current;
}
}
template <class Iterator>
inline Iterator get_line_start(Iterator lower_bound, Iterator current)
{
return detail::get_line_start(
lower_bound,
current,
typename std::iterator_traits<Iterator>::iterator_category()
);
}
template <class Iterator>
inline line_pos_iterator<Iterator>
get_line_start(line_pos_iterator<Iterator> lower_bound,
line_pos_iterator<Iterator> current)
{
// No need in line number counting because it will be the same
Iterator it = get_line_start(lower_bound.base(), current.base());
return line_pos_iterator<Iterator>(it, current.position());
}
template <class Iterator>
inline Iterator get_line_end(Iterator current, Iterator upper_bound)
{
for (Iterator i = current; i != upper_bound; ++i) {
if ((*i == '\n') || (*i == '\r')) {
return i;
}
}
return upper_bound;
}
template <class Iterator>
inline line_pos_iterator<Iterator>
get_line_end(line_pos_iterator<Iterator> current,
line_pos_iterator<Iterator> upper_bound)
{
// No need in line number counting because it will be the same
Iterator it = get_line_end(current.base(), upper_bound.base());
return line_pos_iterator<Iterator>(it, current.position());
}
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_end(current, 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;
}
template <class Iterator>
inline std::size_t get_column(line_pos_iterator<Iterator> lower_bound,
line_pos_iterator<Iterator> current,
std::size_t tabs = 4)
{
return get_column(lower_bound.base(), current.base(), tabs);
}
}}
#endif // BOOST_SPIRIT_SUPPORT_LINE_POS_ITERATOR
+69
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
+246
View File
@@ -0,0 +1,246 @@
// 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/core/invoke_swap.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::core::invoke_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) const
{
return !(*this == y);
}
bool operator>(multi_pass const& y) const
{
return y < *this;
}
bool operator>=(multi_pass const& y) const
{
return !(*this < y);
}
bool operator<=(multi_pass const& y) const
{
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
@@ -0,0 +1,90 @@
/*=============================================================================
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>
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
@@ -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