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_16_2008_0448M) 7 #define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M 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 13 namespace boost { namespace spirit { namespace iterator_policies 14 { 15 namespace is_valid_test_ 16 { 17 template <typename Token> token_is_valid(Token const &)18 inline bool token_is_valid(Token const&) 19 { 20 return true; 21 } 22 } 23 24 /////////////////////////////////////////////////////////////////////////// 25 // class functor_input 26 // Implementation of the InputPolicy used by multi_pass 27 // functor_input gets tokens from a functor 28 // 29 // Note: the functor must have a typedef for result_type 30 // It also must have a static variable of type result_type defined 31 // to represent EOF that is called eof. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 struct functor_input 35 { 36 /////////////////////////////////////////////////////////////////////// 37 template <typename Functor> 38 class unique : public detail::default_input_policy 39 { 40 private: 41 typedef typename Functor::result_type result_type; 42 43 protected: unique()44 unique() {} unique(Functor const & x)45 explicit unique(Functor const& x) : ftor(x) {} 46 swap(unique & x)47 void swap(unique& x) 48 { 49 boost::swap(ftor, x.ftor); 50 } 51 52 public: 53 typedef result_type value_type; 54 typedef std::ptrdiff_t difference_type; 55 typedef std::ptrdiff_t distance_type; 56 typedef result_type* pointer; 57 typedef result_type& reference; 58 59 public: 60 // get the next token 61 template <typename MultiPass> get_input(MultiPass & mp)62 static typename MultiPass::reference get_input(MultiPass& mp) 63 { 64 value_type& curtok = mp.shared()->curtok; 65 if (!input_is_valid(mp, curtok)) 66 curtok = mp.ftor(); 67 return curtok; 68 } 69 70 template <typename MultiPass> advance_input(MultiPass & mp)71 static void advance_input(MultiPass& mp) 72 { 73 // if mp.shared is NULL then this instance of the multi_pass 74 // represents a end iterator 75 BOOST_ASSERT(0 != mp.shared()); 76 mp.shared()->curtok = mp.ftor(); 77 } 78 79 // test, whether we reached the end of the underlying stream 80 template <typename MultiPass> input_at_eof(MultiPass const & mp)81 static bool input_at_eof(MultiPass const& mp) 82 { 83 return mp.shared()->curtok == mp.ftor.eof; 84 } 85 86 template <typename MultiPass> input_is_valid(MultiPass const &,value_type const & t)87 static bool input_is_valid(MultiPass const&, value_type const& t) 88 { 89 using namespace is_valid_test_; 90 return token_is_valid(t); 91 } 92 get_functor() const93 Functor& get_functor() const 94 { 95 return ftor; 96 } 97 98 protected: 99 mutable Functor ftor; 100 }; 101 102 /////////////////////////////////////////////////////////////////////// 103 template <typename Functor> 104 struct shared 105 { sharedboost::spirit::iterator_policies::functor_input::shared106 explicit shared(Functor const&) : curtok(0) {} 107 108 typename Functor::result_type curtok; 109 }; 110 }; 111 112 }}} 113 114 #endif 115