]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (c) 2001 Daniel C. Nuffer |
2 | // Copyright (c) 2001-2011 Hartmut Kaiser | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #if !defined(BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM) | |
8 | #define BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM | |
9 | ||
10 | #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp> | |
11 | #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp> | |
12 | #include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp> | |
13 | #include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits | |
14 | #include <boost/assert.hpp> | |
15 | ||
16 | namespace boost { namespace spirit { namespace iterator_policies | |
17 | { | |
18 | /////////////////////////////////////////////////////////////////////////// | |
19 | // class input_iterator | |
20 | // | |
21 | // Implementation of the InputPolicy used by multi_pass, this is different | |
22 | // from the input_iterator policy only as it is buffering the last input | |
23 | // character to allow returning it by reference. This is needed for | |
24 | // wrapping iterators not buffering the last item (such as the | |
25 | // std::istreambuf_iterator). Unfortunately there is no way to | |
26 | // automatically figure this out at compile time. | |
27 | // | |
28 | // The buffering_input_iterator encapsulates an input iterator of type T | |
29 | /////////////////////////////////////////////////////////////////////////// | |
30 | struct buffering_input_iterator | |
31 | { | |
32 | /////////////////////////////////////////////////////////////////////// | |
33 | template <typename T> | |
34 | class unique // : public detail::default_input_policy | |
35 | { | |
36 | private: | |
37 | typedef | |
38 | typename boost::detail::iterator_traits<T>::value_type | |
39 | result_type; | |
40 | ||
41 | public: | |
42 | typedef | |
43 | typename boost::detail::iterator_traits<T>::difference_type | |
44 | difference_type; | |
45 | typedef | |
46 | typename boost::detail::iterator_traits<T>::difference_type | |
47 | distance_type; | |
48 | typedef | |
49 | typename boost::detail::iterator_traits<T>::pointer | |
50 | pointer; | |
51 | typedef result_type& reference; | |
52 | typedef result_type value_type; | |
53 | ||
54 | protected: | |
55 | unique() {} | |
56 | explicit unique(T x) {} | |
57 | ||
58 | void swap(unique&) {} | |
59 | ||
60 | public: | |
61 | template <typename MultiPass> | |
62 | static void destroy(MultiPass&) {} | |
63 | ||
64 | template <typename MultiPass> | |
65 | static typename MultiPass::reference get_input(MultiPass& mp) | |
66 | { | |
67 | return mp.shared()->get_input(); | |
68 | } | |
69 | ||
70 | template <typename MultiPass> | |
71 | static void advance_input(MultiPass& mp) | |
72 | { | |
73 | BOOST_ASSERT(0 != mp.shared()); | |
74 | mp.shared()->advance_input(); | |
75 | } | |
76 | ||
77 | // test, whether we reached the end of the underlying stream | |
78 | template <typename MultiPass> | |
79 | static bool input_at_eof(MultiPass const& mp) | |
80 | { | |
81 | static T const end_iter; | |
82 | return mp.shared()->input_ == end_iter; | |
83 | } | |
84 | ||
85 | template <typename MultiPass> | |
86 | static bool input_is_valid(MultiPass const& mp, value_type const& t) | |
87 | { | |
88 | return mp.shared()->input_is_valid_; | |
89 | } | |
90 | ||
91 | // no unique data elements | |
92 | }; | |
93 | ||
94 | /////////////////////////////////////////////////////////////////////// | |
95 | template <typename T> | |
96 | struct shared | |
97 | { | |
98 | typedef | |
99 | typename boost::detail::iterator_traits<T>::value_type | |
100 | result_type; | |
101 | ||
102 | explicit shared(T const& input) | |
103 | : input_(input), curtok_(0), input_is_valid_(false) {} | |
104 | ||
105 | void advance_input() | |
106 | { | |
107 | ++input_; | |
108 | input_is_valid_ = false; | |
109 | } | |
110 | ||
111 | result_type& get_input() | |
112 | { | |
113 | if (!input_is_valid_) { | |
114 | curtok_ = *input_; | |
115 | input_is_valid_ = true; | |
116 | } | |
117 | return curtok_; | |
118 | } | |
119 | ||
120 | T input_; | |
121 | result_type curtok_; | |
122 | bool input_is_valid_; | |
123 | }; | |
124 | }; | |
125 | ||
126 | }}} | |
127 | ||
128 | #endif |