Line data Source code
1 : // file : xsd/cxx/tree/iterator-adapter.hxx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : #ifndef XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
6 : #define XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
7 :
8 : #include <cstddef> // std::ptrdiff_t
9 : #include <iterator> // std::iterator_traits
10 :
11 : namespace xsd
12 : {
13 : namespace cxx
14 : {
15 : namespace tree
16 : {
17 : // Sun CC's <iterator> does not have iterator_traits. To overcome
18 : // this, we will wrap std::iterator_traits into our own and also
19 : // specialize it for pointer types. Since Sun CC uses pointer
20 : // for vector::iterator, it will use the specialization and won't
21 : // notice the std::iterator_traits.
22 : //
23 : #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
24 : template <typename I>
25 : struct iterator_traits
26 : {
27 : typedef
28 : typename std::iterator_traits<I>::iterator_category
29 : iterator_category;
30 :
31 : typedef
32 : typename std::iterator_traits<I>::value_type
33 : value_type;
34 :
35 : typedef
36 : typename std::iterator_traits<I>::difference_type
37 : difference_type;
38 : };
39 : #else
40 : // The Pointer specialization does not work for reverse and
41 : // set iterators. But these iterators are user-dfined types
42 : // and have suitable typedefs that we can use.
43 : //
44 : template <typename I>
45 : struct iterator_traits
46 : {
47 : typedef typename I::iterator_category iterator_category;
48 : typedef typename I::value_type value_type;
49 : typedef typename I::difference_type difference_type;
50 : };
51 :
52 : template <typename T>
53 : struct iterator_traits<T*>
54 : {
55 : typedef std::random_access_iterator_tag iterator_category;
56 : typedef T value_type;
57 : typedef std::ptrdiff_t difference_type;
58 : };
59 : #endif
60 :
61 : // Iterator adapter for complex types. It expects I to point to
62 : // a smart pointer-like object that has operator*() that returns
63 : // a refernce to a type static_cast'able to T and get() that
64 : // returns a pointer to a type static_cast'able to T.
65 : //
66 :
67 : template <typename I, typename T>
68 : struct iterator_adapter
69 : {
70 : typedef T value_type;
71 : typedef value_type& reference;
72 : typedef value_type* pointer;
73 :
74 : typedef
75 : typename iterator_traits<I>::iterator_category
76 : iterator_category;
77 :
78 : typedef
79 : typename iterator_traits<I>::difference_type
80 : difference_type;
81 :
82 :
83 : public:
84 : iterator_adapter ()
85 : : i_ () // i_ can be of a pointer type.
86 : {
87 : }
88 :
89 : // Allow iterator to const_iterator conversion.
90 : //
91 : template <typename J, typename T2>
92 : iterator_adapter (const iterator_adapter<J, T2>& j)
93 : : i_ (j.base ())
94 : {
95 : }
96 :
97 : explicit
98 0 : iterator_adapter (const I& i)
99 0 : : i_ (i)
100 : {
101 0 : }
102 :
103 : public:
104 : // Forward iterator requirements.
105 : //
106 : reference
107 0 : operator* () const
108 : {
109 0 : return static_cast<reference> (**i_);
110 : }
111 :
112 : pointer
113 : operator-> () const
114 : {
115 : return static_cast<pointer> (i_->get ());
116 : }
117 :
118 : iterator_adapter&
119 0 : operator++ ()
120 : {
121 0 : ++i_;
122 0 : return *this;
123 : }
124 :
125 : iterator_adapter
126 : operator++ (int)
127 : {
128 : iterator_adapter r (*this);
129 : ++i_;
130 : return r;
131 : }
132 :
133 : // Bidirectional iterator requirements.
134 : //
135 : iterator_adapter&
136 : operator-- ()
137 : {
138 : --i_;
139 : return *this;
140 : }
141 :
142 : iterator_adapter
143 : operator-- (int)
144 : {
145 : iterator_adapter r (*this);
146 : --i_;
147 : return r;
148 : }
149 :
150 : // Random access iterator requirements.
151 : //
152 : reference
153 : operator[] (difference_type n) const
154 : {
155 : return static_cast<reference> (*(i_[n]));
156 : }
157 :
158 : iterator_adapter&
159 : operator+= (difference_type n)
160 : {
161 : i_ += n;
162 : return *this;
163 : }
164 :
165 : iterator_adapter
166 : operator+ (difference_type n) const
167 : {
168 : return iterator_adapter (i_ + n);
169 : }
170 :
171 : iterator_adapter&
172 : operator-= (difference_type n)
173 : {
174 : i_ -= n;
175 : return *this;
176 : }
177 :
178 : iterator_adapter
179 : operator- (difference_type n) const
180 : {
181 : return iterator_adapter (i_ - n);
182 : }
183 :
184 : public:
185 : const I&
186 0 : base () const
187 : {
188 0 : return i_;
189 : }
190 :
191 : private:
192 : I i_;
193 : };
194 :
195 : // Note: We use different types for left- and right-hand-side
196 : // arguments to allow comparison between iterator and const_iterator.
197 : //
198 :
199 : // Forward iterator requirements.
200 : //
201 : template <typename I, typename J, typename T1, typename T2>
202 : inline bool
203 : operator== (const iterator_adapter<I, T1>& i,
204 : const iterator_adapter<J, T2>& j)
205 : {
206 : return i.base () == j.base ();
207 : }
208 :
209 : template <typename I, typename J, typename T1, typename T2>
210 : inline bool
211 0 : operator!= (const iterator_adapter<I, T1>& i,
212 : const iterator_adapter<J, T2>& j)
213 : {
214 0 : return i.base () != j.base ();
215 : }
216 :
217 : // Random access iterator requirements
218 : //
219 : template <typename I, typename J, typename T1, typename T2>
220 : inline bool
221 : operator< (const iterator_adapter<I, T1>& i,
222 : const iterator_adapter<J, T2>& j)
223 : {
224 : return i.base () < j.base ();
225 : }
226 :
227 : template <typename I, typename J, typename T1, typename T2>
228 : inline bool
229 : operator> (const iterator_adapter<I, T1>& i,
230 : const iterator_adapter<J, T2>& j)
231 : {
232 : return i.base () > j.base ();
233 : }
234 :
235 : template <typename I, typename J, typename T1, typename T2>
236 : inline bool
237 : operator<= (const iterator_adapter<I, T1>& i,
238 : const iterator_adapter<J, T2>& j)
239 : {
240 : return i.base () <= j.base ();
241 : }
242 :
243 : template <typename I, typename J, typename T1, typename T2>
244 : inline bool
245 : operator>= (const iterator_adapter<I, T1>& i,
246 : const iterator_adapter<J, T2>& j)
247 : {
248 : return i.base () >= j.base ();
249 : }
250 :
251 : template <typename I, typename J, typename T1, typename T2>
252 : inline typename iterator_adapter<I, T1>::difference_type
253 : operator- (const iterator_adapter<I, T1>& i,
254 : const iterator_adapter<J, T2>& j)
255 : {
256 : return i.base () - j.base ();
257 : }
258 :
259 : template <typename I, typename T>
260 : inline iterator_adapter<I, T>
261 : operator+ (typename iterator_adapter<I, T>::difference_type n,
262 : const iterator_adapter<I, T>& i)
263 : {
264 : return iterator_adapter<I, T> (i.base () + n);
265 : }
266 : }
267 : }
268 : }
269 :
270 : #endif // XSD_CXX_TREE_ITERATOR_ADAPTER_HXX
|