/*============================================================================= | |
Boost.Wave: A Standard compliant C++ preprocessor library | |
http://www.boost.org/ | |
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(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) | |
#define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED | |
#include <boost/assert.hpp> | |
#include <boost/spirit/include/classic_multi_pass.hpp> | |
#include <boost/wave/wave_config.hpp> | |
// this must occur after all of the includes and before any code appears | |
#ifdef BOOST_HAS_ABI_HEADERS | |
#include BOOST_ABI_PREFIX | |
#endif | |
/////////////////////////////////////////////////////////////////////////////// | |
namespace boost { | |
namespace wave { | |
namespace util { | |
/////////////////////////////////////////////////////////////////////////////// | |
// | |
// 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. | |
// | |
// This functor input policy template is essentially the same as the | |
// predefined multi_pass functor_input policy. The difference is, | |
// that the first token is not read at initialization time, but only | |
// just before returning the first token. Additionally it does not | |
// call operator new() twice but only once. | |
// | |
/////////////////////////////////////////////////////////////////////////////// | |
struct functor_input { | |
template <typename FunctorT> | |
class inner { | |
private: | |
typedef typename FunctorT::result_type result_type; | |
public: | |
typedef result_type value_type; | |
private: | |
struct Data { | |
Data(FunctorT const &ftor_) | |
: ftor(ftor_), was_initialized(false) | |
{} | |
FunctorT ftor; | |
value_type curtok; | |
bool was_initialized; | |
}; | |
// Needed by compilers not implementing the resolution to DR45. For | |
// reference, see | |
// http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45. | |
friend struct Data; | |
public: | |
typedef std::ptrdiff_t difference_type; | |
typedef result_type *pointer; | |
typedef result_type &reference; | |
protected: | |
inner() | |
: data(0) | |
{} | |
inner(FunctorT const &x) | |
: data(new Data(x)) | |
{} | |
inner(inner const &x) | |
: data(x.data) | |
{} | |
void destroy() | |
{ | |
delete data; | |
data = 0; | |
} | |
bool same_input(inner const &x) const | |
{ | |
return data == x.data; | |
} | |
void swap(inner &x) | |
{ | |
boost::spirit::classic::impl::mp_swap(data, x.data); | |
} | |
void ensure_initialized() const | |
{ | |
if (data && !data->was_initialized) { | |
data->curtok = (data->ftor)(); // get the first token | |
data->was_initialized = true; | |
} | |
} | |
public: | |
reference get_input() const | |
{ | |
ensure_initialized(); | |
return data->curtok; | |
} | |
void advance_input() | |
{ | |
BOOST_ASSERT(0 != data); | |
data->curtok = (data->ftor)(); | |
data->was_initialized = true; | |
} | |
bool input_at_eof() const | |
{ | |
ensure_initialized(); | |
return !data || data->curtok == data->ftor.eof; | |
} | |
FunctorT& get_functor() const | |
{ | |
BOOST_ASSERT(0 != data); | |
return data->ftor; | |
} | |
private: | |
mutable Data *data; | |
}; | |
}; | |
/////////////////////////////////////////////////////////////////////////////// | |
} // namespace util | |
} // namespace wave | |
} // namespace boost | |
// the suffix header occurs after all of the code | |
#ifdef BOOST_HAS_ABI_HEADERS | |
#include BOOST_ABI_SUFFIX | |
#endif | |
#endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) |