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