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

source code of boost/libs/spirit/include/boost/spirit/home/support/iterators/multi_pass.hpp