diff options
Diffstat (limited to 'boost/wave/util/functor_input.hpp')
-rw-r--r-- | boost/wave/util/functor_input.hpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/boost/wave/util/functor_input.hpp b/boost/wave/util/functor_input.hpp new file mode 100644 index 0000000000..d30a090a1a --- /dev/null +++ b/boost/wave/util/functor_input.hpp @@ -0,0 +1,155 @@ +/*============================================================================= + 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) |