]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/support/iterators/multi_pass.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / support / iterators / multi_pass.hpp
1 // Copyright (c) 2001, Daniel C. Nuffer
2 // Copyright (c) 2001-2011 Hartmut Kaiser
3 // http://spirit.sourceforge.net/
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
9 #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
10
11 #include <boost/config.hpp>
12 #include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
13 #include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
14 #include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
15 #include <boost/limits.hpp>
16 #include <boost/detail/workaround.hpp>
17 #include <boost/utility/base_from_member.hpp>
18
19 namespace boost { namespace spirit
20 {
21 ///////////////////////////////////////////////////////////////////////////
22 // The default multi_pass instantiation uses a ref-counted std_deque scheme.
23 ///////////////////////////////////////////////////////////////////////////
24 template<typename T, typename Policies>
25 class multi_pass
26 : private boost::base_from_member<
27 typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
28 , public Policies::BOOST_NESTED_TEMPLATE unique<T>
29 {
30 private:
31 // unique and shared data types
32 typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T>
33 policies_base_type;
34 typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T>
35 shared_data_type;
36
37 typedef boost::base_from_member<shared_data_type*> member_base;
38
39 // define the types the standard embedded iterator typedefs are taken
40 // from
41 typedef typename policies_base_type::input_policy iterator_type;
42
43 public:
44 // standard iterator typedefs
45 typedef std::forward_iterator_tag iterator_category;
46 typedef typename iterator_type::value_type value_type;
47 typedef typename iterator_type::difference_type difference_type;
48 typedef typename iterator_type::distance_type distance_type;
49 typedef typename iterator_type::reference reference;
50 typedef typename iterator_type::pointer pointer;
51
52 multi_pass() : member_base(static_cast<shared_data_type*>(0)) {}
53
54 explicit multi_pass(T& input)
55 : member_base(new shared_data_type(input)), policies_base_type(input) {}
56
57 explicit multi_pass(T const& input)
58 : member_base(new shared_data_type(input)), policies_base_type(input) {}
59
60 multi_pass(multi_pass const& x)
61 : member_base(x.member), policies_base_type(x)
62 {
63 policies_base_type::clone(*this);
64 }
65
66 #if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
67 // The standard library shipped with gcc-3.1 has a bug in
68 // bits/basic_string.tcc. It tries to use iter::iter(0) to
69 // construct an iterator. Ironically, this happens in sanity
70 // checking code that isn't required by the standard.
71 // The workaround is to provide an additional constructor that
72 // ignores its int argument and behaves like the default constructor.
73 multi_pass(int) : member_base(static_cast<shared_data_type*>(0)) {}
74 #endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
75
76 ~multi_pass()
77 {
78 if (policies_base_type::release(*this)) {
79 policies_base_type::destroy(*this);
80 delete this->member;
81 }
82 }
83
84 multi_pass& operator=(multi_pass const& x)
85 {
86 if (this != &x) {
87 multi_pass temp(x);
88 temp.swap(*this);
89 }
90 return *this;
91 }
92
93 void swap(multi_pass& x)
94 {
95 boost::swap(this->member, x.member);
96 this->policies_base_type::swap(x);
97 }
98
99 reference operator*() const
100 {
101 policies_base_type::docheck(*this);
102 return policies_base_type::dereference(*this);
103 }
104 pointer operator->() const
105 {
106 return &(operator*());
107 }
108
109 multi_pass& operator++()
110 {
111 policies_base_type::docheck(*this);
112 policies_base_type::increment(*this);
113 return *this;
114 }
115 multi_pass operator++(int)
116 {
117 multi_pass tmp(*this);
118 ++*this;
119 return tmp;
120 }
121
122 void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode =
123 traits::clear_mode::clear_if_enabled)
124 {
125 if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
126 policies_base_type::clear_queue(*this);
127 }
128 bool inhibit_clear_queue() const
129 {
130 return this->member->inhibit_clear_queue_;
131 }
132 void inhibit_clear_queue(bool flag)
133 {
134 this->member->inhibit_clear_queue_ = flag;
135 }
136
137 bool operator==(multi_pass const& y) const
138 {
139 if (is_eof())
140 return y.is_eof();
141 if (y.is_eof())
142 return false;
143
144 return policies_base_type::equal_to(*this, y);
145 }
146 bool operator<(multi_pass const& y) const
147 {
148 return policies_base_type::less_than(*this, y);
149 }
150
151 bool operator!=(multi_pass const& y)
152 {
153 return !(*this == y);
154 }
155 bool operator>(multi_pass const& y)
156 {
157 return y < *this;
158 }
159 bool operator>=(multi_pass const& y)
160 {
161 return !(*this < y);
162 }
163 bool operator<=(multi_pass const& y)
164 {
165 return !(y < *this);
166 }
167
168 // allow access to base member
169 shared_data_type* shared() const { return this->member; }
170
171 private: // helper functions
172 bool is_eof() const
173 {
174 return (0 == this->member) || policies_base_type::is_eof(*this);
175 }
176 };
177
178 ///////////////////////////////////////////////////////////////////////////
179 // Generator function
180 ///////////////////////////////////////////////////////////////////////////
181 template <typename Policies, typename T>
182 inline multi_pass<T, Policies>
183 make_multi_pass(T& i)
184 {
185 return multi_pass<T, Policies>(i);
186 }
187 template <typename Policies, typename T>
188 inline multi_pass<T, Policies>
189 make_multi_pass(T const& i)
190 {
191 return multi_pass<T, Policies>(i);
192 }
193
194 ///////////////////////////////////////////////////////////////////////////
195 template <typename T>
196 inline multi_pass<T>
197 make_default_multi_pass(T& i)
198 {
199 return multi_pass<T>(i);
200 }
201 template <typename T>
202 inline multi_pass<T>
203 make_default_multi_pass(T const& i)
204 {
205 return multi_pass<T>(i);
206 }
207
208 ///////////////////////////////////////////////////////////////////////////
209 template <typename T, typename Policies>
210 inline void
211 swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
212 {
213 x.swap(y);
214 }
215
216 ///////////////////////////////////////////////////////////////////////////
217 // define special functions allowing to integrate any multi_pass iterator
218 // with expectation points
219 namespace traits
220 {
221 template <typename T, typename Policies>
222 void clear_queue(multi_pass<T, Policies>& mp
223 , BOOST_SCOPED_ENUM(traits::clear_mode) mode)
224 {
225 mp.clear_queue(mode);
226 }
227
228 template <typename T, typename Policies>
229 void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
230 {
231 mp.inhibit_clear_queue(flag);
232 }
233
234 template <typename T, typename Policies>
235 bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
236 {
237 return mp.inhibit_clear_queue();
238 }
239 }
240
241 }} // namespace boost::spirit
242
243 #endif
244
245