1 | // (C) Copyright David Abrahams 2002. |
2 | // (C) Copyright Jeremy Siek 2002. |
3 | // (C) Copyright Thomas Witt 2002. |
4 | // Distributed under the Boost Software License, Version 1.0. (See |
5 | // accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | #ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP |
8 | #define BOOST_INDIRECT_ITERATOR_23022003THW_HPP |
9 | |
10 | #include <boost/iterator.hpp> |
11 | #include <boost/iterator/iterator_adaptor.hpp> |
12 | |
13 | #include <boost/pointee.hpp> |
14 | #include <boost/indirect_reference.hpp> |
15 | #include <boost/detail/iterator.hpp> |
16 | |
17 | #include <boost/detail/indirect_traits.hpp> |
18 | |
19 | #include <boost/type_traits/is_same.hpp> |
20 | #include <boost/type_traits/add_reference.hpp> |
21 | |
22 | #include <boost/mpl/bool.hpp> |
23 | #include <boost/mpl/identity.hpp> |
24 | #include <boost/mpl/eval_if.hpp> |
25 | #include <boost/mpl/not.hpp> |
26 | #include <boost/mpl/has_xxx.hpp> |
27 | |
28 | #ifdef BOOST_MPL_CFG_NO_HAS_XXX |
29 | # include <boost/shared_ptr.hpp> |
30 | # include <boost/scoped_ptr.hpp> |
31 | # include <boost/mpl/bool.hpp> |
32 | # include <memory> |
33 | #endif |
34 | |
35 | #include <boost/iterator/detail/config_def.hpp> // must be last #include |
36 | |
37 | namespace boost { |
38 | namespace iterators { |
39 | |
40 | template <class Iter, class Value, class Category, class Reference, class Difference> |
41 | class indirect_iterator; |
42 | |
43 | namespace detail |
44 | { |
45 | template <class Iter, class Value, class Category, class Reference, class Difference> |
46 | struct indirect_base |
47 | { |
48 | typedef typename boost::detail::iterator_traits<Iter>::value_type dereferenceable; |
49 | |
50 | typedef iterator_adaptor< |
51 | indirect_iterator<Iter, Value, Category, Reference, Difference> |
52 | , Iter |
53 | , typename ia_dflt_help< |
54 | Value, pointee<dereferenceable> |
55 | >::type |
56 | , Category |
57 | , typename ia_dflt_help< |
58 | Reference |
59 | , mpl::eval_if< |
60 | is_same<Value,use_default> |
61 | , indirect_reference<dereferenceable> |
62 | , add_reference<Value> |
63 | > |
64 | >::type |
65 | , Difference |
66 | > type; |
67 | }; |
68 | |
69 | template <> |
70 | struct indirect_base<int, int, int, int, int> {}; |
71 | } // namespace detail |
72 | |
73 | |
74 | template < |
75 | class Iterator |
76 | , class Value = use_default |
77 | , class Category = use_default |
78 | , class Reference = use_default |
79 | , class Difference = use_default |
80 | > |
81 | class indirect_iterator |
82 | : public detail::indirect_base< |
83 | Iterator, Value, Category, Reference, Difference |
84 | >::type |
85 | { |
86 | typedef typename detail::indirect_base< |
87 | Iterator, Value, Category, Reference, Difference |
88 | >::type super_t; |
89 | |
90 | friend class iterator_core_access; |
91 | |
92 | public: |
93 | indirect_iterator() {} |
94 | |
95 | indirect_iterator(Iterator iter) |
96 | : super_t(iter) {} |
97 | |
98 | template < |
99 | class Iterator2, class Value2, class Category2 |
100 | , class Reference2, class Difference2 |
101 | > |
102 | indirect_iterator( |
103 | indirect_iterator< |
104 | Iterator2, Value2, Category2, Reference2, Difference2 |
105 | > const& y |
106 | , typename enable_if_convertible<Iterator2, Iterator>::type* = 0 |
107 | ) |
108 | : super_t(y.base()) |
109 | {} |
110 | |
111 | private: |
112 | typename super_t::reference dereference() const |
113 | { |
114 | # if BOOST_WORKAROUND(__BORLANDC__, < 0x5A0 ) |
115 | return const_cast<super_t::reference>(**this->base()); |
116 | # else |
117 | return **this->base(); |
118 | # endif |
119 | } |
120 | }; |
121 | |
122 | template <class Iter> |
123 | inline |
124 | indirect_iterator<Iter> make_indirect_iterator(Iter x) |
125 | { |
126 | return indirect_iterator<Iter>(x); |
127 | } |
128 | |
129 | template <class Traits, class Iter> |
130 | inline |
131 | indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0) |
132 | { |
133 | return indirect_iterator<Iter, Traits>(x); |
134 | } |
135 | |
136 | } // namespace iterators |
137 | |
138 | using iterators::indirect_iterator; |
139 | using iterators::make_indirect_iterator; |
140 | |
141 | } // namespace boost |
142 | |
143 | #include <boost/iterator/detail/config_undef.hpp> |
144 | |
145 | #endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP |
146 | |