Line data Source code
1 : /*============================================================================= 2 : Boost.Wave: A Standard compliant C++ preprocessor library 3 : 4 : http://www.boost.org/ 5 : 6 : Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost 7 : Software License, Version 1.0. (See accompanying file 8 : LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 : =============================================================================*/ 10 : 11 : #if !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) 12 : #define FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED 13 : 14 : #include <boost/assert.hpp> 15 : #include <boost/spirit/include/classic_multi_pass.hpp> 16 : #include <boost/wave/wave_config.hpp> 17 : 18 : // this must occur after all of the includes and before any code appears 19 : #ifdef BOOST_HAS_ABI_HEADERS 20 : #include BOOST_ABI_PREFIX 21 : #endif 22 : 23 : /////////////////////////////////////////////////////////////////////////////// 24 : namespace boost { 25 : namespace wave { 26 : namespace util { 27 : 28 : /////////////////////////////////////////////////////////////////////////////// 29 : // 30 : // class functor_input 31 : // 32 : // Implementation of the InputPolicy used by multi_pass 33 : // functor_input gets tokens from a functor 34 : // Note: the functor must have a typedef for result_type 35 : // It also must have a static variable of type result_type defined 36 : // to represent eof that is called eof. 37 : // 38 : // This functor input policy template is essentially the same as the 39 : // predefined multi_pass functor_input policy. The difference is, 40 : // that the first token is not read at initialization time, but only 41 : // just before returning the first token. Additionally it does not 42 : // call operator new() twice but only once. 43 : // 44 : /////////////////////////////////////////////////////////////////////////////// 45 : struct functor_input { 46 : 47 : template <typename FunctorT> 48 : class inner { 49 : private: 50 : typedef typename FunctorT::result_type result_type; 51 : 52 : public: 53 : typedef result_type value_type; 54 : 55 : private: 56 : struct Data { 57 0 : Data(FunctorT const &ftor_) 58 0 : : ftor(ftor_), was_initialized(false) 59 : {} 60 : 61 : FunctorT ftor; 62 : value_type curtok; 63 : bool was_initialized; 64 : }; 65 : 66 : // Needed by compilers not implementing the resolution to DR45. For 67 : // reference, see 68 : // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45. 69 : 70 : friend struct Data; 71 : 72 : public: 73 : typedef std::ptrdiff_t difference_type; 74 : typedef result_type *pointer; 75 : typedef result_type &reference; 76 : 77 : protected: 78 0 : inner() 79 0 : : data(0) 80 : {} 81 : 82 0 : inner(FunctorT const &x) 83 0 : : data(new Data(x)) 84 0 : {} 85 : 86 : inner(inner const &x) 87 : : data(x.data) 88 : {} 89 : 90 : void destroy() 91 : { 92 : delete data; 93 : data = 0; 94 : } 95 : 96 0 : bool same_input(inner const &x) const 97 : { 98 : return data == x.data; 99 : } 100 : 101 : void swap(inner &x) 102 : { 103 : boost::spirit::classic::impl::mp_swap(data, x.data); 104 : } 105 : 106 : void ensure_initialized() const 107 : { 108 : if (data && !data->was_initialized) { 109 : data->curtok = (data->ftor)(); // get the first token 110 : data->was_initialized = true; 111 : } 112 : } 113 : 114 : public: 115 0 : reference get_input() const 116 : { 117 0 : ensure_initialized(); 118 0 : return data->curtok; 119 : } 120 : 121 : void advance_input() 122 : { 123 : BOOST_ASSERT(0 != data); 124 : data->curtok = (data->ftor)(); 125 : data->was_initialized = true; 126 : } 127 : 128 0 : bool input_at_eof() const 129 : { 130 0 : ensure_initialized(); 131 0 : return !data || data->curtok == data->ftor.eof; 132 : } 133 : 134 0 : FunctorT& get_functor() const 135 : { 136 0 : BOOST_ASSERT(0 != data); 137 0 : return data->ftor; 138 : } 139 : 140 : private: 141 : mutable Data *data; 142 : }; 143 : }; 144 : 145 : /////////////////////////////////////////////////////////////////////////////// 146 : } // namespace util 147 : } // namespace wave 148 : } // namespace boost 149 : 150 : // the suffix header occurs after all of the code 151 : #ifdef BOOST_HAS_ABI_HEADERS 152 : #include BOOST_ABI_SUFFIX 153 : #endif 154 : 155 : #endif // !defined(FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED)