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)
6
#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
7
#define BOOST_ITERATOR_ARCHETYPES_HPP
9
#include <boost/iterator/iterator_categories.hpp>
10
#include <boost/operators.hpp>
11
#include <boost/static_assert.hpp>
12
#include <boost/iterator.hpp>
14
#include <boost/iterator/detail/facade_iterator_category.hpp>
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>
21
#include <boost/concept_archetype.hpp>
23
#include <boost/mpl/aux_/msvc_eti_base.hpp>
24
#include <boost/mpl/bitand.hpp>
25
#include <boost/mpl/int.hpp>
26
#include <boost/mpl/equal_to.hpp>
27
#include <boost/mpl/if.hpp>
28
#include <boost/mpl/eval_if.hpp>
29
#include <boost/mpl/and.hpp>
30
#include <boost/mpl/identity.hpp>
36
template <class Value, class AccessCategory>
37
struct access_archetype;
39
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
40
struct traversal_archetype;
42
namespace iterator_archetypes
45
readable_iterator_bit = 1
46
, writable_iterator_bit = 2
47
, swappable_iterator_bit = 4
48
, lvalue_iterator_bit = 8
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;
56
(readable_iterator_bit|writable_iterator_bit)
57
>::type readable_writable_iterator_t;
60
(readable_iterator_bit|lvalue_iterator_bit)
61
>::type readable_lvalue_iterator_t;
64
(lvalue_iterator_bit|writable_iterator_bit)
65
>::type writable_lvalue_iterator_t;
67
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
68
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
70
template <class Derived, class Base>
73
mpl::bitand_<Derived,Base>
84
assign_proxy& operator=(T) { return *this; }
90
operator T() { return static_object<T>::get(); }
94
struct read_write_proxy
95
: read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
97
read_write_proxy& operator=(T) { return *this; }
103
T const* operator->() const { return 0; }
106
struct no_operator_brackets {};
108
template <class ValueType>
109
struct readable_operator_brackets
111
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
114
template <class ValueType>
115
struct writable_operator_brackets
117
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
120
template <class Value, class AccessCategory, class TraversalCategory>
121
struct operator_brackets
122
: mpl::aux::msvc_eti_base<
123
typename mpl::eval_if<
124
is_convertible<TraversalCategory, random_access_traversal_tag>
126
iterator_archetypes::has_access<
128
, iterator_archetypes::writable_iterator_t
130
, mpl::identity<writable_operator_brackets<Value> >
132
iterator_archetypes::has_access<
134
, iterator_archetypes::readable_iterator_t
136
, readable_operator_brackets<Value>
137
, no_operator_brackets
140
, mpl::identity<no_operator_brackets>
145
template <class TraversalCategory>
146
struct traversal_archetype_impl
148
template <class Derived,class Value> struct archetype;
151
// Constructor argument for those iterators that
152
// are not default constructible
155
template <class Derived, class Value, class TraversalCategory>
156
struct traversal_archetype_
157
: mpl::aux::msvc_eti_base<
158
typename traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
162
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
165
traversal_archetype_() {}
167
traversal_archetype_(ctor_arg arg)
173
struct traversal_archetype_impl<incrementable_traversal_tag>
175
template<class Derived, class Value>
178
explicit archetype(ctor_arg) {}
180
struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
181
typedef bogus difference_type;
183
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
184
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
189
struct traversal_archetype_impl<single_pass_traversal_tag>
191
template<class Derived, class Value>
193
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
194
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
196
explicit archetype(ctor_arg arg)
197
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
200
typedef std::ptrdiff_t difference_type;
204
template <class Derived, class Value>
205
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
206
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
208
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
209
// doesn't seem to pick up != from equality_comparable
210
template <class Derived, class Value>
211
bool operator!=(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
212
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
215
struct traversal_archetype_impl<forward_traversal_tag>
217
template<class Derived, class Value>
219
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
222
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
228
struct traversal_archetype_impl<bidirectional_traversal_tag>
230
template<class Derived, class Value>
232
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
234
Derived& operator--() { return static_object<Derived>::get(); }
235
Derived operator--(int) const { return static_object<Derived>::get(); }
240
struct traversal_archetype_impl<random_access_traversal_tag>
242
template<class Derived, class Value>
244
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
246
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
247
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
251
template <class Derived, class Value>
252
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
253
std::ptrdiff_t) { return static_object<Derived>::get(); }
255
template <class Derived, class Value>
256
Derived& operator+(std::ptrdiff_t,
257
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
258
{ return static_object<Derived>::get(); }
260
template <class Derived, class Value>
261
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
263
{ return static_object<Derived>::get(); }
265
template <class Derived, class Value>
266
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
267
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
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&)
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&)
280
template <class Derived, class Value>
281
bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
282
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
285
template <class Derived, class Value>
286
bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
287
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
292
template <class Value>
293
struct convertible_type
294
: mpl::if_< is_const<Value>,
295
typename remove_const<Value>::type,
299
} // namespace detail
302
template <class> struct undefined;
304
template <class AccessCategory>
305
struct iterator_access_archetype_impl
307
template <class Value> struct archetype;
310
template <class Value, class AccessCategory>
311
struct iterator_access_archetype
312
: mpl::aux::msvc_eti_base<
313
typename iterator_access_archetype_impl<
315
>::template archetype<Value>
321
struct iterator_access_archetype_impl<
322
iterator_archetypes::readable_iterator_t
325
template <class Value>
328
typedef typename remove_cv<Value>::type value_type;
329
typedef Value reference;
330
typedef Value* pointer;
332
value_type operator*() const { return static_object<value_type>::get(); }
334
detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
339
struct iterator_access_archetype_impl<
340
iterator_archetypes::writable_iterator_t
343
template <class Value>
346
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
347
BOOST_STATIC_ASSERT(!is_const<Value>::value);
349
typedef void value_type;
350
typedef void reference;
351
typedef void pointer;
353
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
358
struct iterator_access_archetype_impl<
359
iterator_archetypes::readable_writable_iterator_t
362
template <class Value>
364
: public virtual iterator_access_archetype<
365
Value, iterator_archetypes::readable_iterator_t
368
typedef detail::read_write_proxy<Value> reference;
370
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
375
struct iterator_access_archetype_impl<iterator_archetypes::readable_lvalue_iterator_t>
377
template <class Value>
379
: public virtual iterator_access_archetype<
380
Value, iterator_archetypes::readable_iterator_t
383
typedef Value& reference;
385
Value& operator*() const { return static_object<Value>::get(); }
386
Value* operator->() const { return 0; }
391
struct iterator_access_archetype_impl<iterator_archetypes::writable_lvalue_iterator_t>
393
template <class Value>
395
: public virtual iterator_access_archetype<
396
Value, iterator_archetypes::readable_lvalue_iterator_t
399
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
400
BOOST_STATIC_ASSERT((!is_const<Value>::value));
406
template <class Value, class AccessCategory, class TraversalCategory>
407
struct iterator_archetype;
409
template <class Value, class AccessCategory, class TraversalCategory>
410
struct traversal_archetype_base
411
: detail::operator_brackets<
412
typename remove_cv<Value>::type
416
, detail::traversal_archetype_<
417
iterator_archetype<Value, AccessCategory, TraversalCategory>
426
template <class Value, class AccessCategory, class TraversalCategory>
427
struct iterator_archetype_base
428
: iterator_access_archetype<Value, AccessCategory>
429
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
431
typedef iterator_access_archetype<Value, AccessCategory> access;
433
typedef typename detail::facade_iterator_category<
435
, typename mpl::eval_if<
436
iterator_archetypes::has_access<
437
AccessCategory, iterator_archetypes::writable_iterator_t
439
, remove_const<Value>
442
, typename access::reference
443
>::type iterator_category;
445
// Needed for some broken libraries (see below)
446
typedef boost::iterator<
449
, typename traversal_archetype_base<
450
Value, AccessCategory, TraversalCategory
452
, typename access::pointer
453
, typename access::reference
454
> workaround_iterator_base;
458
template <class Value, class AccessCategory, class TraversalCategory>
459
struct iterator_archetype
460
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
462
// These broken libraries require derivation from std::iterator
463
// (or related magic) in order to handle iter_swap and other
464
// iterator operations
465
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
466
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
467
, public detail::iterator_archetype_base<
468
Value, AccessCategory, TraversalCategory
469
>::workaround_iterator_base
472
// Derivation from std::iterator above caused references to nested
473
// types to be ambiguous, so now we have to redeclare them all
475
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
476
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
478
typedef detail::iterator_archetype_base<
479
Value,AccessCategory,TraversalCategory
482
typedef typename base::value_type value_type;
483
typedef typename base::reference reference;
484
typedef typename base::pointer pointer;
485
typedef typename base::difference_type difference_type;
486
typedef typename base::iterator_category iterator_category;
489
iterator_archetype() { }
490
iterator_archetype(iterator_archetype const& x)
491
: detail::iterator_archetype_base<
498
iterator_archetype& operator=(iterator_archetype const&)
502
// Optional conversion from mutable
505
typename detail::convertible_type<Value>::type
507
, TraversalCategory> const&
515
#endif // BOOST_ITERATOR_ARCHETYPES_HPP