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 
44 {
50 };
51 
52 
54 {
59 };
60 
61 
63 {
66 };
67 
68 
70 {
75 };
76 
77 
78 template<typename _type>
80 {
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
100  {
101  switch(op)
102  {
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>
121 {
122 public:
124  typedef typename base::value_type value_type;
125 
126  using base::get_reference;
127 
128  using base::init;
129 
130  static void
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>
153 {
154 public:
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>
169 {
170 public:
172  typedef typename base::value_type value_type;
173 
174  using base::get_reference;
175 
176  using base::init;
177 
178  static void
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;
253 
254  static_assert(is_convertible<decltype(*std::declval<typename
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;
265 
266  reference
267  operator*() const
268  {
269  yassume(manager);
270 
272 
274  return reference(t.access<void_ref>());
275  }
276 
277  pointer
278  operator->() const
279  {
280  return &**this;
281  }
282 
285  {
286  yassume(manager);
287 
289  return *this;
290  }
291 
293  any
294  get() const
295  {
296  return static_cast<const any&>(*this);
297  }
298 
300  bool
302  {
303  if(manager)
304  {
306 
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 
324 
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 
339 
343 
344 
349 template<typename _type, typename _tDifference = ptrdiff_t,
350  typename _tPointer = _type*, typename _tReference = _type&>
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;
366 
369  {
371  return *this;
372  }
374 };
375 
377 
378 YB_ITERATOR_OP2(operator!=, bool, any_forward_iterator, !(x == y))
379 
382 
385 
386 
391 template<typename _type, typename _tDifference = ptrdiff_t,
392  typename _tPointer = _type*, typename _tReference = _type&>
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>
404  : any_input_iterator<_type, _tPointer, _tReference>(yforward(i))
405  {}
408 
411  {
413  return *this;
414  }
416 
418  operator--()
419  {
420  yassume(this->manager);
421 
422  this->manager(this->storage, this->storage, any_ops::decrease);
423  return *this;
424  }
426 };
427 
429 
430 YB_ITERATOR_OP2(operator!=, bool, any_bidirectional_iterator, !(x == y))
431 
434 
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