Line data Source code
1 : // Copyright (c) 2001-2011 Hartmut Kaiser 2 : // 3 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 : 6 : #if !defined(BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM) 7 : #define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM 8 : 9 : #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp> 10 : #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp> 11 : #include <boost/assert.hpp> 12 : #include <boost/type_traits/is_empty.hpp> 13 : 14 : namespace boost { namespace spirit { namespace iterator_policies 15 : { 16 : namespace split_functor_input_is_valid_test_ 17 : { 18 : template <typename Token> 19 : inline bool token_is_valid(Token const&) 20 : { 21 : return true; 22 : } 23 : } 24 : 25 : /////////////////////////////////////////////////////////////////////////// 26 : // class split_functor_input 27 : // Implementation of the InputPolicy used by multi_pass 28 : // split_functor_input gets tokens from a functor 29 : // 30 : // This policy should be used when the functor holds two parts of data: a 31 : // unique part (unique for each instance of the iterator) and a shared 32 : // part (to be shared between the different copies of the same iterator). 33 : // Using this policy allows to merge the shared part of the functor with 34 : // the shared part of the iterator data, saving one pointer and one 35 : // allocation per iterator instance. 36 : // 37 : // The Functor template parameter of this policy is expected to be a 38 : // std::pair<unique, shared>, where 'unique' and 'shared' represent the 39 : // respective parts of the functor itself. 40 : // 41 : // Note: the unique part of the functor must have a typedef for result_type 42 : // It also must have a static variable of type result_type defined 43 : // to represent EOF that is called eof. 44 : // 45 : /////////////////////////////////////////////////////////////////////////// 46 : struct split_functor_input 47 : { 48 : /////////////////////////////////////////////////////////////////////// 49 : template <typename Functor 50 : , bool FunctorIsEmpty = is_empty<typename Functor::first_type>::value> 51 : class unique; 52 : 53 : // the unique part of the functor is empty, do not include the functor 54 : // as a member at all to avoid unnecessary padding bytes to be included 55 : // into the generated structure 56 : template <typename Functor> 57 : class unique<Functor, true> // : public detail::default_input_policy 58 : { 59 : protected: 60 : typedef typename Functor::first_type functor_type; 61 : typedef typename functor_type::result_type result_type; 62 : 63 : public: 64 : typedef result_type value_type; 65 : typedef std::ptrdiff_t difference_type; 66 : typedef std::ptrdiff_t distance_type; 67 : typedef result_type const* pointer; 68 : typedef result_type const& reference; 69 : 70 : protected: 71 : unique() {} 72 : explicit unique(Functor const&) {} 73 : 74 : public: 75 : void swap(unique&) {} 76 : 77 : // get the next token 78 : template <typename MultiPass> 79 0 : static typename MultiPass::reference get_input(MultiPass& mp) 80 : { 81 0 : value_type& curtok = mp.shared()->curtok; 82 : using namespace split_functor_input_is_valid_test_; 83 0 : if (!token_is_valid(curtok)) 84 0 : functor_type::get_next(mp, curtok); 85 : return curtok; 86 : } 87 : 88 : template <typename MultiPass> 89 0 : static void advance_input(MultiPass& mp) 90 : { 91 0 : functor_type::get_next(mp, mp.shared()->curtok); 92 : } 93 : 94 : // test, whether we reached the end of the underlying stream 95 : template <typename MultiPass> 96 0 : static bool input_at_eof(MultiPass const& mp) 97 : { 98 0 : return mp.shared()->curtok == functor_type::eof; 99 : } 100 : 101 : template <typename MultiPass> 102 : static bool input_is_valid(MultiPass const&, value_type const& t) 103 : { 104 : using namespace split_functor_input_is_valid_test_; 105 : return token_is_valid(t); 106 : } 107 : 108 : template <typename MultiPass> 109 0 : static void destroy(MultiPass& mp) 110 : { 111 0 : functor_type::destroy(mp); 112 : } 113 : }; 114 : 115 : // the unique part of the functor is non-empty 116 : template <typename Functor> 117 : class unique<Functor, false> : public unique<Functor, true> 118 : { 119 : protected: 120 : typedef typename Functor::first_type functor_type; 121 : typedef typename functor_type::result_type result_type; 122 : 123 : protected: 124 : unique() {} 125 : explicit unique(Functor const& x) : ftor(x.first) {} 126 : 127 : void swap(unique& x) 128 : { 129 : boost::swap(ftor, x.ftor); 130 : } 131 : 132 : public: 133 : typedef result_type value_type; 134 : typedef std::ptrdiff_t difference_type; 135 : typedef std::ptrdiff_t distance_type; 136 : typedef result_type const* pointer; 137 : typedef result_type const& reference; 138 : 139 : public: 140 : // get the next token 141 : template <typename MultiPass> 142 : static typename MultiPass::reference get_input(MultiPass& mp) 143 : { 144 : value_type& curtok = mp.shared()->curtok; 145 : using namespace split_functor_input_is_valid_test_; 146 : if (!token_is_valid(curtok)) 147 : functor_type::get_next(mp, curtok); 148 : return curtok; 149 : } 150 : 151 : template <typename MultiPass> 152 : static void advance_input(MultiPass& mp) 153 : { 154 : mp.ftor.get_next(mp, mp.shared()->curtok); 155 : } 156 : 157 : template <typename MultiPass> 158 : static bool input_is_valid(MultiPass const&, value_type const& t) 159 : { 160 : using namespace split_functor_input_is_valid_test_; 161 : return token_is_valid(t); 162 : } 163 : 164 : // test, whether we reached the end of the underlying stream 165 : template <typename MultiPass> 166 : static bool input_at_eof(MultiPass const& mp) 167 : { 168 : return mp.shared()->curtok == mp.ftor.eof; 169 : } 170 : 171 : typename Functor::first_type& get_functor() const 172 : { 173 : return ftor; 174 : } 175 : 176 : mutable functor_type ftor; 177 : }; 178 : 179 : /////////////////////////////////////////////////////////////////////// 180 : template <typename Functor> 181 0 : struct shared 182 : { 183 : protected: 184 : typedef typename Functor::first_type functor_type; 185 : typedef typename functor_type::result_type result_type; 186 : 187 : public: 188 0 : explicit shared(Functor const& x) : ftor(x.second), curtok(0) {} 189 : 190 : mutable typename Functor::second_type ftor; 191 : result_type curtok; 192 : 193 : // silence MSVC warning C4512: assignment operator could not be generated 194 : BOOST_DELETED_FUNCTION(shared& operator= (shared const&)) 195 : }; 196 : }; 197 : 198 : }}} 199 : 200 : #endif