1 // Copyright (c) 2001, Daniel C. Nuffer
2 // Copyright (c) 2001-2011 Hartmut Kaiser
3 // http://spirit.sourceforge.net/
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)
8 #if !defined(BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM)
9 #define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1124AM
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>
19 namespace boost { namespace spirit
21 ///////////////////////////////////////////////////////////////////////////
22 // The default multi_pass instantiation uses a ref-counted std_deque scheme.
23 ///////////////////////////////////////////////////////////////////////////
24 template<typename T, typename Policies>
26 : private boost::base_from_member<
27 typename Policies::BOOST_NESTED_TEMPLATE shared<T>*>
28 , public Policies::BOOST_NESTED_TEMPLATE unique<T>
31 // unique and shared data types
32 typedef typename Policies::BOOST_NESTED_TEMPLATE unique<T>
34 typedef typename Policies::BOOST_NESTED_TEMPLATE shared<T>
37 typedef boost::base_from_member<shared_data_type*> member_base;
39 // define the types the standard embedded iterator typedefs are taken
41 typedef typename policies_base_type::input_policy iterator_type;
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;
52 multi_pass() : member_base(static_cast<shared_data_type*>(0)) {}
54 explicit multi_pass(T& input)
55 : member_base(new shared_data_type(input)), policies_base_type(input) {}
57 explicit multi_pass(T const& input)
58 : member_base(new shared_data_type(input)), policies_base_type(input) {}
60 multi_pass(multi_pass const& x)
61 : member_base(x.member), policies_base_type(x)
63 policies_base_type::clone(*this);
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)
78 if (policies_base_type::release(*this)) {
79 policies_base_type::destroy(*this);
84 multi_pass& operator=(multi_pass const& x)
93 void swap(multi_pass& x)
95 boost::swap(this->member, x.member);
96 this->policies_base_type::swap(x);
99 reference operator*() const
101 policies_base_type::docheck(*this);
102 return policies_base_type::dereference(*this);
104 pointer operator->() const
106 return &(operator*());
109 multi_pass& operator++()
111 policies_base_type::docheck(*this);
112 policies_base_type::increment(*this);
115 multi_pass operator++(int)
117 multi_pass tmp(*this);
122 void clear_queue(BOOST_SCOPED_ENUM(traits::clear_mode) mode =
123 traits::clear_mode::clear_if_enabled)
125 if (mode == traits::clear_mode::clear_always || !inhibit_clear_queue())
126 policies_base_type::clear_queue(*this);
128 bool inhibit_clear_queue() const
130 return this->member->inhibit_clear_queue_;
132 void inhibit_clear_queue(bool flag)
134 this->member->inhibit_clear_queue_ = flag;
137 bool operator==(multi_pass const& y) const
144 return policies_base_type::equal_to(*this, y);
146 bool operator<(multi_pass const& y) const
148 return policies_base_type::less_than(*this, y);
151 bool operator!=(multi_pass const& y)
153 return !(*this == y);
155 bool operator>(multi_pass const& y)
159 bool operator>=(multi_pass const& y)
163 bool operator<=(multi_pass const& y)
168 // allow access to base member
169 shared_data_type* shared() const { return this->member; }
171 private: // helper functions
174 return (0 == this->member) || policies_base_type::is_eof(*this);
178 ///////////////////////////////////////////////////////////////////////////
179 // Generator function
180 ///////////////////////////////////////////////////////////////////////////
181 template <typename Policies, typename T>
182 inline multi_pass<T, Policies>
183 make_multi_pass(T& i)
185 return multi_pass<T, Policies>(i);
187 template <typename Policies, typename T>
188 inline multi_pass<T, Policies>
189 make_multi_pass(T const& i)
191 return multi_pass<T, Policies>(i);
194 ///////////////////////////////////////////////////////////////////////////
195 template <typename T>
197 make_default_multi_pass(T& i)
199 return multi_pass<T>(i);
201 template <typename T>
203 make_default_multi_pass(T const& i)
205 return multi_pass<T>(i);
208 ///////////////////////////////////////////////////////////////////////////
209 template <typename T, typename Policies>
211 swap(multi_pass<T, Policies> &x, multi_pass<T, Policies> &y)
216 ///////////////////////////////////////////////////////////////////////////
217 // define special functions allowing to integrate any multi_pass iterator
218 // with expectation points
221 template <typename T, typename Policies>
222 void clear_queue(multi_pass<T, Policies>& mp
223 , BOOST_SCOPED_ENUM(traits::clear_mode) mode)
225 mp.clear_queue(mode);
228 template <typename T, typename Policies>
229 void inhibit_clear_queue(multi_pass<T, Policies>& mp, bool flag)
231 mp.inhibit_clear_queue(flag);
234 template <typename T, typename Policies>
235 bool inhibit_clear_queue(multi_pass<T, Policies>& mp)
237 return mp.inhibit_clear_queue();
241 }} // namespace boost::spirit