Imported Upstream version 1.57.0
[platform/upstream/boost.git] / 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