YSTest: any_iterator.hpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
any_iterator.hpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2012 - 2013.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_ystdex_any_iterator_hpp_
29 #define YB_INC_ystdex_any_iterator_hpp_ 1
30
31 #include "any.h"
32 #include "cast.hpp" // for ystdex::polymorphic_downcast;
33 #include "memory.hpp" // for ystdex::is_undereferenceable;
34
35 namespace ystdex
36 {
37
38 namespace any_ops
39 {
40
42
43 enum iterator_op : op_code
44 {
46 check_undereferenceable = end_base_op,
47 dereference,
48 increase,
49 end_iterator_op
50 };
51
52
53 enum input_iterator_op : op_code
54 {
55 equals = end_iterator_op,
56 end_input_iterator_op,
57 end_output_iterator_op = end_input_iterator_op,
58 end_forward_iterator_op = end_input_iterator_op
59 };
60
61
62 enum bidirectional_iteartor_op : op_code
63 {
64 decrease = end_forward_iterator_op,
65 end_bidirectional_iterator_op
66 };
67
68
69 enum random_access_iteartor_op : op_code
70 {
71 advance = end_forward_iterator_op,
72 distance,
73 less_compare,
74 end_random_access_iteartor_op
75 };
76
77
78 template<typename _type>
79 struct wrap_handler
80 {
81 typedef typename wrapped_traits<_type>::type value_type;
82 typedef typename conditional<wrapped_traits<_type>::value,
83 ref_handler<value_type>, value_handler<value_type>>::type type;
84 };
85
86
87 template<typename _type>
88 class iterator_handler : public wrap_handler<_type>::type
89 {
90 public:
91 typedef typename wrap_handler<_type>::type base;
92 typedef typename base::value_type value_type;
93
94 using base::get_reference;
95
96 using base::init;
97
98 static void
99 manage(any_storage& d, const any_storage& s, any_ops::op_code op)
100 {
101 switch(op)
102 {
103 case check_undereferenceable:
104 d.access<bool>() = is_undereferenceable(get_reference(s));
105 break;
106 case dereference:
107 d = void_ref(*get_reference(s));
108 break;
109 case increase:
110 ++get_reference(d);
111 break;
112 default:
113 base::manage(d, s, op);
114 }
115 }
116 };
117
118
119 template<typename _type>
120 class input_iterator_handler : public iterator_handler<_type>
121 {
122 public:
123 typedef iterator_handler<_type> base;
124 typedef typename base::value_type value_type;
125
126 using base::get_reference;
127
128 using base::init;
129
130 static void
131 manage(any_storage& d, const any_storage& s, any_ops::op_code op)
132 {
133 switch(op)
134 {
135 case equals:
136 {
137 const auto p(d.access<any_storage*>());
138
139 d.access<bool>() = get_reference(*p) == get_reference(s);
140 }
141 break;
142 default:
143 base::manage(d, s, op);
144 }
145 }
146 };
148
149
151 template<typename _type>
152 class forward_iterator_handler : public input_iterator_handler<_type>
153 {
154 public:
155 typedef input_iterator_handler<_type> base;
156 typedef typename base::value_type value_type;
157
158 using base::get_reference;
159
160 using base::init;
161
162 using base::manage;
163 };
164
165
167 template<typename _type>
168 class bidirectional_iterator_handler : public forward_iterator_handler<_type>
169 {
170 public:
171 typedef forward_iterator_handler<_type> base;
172 typedef typename base::value_type value_type;
173
174 using base::get_reference;
175
176 using base::init;
177
178 static void
179 manage(any_storage& d, const any_storage& s, any_ops::op_code op)
180 {
181 switch(op)
182 {
183 case decrease:
184 --get_reference(d);
185 break;
186 default:
187 base::manage(d, s, op);
188 }
189 }
190 };
191
192 } // namespace any_ops;
193
194
196
197
198 #define YB_ITERATOR_OP1(_n, _t, _it, _e) \
199 template<typename _type, typename _tDifference, typename _tPointer, \
200 typename _tReference> \
201 inline _t \
202 _n(const _it<_type, _tDifference, _tPointer, _tReference>& i) \
203 { \
204 return _e; \
205 }
206
207 #define YB_ITERATOR_OP2(_n, _t, _it, _e) \
208 template<typename _type, typename _tDifference, typename _tPointer, \
209 typename _tReference> \
210 inline _t \
211 _n(const _it<_type, _tDifference, _tPointer, _tReference>& x, \
212 const _it<_type, _tDifference, _tPointer, _tReference>& y) \
213 { \
214 return _e; \
215 }
216
217 #define YB_ITERATOR_MEMBER_POSTFIX(_op, _it) \
218 _it \
219 operator _op(int) \
220 { \
221 auto tmp = *this; \
222 \
223 _op *this; \
224 return tmp; \
225 }
226
227
232 template<typename _type, typename _tDifference = ptrdiff_t,
233 typename _tPointer = _type*, typename _tReference = _type&>
234 class any_input_iterator : public std::iterator<std::input_iterator_tag, _type,
235 _tDifference, _tPointer, _tReference>, protected any
236 {
237 public:
238 typedef _tPointer pointer;
239 typedef _tReference reference;
240
242 any_input_iterator() = default;
247 template<typename _tIterator>
248 any_input_iterator(_tIterator&& i)
249 : any()
250 {
251 typedef typename remove_rcv<_tIterator>::type param_obj_type;
252 typedef any_ops::input_iterator_handler<param_obj_type> handler;
253
254 static_assert(is_convertible<decltype(*std::declval<typename
255 wrapped_traits<param_obj_type>::type&>()), reference>::value,
256 "Wrong target iterator type found.");
257
258 manager = handler::manage;
259 handler::init(storage, yforward(i));
260 }
262 any_input_iterator(const any_input_iterator&) = default;
264 any_input_iterator(any_input_iterator&&) = default;
265
266 reference
267 operator*() const
268 {
269 yassume(manager);
270
271 any_ops::any_storage t;
272
273 manager(t, storage, any_ops::dereference);
274 return reference(t.access<void_ref>());
275 }
276
277 pointer
278 operator->() const
279 {
280 return &**this;
281 }
282
283 any_input_iterator&
284 operator++()
285 {
286 yassume(manager);
287
288 manager(storage, storage, any_ops::increase);
289 return *this;
290 }
291
293 any
294 get() const
295 {
296 return static_cast<const any&>(*this);
297 }
298
300 bool
301 check_undereferenceable() const
302 {
303 if(manager)
304 {
305 any_ops::any_storage t;
306
307 manager(t, storage, any_ops::check_undereferenceable);
308 return t.access<bool>();
309 }
310 return true;
311 }
312
314
315 bool
316 equals(const any_input_iterator& i) const
317 {
318 if(!*this && !i)
319 return true;
320
321 yassume(type() == i.type());
322
323 any_ops::any_storage t(&storage);
324
325 manager(t, i.storage, any_ops::equals);
326 return t.access<bool>();
327 }
328
329 using any::type;
331 };
332
333 YB_ITERATOR_OP2(operator==, bool, any_input_iterator, x.equals(y))
334
335 YB_ITERATOR_OP2(operator!=, bool, any_input_iterator, !(x == y))
336
337 YB_ITERATOR_OP1(is_undereferenceable, bool, any_input_iterator,
338 i.check_undereferenceable())
339
340 typedef any_input_iterator<void_ref, ptrdiff_t, void*, void_ref>
341 input_monomorphic_iterator;
343
344
349 template<typename _type, typename _tDifference = ptrdiff_t,
350 typename _tPointer = _type*, typename _tReference = _type&>
351 class any_forward_iterator
352 : public any_input_iterator<_type, _tDifference, _tPointer, _tReference>
353 {
354 public:
355 typedef std::forward_iterator_tag iterator_category;
356 typedef _tPointer pointer;
357 typedef _tReference reference;
358
359 any_forward_iterator() = default;
360 template<typename _tIterator>
361 any_forward_iterator(_tIterator&& i)
362 : any_input_iterator<_type, _tPointer, _tReference>(yforward(i))
363 {}
364 any_forward_iterator(const any_forward_iterator&) = default;
365 any_forward_iterator(any_forward_iterator&&) = default;
366
367 any_forward_iterator&
368 operator++()
369 {
370 any_input_iterator<_type, _tPointer, _tReference>::operator++();
371 return *this;
372 }
373 YB_ITERATOR_MEMBER_POSTFIX(++, any_forward_iterator)
374 };
375
376 YB_ITERATOR_OP2(operator==, bool, any_forward_iterator, x.equals(y))
377
378 YB_ITERATOR_OP2(operator!=, bool, any_forward_iterator, !(x == y))
379
380 YB_ITERATOR_OP1(is_undereferenceable, bool, any_forward_iterator,
381 i.check_undereferenceable())
382
383 typedef any_forward_iterator<void_ref, ptrdiff_t, void*, void_ref>
384 forward_monomorphic_iterator;
385
386
391 template<typename _type, typename _tDifference = ptrdiff_t,
392 typename _tPointer = _type*, typename _tReference = _type&>
393 class any_bidirectional_iterator
394 : public any_forward_iterator<_type, _tDifference, _tPointer, _tReference>
395 {
396 public:
397 typedef std::bidirectional_iterator_tag iterator_category;
398 typedef _tPointer pointer;
399 typedef _tReference reference;
400
401 any_bidirectional_iterator() = default;
402 template<typename _tIterator>
403 any_bidirectional_iterator(_tIterator&& i)
404 : any_input_iterator<_type, _tPointer, _tReference>(yforward(i))
405 {}
406 any_bidirectional_iterator(const any_bidirectional_iterator&) = default;
407 any_bidirectional_iterator(any_bidirectional_iterator&&) = default;
408
409 any_bidirectional_iterator&
410 operator++()
411 {
412 any_forward_iterator<_type, _tPointer, _tReference>::operator++();
413 return *this;
414 }
415 YB_ITERATOR_MEMBER_POSTFIX(++, any_bidirectional_iterator)
416
417 any_bidirectional_iterator&
418 operator--()
419 {
420 yassume(this->manager);
421
422 this->manager(this->storage, this->storage, any_ops::decrease);
423 return *this;
424 }
425 YB_ITERATOR_MEMBER_POSTFIX(--, any_bidirectional_iterator)
426 };
427
428 YB_ITERATOR_OP2(operator==, bool, any_bidirectional_iterator, x.equals(y))
429
430 YB_ITERATOR_OP2(operator!=, bool, any_bidirectional_iterator, !(x == y))
431
432 YB_ITERATOR_OP1(is_undereferenceable, bool, any_bidirectional_iterator,
433 i.check_undereferenceable())
434
435 typedef any_bidirectional_iterator<void_ref, ptrdiff_t, void*, void_ref>
436 bidirectional_monomorphic_iterator;
437
438
439 #undef YB_ITERATOR_OP1
440 #undef YB_ITERATOR_OP2
441 #undef YB_ITERATOR_MEMBER_POSTFIX
442
444
445 } // namespace ystdex;
446
447 #endif
448