Chris@16: /*============================================================================= Chris@16: Boost.Wave: A Standard compliant C++ preprocessor library Chris@16: Chris@16: http://www.boost.org/ Chris@16: Chris@16: Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost Chris@16: Software License, Version 1.0. (See accompanying file Chris@16: LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: =============================================================================*/ Chris@16: Chris@16: #if !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) Chris@16: #define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // this must occur after all of the includes and before any code appears Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { Chris@16: namespace wave { Chris@16: namespace util { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // class functor_input Chris@16: // Chris@16: // Implementation of the InputPolicy used by multi_pass Chris@16: // functor_input gets tokens from a functor Chris@16: // Note: the functor must have a typedef for result_type Chris@16: // It also must have a static variable of type result_type defined Chris@16: // to represent eof that is called eof. Chris@16: // Chris@16: // This functor input policy template is essentially the same as the Chris@16: // predefined multi_pass functor_input policy. The difference is, Chris@16: // that the first token is not read at initialization time, but only Chris@16: // just before returning the first token. Additionally it does not Chris@16: // call operator new() twice but only once. Chris@16: // Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: struct functor_input { Chris@16: Chris@16: template Chris@16: class inner { Chris@16: private: Chris@16: typedef typename FunctorT::result_type result_type; Chris@16: Chris@16: public: Chris@16: typedef result_type value_type; Chris@16: Chris@16: private: Chris@16: struct Data { Chris@16: Data(FunctorT const &ftor_) Chris@16: : ftor(ftor_), was_initialized(false) Chris@16: {} Chris@16: Chris@16: FunctorT ftor; Chris@16: value_type curtok; Chris@16: bool was_initialized; Chris@16: }; Chris@16: Chris@16: // Needed by compilers not implementing the resolution to DR45. For Chris@16: // reference, see Chris@16: // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45. Chris@16: Chris@16: friend struct Data; Chris@16: Chris@16: public: Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: typedef result_type *pointer; Chris@16: typedef result_type &reference; Chris@16: Chris@16: protected: Chris@16: inner() Chris@16: : data(0) Chris@16: {} Chris@16: Chris@16: inner(FunctorT const &x) Chris@16: : data(new Data(x)) Chris@16: {} Chris@16: Chris@16: inner(inner const &x) Chris@16: : data(x.data) Chris@16: {} Chris@16: Chris@16: void destroy() Chris@16: { Chris@16: delete data; Chris@16: data = 0; Chris@16: } Chris@16: Chris@16: bool same_input(inner const &x) const Chris@16: { Chris@16: return data == x.data; Chris@16: } Chris@16: Chris@16: void swap(inner &x) Chris@16: { Chris@16: boost::spirit::classic::impl::mp_swap(data, x.data); Chris@16: } Chris@16: Chris@16: void ensure_initialized() const Chris@16: { Chris@16: if (data && !data->was_initialized) { Chris@16: data->curtok = (data->ftor)(); // get the first token Chris@16: data->was_initialized = true; Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: reference get_input() const Chris@16: { Chris@16: ensure_initialized(); Chris@16: return data->curtok; Chris@16: } Chris@16: Chris@16: void advance_input() Chris@16: { Chris@16: BOOST_ASSERT(0 != data); Chris@16: data->curtok = (data->ftor)(); Chris@16: data->was_initialized = true; Chris@16: } Chris@16: Chris@16: bool input_at_eof() const Chris@16: { Chris@16: ensure_initialized(); Chris@16: return !data || data->curtok == data->ftor.eof; Chris@16: } Chris@16: Chris@16: FunctorT& get_functor() const Chris@16: { Chris@16: BOOST_ASSERT(0 != data); Chris@16: return data->ftor; Chris@16: } Chris@16: Chris@16: private: Chris@16: mutable Data *data; Chris@16: }; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: } // namespace util Chris@16: } // namespace wave Chris@16: } // namespace boost Chris@16: Chris@16: // the suffix header occurs after all of the code Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: #include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: Chris@16: #endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)