]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/spirit/home/support/iterators/detail/buffering_input_iterator_policy.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / spirit / home / support / iterators / detail / buffering_input_iterator_policy.hpp
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