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(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) 12 #define BOOST_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 { Databoost::wave::util::functor_input::inner::Data57 Data(FunctorT const &ftor_) 58 : 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: inner()78 inner() 79 : data(0) 80 {} 81 inner(FunctorT const & x)82 inner(FunctorT const &x) 83 : data(new Data(x)) 84 {} 85 inner(inner const & x)86 inner(inner const &x) 87 : data(x.data) 88 {} 89 destroy()90 void destroy() 91 { 92 delete data; 93 data = 0; 94 } 95 same_input(inner const & x) const96 bool same_input(inner const &x) const 97 { 98 return data == x.data; 99 } 100 swap(inner & x)101 void swap(inner &x) 102 { 103 boost::spirit::classic::impl::mp_swap(data, x.data); 104 } 105 ensure_initialized() const106 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: get_input() const115 reference get_input() const 116 { 117 ensure_initialized(); 118 return data->curtok; 119 } 120 advance_input()121 void advance_input() 122 { 123 BOOST_ASSERT(0 != data); 124 data->curtok = (data->ftor)(); 125 data->was_initialized = true; 126 } 127 input_at_eof() const128 bool input_at_eof() const 129 { 130 ensure_initialized(); 131 return !data || data->curtok == data->ftor.eof; 132 } 133 get_functor() const134 FunctorT& get_functor() const 135 { 136 BOOST_ASSERT(0 != data); 137 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(BOOST_FUNCTOR_INPUT_HPP_ED3A4C21_8F8A_453F_B438_08214FAC106A_INCLUDED) 156