1// (C) Copyright Jeremy Siek 2002.
2// Distributed under the Boost Software License, Version 1.0. (See
3// accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
7#define BOOST_ITERATOR_ARCHETYPES_HPP
8
9#include <boost/iterator/iterator_categories.hpp>
10#include <boost/operators.hpp>
11#include <boost/static_assert.hpp>
12#include <boost/iterator.hpp>
13
14#include <boost/iterator/detail/facade_iterator_category.hpp>
15
16#include <boost/type_traits/is_const.hpp>
17#include <boost/type_traits/add_const.hpp>
18#include <boost/type_traits/remove_const.hpp>
19#include <boost/type_traits/remove_cv.hpp>
20
21#include <boost/concept_archetype.hpp>
22
23#include <boost/mpl/bitand.hpp>
24#include <boost/mpl/int.hpp>
25#include <boost/mpl/equal_to.hpp>
26#include <boost/mpl/if.hpp>
27#include <boost/mpl/eval_if.hpp>
28#include <boost/mpl/and.hpp>
29#include <boost/mpl/identity.hpp>
30
31#include <cstddef>
32
33namespace boost {
34namespace iterators {
35
36template <class Value, class AccessCategory>
37struct access_archetype;
38
39template <class Derived, class Value, class AccessCategory, class TraversalCategory>
40struct traversal_archetype;
41
42namespace archetypes
43{
44 enum {
45 readable_iterator_bit = 1
46 , writable_iterator_bit = 2
47 , swappable_iterator_bit = 4
48 , lvalue_iterator_bit = 8
49 };
50
51 // Not quite tags, since dispatching wouldn't work.
52 typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
53 typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
54
55 typedef mpl::int_<
56 (readable_iterator_bit|writable_iterator_bit)
57 >::type readable_writable_iterator_t;
58
59 typedef mpl::int_<
60 (readable_iterator_bit|lvalue_iterator_bit)
61 >::type readable_lvalue_iterator_t;
62
63 typedef mpl::int_<
64 (lvalue_iterator_bit|writable_iterator_bit)
65 >::type writable_lvalue_iterator_t;
66
67 typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
68 typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
69
70 template <class Derived, class Base>
71 struct has_access
72 : mpl::equal_to<
73 mpl::bitand_<Derived,Base>
74 , Base
75 >
76 {};
77}
78
79namespace detail
80{
81 template <class T>
82 struct assign_proxy
83 {
84 assign_proxy& operator=(T) { return *this; }
85 };
86
87 template <class T>
88 struct read_proxy
89 {
90 operator T() { return static_object<T>::get(); }
91 };
92
93 template <class T>
94 struct read_write_proxy
95 : read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
96 {
97 read_write_proxy& operator=(T) { return *this; }
98 };
99
100 template <class T>
101 struct arrow_proxy
102 {
103 T const* operator->() const { return 0; }
104 };
105
106 struct no_operator_brackets {};
107
108 template <class ValueType>
109 struct readable_operator_brackets
110 {
111 read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
112 };
113
114 template <class ValueType>
115 struct writable_operator_brackets
116 {
117 read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
118 };
119
120 template <class Value, class AccessCategory, class TraversalCategory>
121 struct operator_brackets
122 : mpl::eval_if<
123 is_convertible<TraversalCategory, random_access_traversal_tag>
124 , mpl::eval_if<
125 archetypes::has_access<
126 AccessCategory
127 , archetypes::writable_iterator_t
128 >
129 , mpl::identity<writable_operator_brackets<Value> >
130 , mpl::if_<
131 archetypes::has_access<
132 AccessCategory
133 , archetypes::readable_iterator_t
134 >
135 , readable_operator_brackets<Value>
136 , no_operator_brackets
137 >
138 >
139 , mpl::identity<no_operator_brackets>
140 >::type
141 {};
142
143 template <class TraversalCategory>
144 struct traversal_archetype_impl
145 {
146 template <class Derived,class Value> struct archetype;
147 };
148
149 // Constructor argument for those iterators that
150 // are not default constructible
151 struct ctor_arg {};
152
153 template <class Derived, class Value, class TraversalCategory>
154 struct traversal_archetype_
155 : traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
156 {
157 typedef typename
158 traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
159 base;
160
161 traversal_archetype_() {}
162
163 traversal_archetype_(ctor_arg arg)
164 : base(arg)
165 {}
166 };
167
168 template <>
169 struct traversal_archetype_impl<incrementable_traversal_tag>
170 {
171 template<class Derived, class Value>
172 struct archetype
173 {
174 explicit archetype(ctor_arg) {}
175
176 struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
177 typedef bogus difference_type;
178
179 Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
180 Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
181 };
182 };
183
184 template <>
185 struct traversal_archetype_impl<single_pass_traversal_tag>
186 {
187 template<class Derived, class Value>
188 struct archetype
189 : public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
190 public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
191 {
192 explicit archetype(ctor_arg arg)
193 : traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
194 {}
195
196 typedef std::ptrdiff_t difference_type;
197 };
198 };
199
200 template <class Derived, class Value>
201 bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
202 traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
203
204 template <>
205 struct traversal_archetype_impl<forward_traversal_tag>
206 {
207 template<class Derived, class Value>
208 struct archetype
209 : public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
210 {
211 archetype()
212 : traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
213 {}
214 };
215 };
216
217 template <>
218 struct traversal_archetype_impl<bidirectional_traversal_tag>
219 {
220 template<class Derived, class Value>
221 struct archetype
222 : public traversal_archetype_<Derived, Value, forward_traversal_tag>
223 {
224 Derived& operator--() { return static_object<Derived>::get(); }
225 Derived operator--(int) const { return static_object<Derived>::get(); }
226 };
227 };
228
229 template <>
230 struct traversal_archetype_impl<random_access_traversal_tag>
231 {
232 template<class Derived, class Value>
233 struct archetype
234 : public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
235 {
236 Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
237 Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
238 };
239 };
240
241 template <class Derived, class Value>
242 Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
243 std::ptrdiff_t) { return static_object<Derived>::get(); }
244
245 template <class Derived, class Value>
246 Derived& operator+(std::ptrdiff_t,
247 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
248 { return static_object<Derived>::get(); }
249
250 template <class Derived, class Value>
251 Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
252 std::ptrdiff_t)
253 { return static_object<Derived>::get(); }
254
255 template <class Derived, class Value>
256 std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
257 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
258 { return 0; }
259
260 template <class Derived, class Value>
261 bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
262 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
263 { return true; }
264
265 template <class Derived, class Value>
266 bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
267 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
268 { return true; }
269
270 template <class Derived, class Value>
271 bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
272 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
273 { return true; }
274
275 template <class Derived, class Value>
276 bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
277 traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
278 { return true; }
279
280 struct bogus_type;
281
282 template <class Value>
283 struct convertible_type
284 : mpl::if_< is_const<Value>,
285 typename remove_const<Value>::type,
286 bogus_type >
287 {};
288
289} // namespace detail
290
291
292template <class> struct undefined;
293
294template <class AccessCategory>
295struct iterator_access_archetype_impl
296{
297 template <class Value> struct archetype;
298};
299
300template <class Value, class AccessCategory>
301struct iterator_access_archetype
302 : iterator_access_archetype_impl<
303 AccessCategory
304 >::template archetype<Value>
305{
306};
307
308template <>
309struct iterator_access_archetype_impl<
310 archetypes::readable_iterator_t
311>
312{
313 template <class Value>
314 struct archetype
315 {
316 typedef typename remove_cv<Value>::type value_type;
317 typedef Value reference;
318 typedef Value* pointer;
319
320 value_type operator*() const { return static_object<value_type>::get(); }
321
322 detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
323 };
324};
325
326template <>
327struct iterator_access_archetype_impl<
328 archetypes::writable_iterator_t
329>
330{
331 template <class Value>
332 struct archetype
333 {
334 BOOST_STATIC_ASSERT(!is_const<Value>::value);
335 typedef void value_type;
336 typedef void reference;
337 typedef void pointer;
338
339 detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
340 };
341};
342
343template <>
344struct iterator_access_archetype_impl<
345 archetypes::readable_writable_iterator_t
346>
347{
348 template <class Value>
349 struct archetype
350 : public virtual iterator_access_archetype<
351 Value, archetypes::readable_iterator_t
352 >
353 {
354 typedef detail::read_write_proxy<Value> reference;
355
356 detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
357 };
358};
359
360template <>
361struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
362{
363 template <class Value>
364 struct archetype
365 : public virtual iterator_access_archetype<
366 Value, archetypes::readable_iterator_t
367 >
368 {
369 typedef Value& reference;
370
371 Value& operator*() const { return static_object<Value>::get(); }
372 Value* operator->() const { return 0; }
373 };
374};
375
376template <>
377struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
378{
379 template <class Value>
380 struct archetype
381 : public virtual iterator_access_archetype<
382 Value, archetypes::readable_lvalue_iterator_t
383 >
384 {
385 BOOST_STATIC_ASSERT((!is_const<Value>::value));
386 };
387};
388
389
390template <class Value, class AccessCategory, class TraversalCategory>
391struct iterator_archetype;
392
393template <class Value, class AccessCategory, class TraversalCategory>
394struct traversal_archetype_base
395 : detail::operator_brackets<
396 typename remove_cv<Value>::type
397 , AccessCategory
398 , TraversalCategory
399 >
400 , detail::traversal_archetype_<
401 iterator_archetype<Value, AccessCategory, TraversalCategory>
402 , Value
403 , TraversalCategory
404 >
405{
406};
407
408namespace detail
409{
410 template <class Value, class AccessCategory, class TraversalCategory>
411 struct iterator_archetype_base
412 : iterator_access_archetype<Value, AccessCategory>
413 , traversal_archetype_base<Value, AccessCategory, TraversalCategory>
414 {
415 typedef iterator_access_archetype<Value, AccessCategory> access;
416
417 typedef typename detail::facade_iterator_category<
418 TraversalCategory
419 , typename mpl::eval_if<
420 archetypes::has_access<
421 AccessCategory, archetypes::writable_iterator_t
422 >
423 , remove_const<Value>
424 , add_const<Value>
425 >::type
426 , typename access::reference
427 >::type iterator_category;
428
429 // Needed for some broken libraries (see below)
430 typedef boost::iterator<
431 iterator_category
432 , Value
433 , typename traversal_archetype_base<
434 Value, AccessCategory, TraversalCategory
435 >::difference_type
436 , typename access::pointer
437 , typename access::reference
438 > workaround_iterator_base;
439 };
440}
441
442template <class Value, class AccessCategory, class TraversalCategory>
443struct iterator_archetype
444 : public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
445
446 // These broken libraries require derivation from std::iterator
447 // (or related magic) in order to handle iter_swap and other
448 // iterator operations
449# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
450 || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
451 , public detail::iterator_archetype_base<
452 Value, AccessCategory, TraversalCategory
453 >::workaround_iterator_base
454# endif
455{
456 // Derivation from std::iterator above caused references to nested
457 // types to be ambiguous, so now we have to redeclare them all
458 // here.
459# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
460 || BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
461
462 typedef detail::iterator_archetype_base<
463 Value,AccessCategory,TraversalCategory
464 > base;
465
466 typedef typename base::value_type value_type;
467 typedef typename base::reference reference;
468 typedef typename base::pointer pointer;
469 typedef typename base::difference_type difference_type;
470 typedef typename base::iterator_category iterator_category;
471# endif
472
473 iterator_archetype() { }
474 iterator_archetype(iterator_archetype const& x)
475 : detail::iterator_archetype_base<
476 Value
477 , AccessCategory
478 , TraversalCategory
479 >(x)
480 {}
481
482 iterator_archetype& operator=(iterator_archetype const&)
483 { return *this; }
484
485# if 0
486 // Optional conversion from mutable
487 iterator_archetype(
488 iterator_archetype<
489 typename detail::convertible_type<Value>::type
490 , AccessCategory
491 , TraversalCategory> const&
492 );
493# endif
494};
495
496} // namespace iterators
497
498// Backward compatibility names
499namespace iterator_archetypes = iterators::archetypes;
500using iterators::access_archetype;
501using iterators::traversal_archetype;
502using iterators::iterator_archetype;
503using iterators::undefined;
504using iterators::iterator_access_archetype_impl;
505using iterators::traversal_archetype_base;
506
507} // namespace boost
508
509#endif // BOOST_ITERATOR_ARCHETYPES_HPP
510

source code of boost/boost/iterator/iterator_archetypes.hpp