OGLplus (0.52.0) a C++ wrapper for OpenGL

ranges.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_OPT_RANGE_HPP
14 #define OGLPLUS_OPT_RANGE_HPP
15 
16 #include <oglplus/config/basic.hpp>
17 #include <oglplus/detail/base_range.hpp>
18 
19 namespace oglplus {
20 
34 #if OGLPLUS_DOCUMENTATION_ONLY
35 
39 class Range
40 {
41 public:
43  typedef const Unspecified ValueType;
44 
46  Range(const Range&);
47 
49  bool Empty(void) const;
50 
52  size_t Size(void) const;
53 
55 
61  void Next(void);
62 
64 
70  ValueType Front(void);
71 };
72 #endif
73 
75 namespace ranges {
76 
78 
81 template <typename Range>
82 struct IsRange
83 {
84  typedef decltype(oglplus::aux::IsRange((Range*)nullptr)) Type;
85 };
86 
87 
89 
92 template <typename Element>
93 class AnyRange
94 {
95 private:
96  struct _intf
97  {
98  virtual ~_intf(void){ }
99 
100  virtual _intf* _clone(void) const = 0;
101 
102  virtual bool _empty(void) const = 0;
103  virtual size_t _size(void) const = 0;
104  virtual void _next(void) = 0;
105  virtual Element _front(void) const = 0;
106  };
107 
108  template <class Rng>
109  class _impl : public _intf
110  {
111  private:
112  static_assert(IsRange<Rng>::Type::value, "Range is expected");
113  Rng _rng;
114  public:
115  _impl(Rng rng)
116  : _rng(rng)
117  { }
118 
119  _intf* _clone(void) const
120  {
121  return new _impl(*this);
122  }
123 
124  bool _empty(void) const
125  {
126  return _rng.Empty();
127  }
128 
129  size_t _size(void) const
130  {
131  return _rng.Size();
132  }
133 
134  void _next(void)
135  {
136  _rng.Next();
137  }
138 
139  Element _front(void) const
140  {
141  return _rng.Front();
142  }
143  };
144 
145  _intf* _pimpl;
146 
147  static _intf* _clone(_intf* pimpl)
148  {
149  assert(pimpl);
150  return pimpl->_clone();
151  }
152 public:
153  typedef Element ValueType;
154 
155  AnyRange(void)
156  : _pimpl(nullptr)
157  { }
158 
159  template <typename Range>
160  AnyRange(Range range)
161  : _pimpl(new _impl<Range>(range))
162  { }
163 
164  AnyRange(const AnyRange& other)
165  : _pimpl(_clone(other._pimpl))
166  { }
167 
168  AnyRange(AnyRange&& temp)
169  : _pimpl(temp._pimpl)
170  {
171  temp._pimpl = nullptr;
172  }
173 
174  ~AnyRange(void)
175  {
176  if(_pimpl) delete _pimpl;
177  }
178 
179  template <typename Range>
180  AnyRange& operator = (const Range& range)
181  {
182  if(_pimpl) delete _pimpl;
183  _pimpl = new _impl<Range>(range);
184  return *this;
185  }
186 
187  AnyRange& operator = (const AnyRange& other)
188  {
189  if(_pimpl) delete _pimpl;
190  _pimpl = _clone(other._pimpl);
191  return *this;
192  }
193 
194  AnyRange& operator = (AnyRange&& other)
195  {
196  if(_pimpl) delete _pimpl;
197  _pimpl = other._pimpl;
198  other._pimpl = nullptr;
199  return *this;
200  }
201 
203  bool Empty(void) const
204  {
205  if(!_pimpl) return true;
206  return _pimpl->_empty();
207  }
208 
210  size_t Size(void) const
211  {
212  if(!_pimpl) return 0;
213  return _pimpl->_size();
214  }
215 
217  void Next(void)
218  {
219  assert(!Empty());
220  _pimpl->_next();
221  }
222 
224  ValueType Front(void) const
225  {
226  assert(!Empty());
227  return _pimpl->_front();
228  }
229 };
230 
231 template <typename Range>
232 inline AnyRange<typename Range::ValueType> EraseType(Range range)
233 {
234  return AnyRange<typename Range::ValueType>(range);
235 }
236 
238 
241 template <typename Range, typename Func>
242 inline Func ForEach(Range range, Func func)
243 {
244  static_assert(
246  "A Range is expected as the first argument"
247  );
248  while(!range.Empty())
249  {
250  func(range.Front());
251  range.Next();
252  }
253  return func;
254 }
255 
257 
264 template <typename Range>
265 inline Range Find(Range range, typename Range::ValueType value)
266 {
267  static_assert(
269  "A Range is expected as the first argument"
270  );
271  while(!range.Empty())
272  {
273  if(range.Front() == value) break;
274  range.Next();
275  }
276  return range;
277 }
278 
279 template <typename Range>
280 inline bool Contains(Range range, typename Range::ValueType value)
281 {
282  static_assert(
283  IsRange<Range>::Type::value,
284  "A Range is expected as the first argument"
285  );
286  while(!range.Empty())
287  {
288  if(range.Front() == value) return true;
289  range.Next();
290  }
291  return false;
292 }
293 
294 template <typename Range, typename Predicate>
295 inline Range& AdvanceUntil(Range& range, Predicate predicate)
296 {
297  static_assert(
298  IsRange<Range>::Type::value,
299  "A Range is expected as the first argument"
300  );
301  while(!range.Empty())
302  {
303  if(predicate(range.Front())) break;
304  range.Next();
305  }
306  return range;
307 }
308 
309 template <typename Range, typename Predicate>
310 inline std::size_t CountIf(Range range, Predicate predicate)
311 {
312  static_assert(
313  IsRange<Range>::Type::value,
314  "A Range is expected as the first argument"
315  );
316  std::size_t result = 0;
317  while(!range.Empty())
318  {
319  if(predicate(range.Front())) ++result;
320  range.Next();
321  }
322  return result;
323 }
324 
326 
333 template <typename Range, typename Predicate>
334 inline Range FindIf(Range range, Predicate predicate)
335 {
336  return AdvanceUntil(range, predicate);
337 }
338 
339 template <typename Range, typename Predicate>
340 inline bool Has(Range range, Predicate predicate)
341 {
342  return !AdvanceUntil(range, predicate).Empty();
343 }
344 
345 template <typename Range, typename Transf>
346 class Transformed
347 {
348 private:
349  Range _range;
350  Transf _transf;
351 public:
352  typedef decltype(std::declval<Transf>()(
353  std::declval<typename Range::ValueType>())
354  ) ValueType;
355 
356  Transformed(Range range, Transf transf)
357  : _range(range)
358  , _transf(transf)
359  { }
360 
361  bool Empty(void) const
362  {
363  return _range.Empty();
364  }
365 
366  size_t Size(void) const
367  {
368  return _range.Size();
369  }
370 
371  void Next(void)
372  {
373  _range.Next();
374  }
375 
376  ValueType Front(void) const
377  {
378  return _transf(_range.Front());
379  }
380 };
381 
383 
388 template <typename Range, typename Transf>
389 inline Transformed<Range, Transf> Transform(Range range, Transf transf)
390 {
391  static_assert(
393  "A Range is expected as the first argument"
394  );
395  return Transformed<Range, Transf>(range, transf);
396 }
397 
399 
413 template <typename Range, typename State, typename Op>
414 inline State Fold(Range range, State state, Op op)
415 {
416  static_assert(
418  "A Range is expected as the first argument"
419  );
420  while(!range.Empty())
421  {
422  state = op(state, range.Front());
423  range.Next();
424  }
425  return state;
426 }
427 
428 
429 template <typename Range, typename Predicate>
430 class Filtered
431 {
432 private:
433  Range _range;
434  Predicate _pred;
435 public:
436  typedef typename Range::ValueType ValueType;
437 
438  Filtered(Range range, Predicate pred)
439  : _range(range)
440  , _pred(pred)
441  {
442  oglplus::ranges::AdvanceUntil(_range, _pred);
443  }
444 
445  bool Empty(void) const
446  {
447  return _range.Empty();
448  }
449 
450  size_t Size(void) const
451  {
452  return CountIf(*this, _pred);
453  }
454 
455  void Next(void)
456  {
457  _range.Next();
458  oglplus::ranges::AdvanceUntil(_range, _pred);
459  }
460 
461  ValueType Front(void) const
462  {
463  return _range.Front();
464  }
465 };
466 
468 
473 template <typename Range, typename Predicate>
474 inline Filtered<Range, Predicate> OnlyIf(Range range, Predicate pred)
475 {
476  static_assert(
478  "A Range is expected as the first argument"
479  );
480  return Filtered<Range, Predicate>(range, pred);
481 }
482 
483 template <typename Element, typename R1, typename R2>
484 class Concatenated
485 {
486 private:
487  R1 _r1;
488  R2 _r2;
489 public:
490  typedef Element ValueType;
491 
492  Concatenated(R1 r1, R2 r2)
493  : _r1(r1)
494  , _r2(r2)
495  { }
496 
497  bool Empty(void) const
498  {
499  return _r1.Empty() && _r2.Empty();
500  }
501 
502  size_t Size(void) const
503  {
504  return _r1.Size() + _r2.Size();
505  }
506 
507  void Next(void)
508  {
509  if(!_r1.Empty())
510  _r1.Next();
511  else if(!_r2.Empty())
512  _r2.Next();
513  else assert(!Empty());
514  }
515 
516  ValueType Front(void) const
517  {
518  if(!_r1.Empty())
519  return ValueType(_r1.Front());
520  else if(!_r2.Empty())
521  return ValueType(_r2.Front());
522  else assert(!Empty());
523  return *((ValueType*)nullptr);
524  }
525 };
526 
527 template <typename Element, typename R1, typename R2>
528 inline Concatenated<Element, R1, R2> Concatenate(R1 r1, R2 r2)
529 {
530  static_assert(
531  IsRange<R1>::Type::value,
532  "A Range is expected as the first argument"
533  );
534  static_assert(
535  IsRange<R2>::Type::value,
536  "A Range is expected as the second argument"
537  );
538  return Concatenated<Element, R1, R2>(r1, r2);
539 }
540 
541 } // namespace ranges
542 } // namespace oglplus
543 
544 #endif // include guard
void Next(void)
Goes to the next element in the range.
Wrapper class for all ranges that can be used for Element traversal.
Definition: ranges.hpp:39
bool Empty(void) const
Returns true if the range is empty.
Definition: ranges.hpp:203
A type erasure for types conforming to the oglplus::Range concept.
Definition: ranges.hpp:93
ValueType Front(void) const
Returns the element at the front of the range.
Definition: ranges.hpp:224
Func ForEach(Range range, Func func)
Executes a functor on every element in a range.
Definition: ranges.hpp:242
Filtered< Range, Predicate > OnlyIf(Range range, Predicate pred)
Returns a range containing only elements satisfying a predicate.
Definition: ranges.hpp:474
size_t Size(void) const
Returns the number of Elements in the range.
bool Empty(void) const
Returns true if the range is empty.
size_t Size(void) const
Returns the number of Elements in the range.
Definition: ranges.hpp:210
const Unspecified ValueType
The type of value returned by Front.
Definition: ranges.hpp:43
Metafunction for checking if a type conforms to the oglplus::Range concept.
Definition: ranges.hpp:82
Range FindIf(Range range, Predicate predicate)
Finds the first a value satisfying a predicate in a range.
Definition: ranges.hpp:334
Range(const Range &)
Copy constructor.
Transformed< Range, Transf > Transform(Range range, Transf transf)
Transforms a range by an unary function.
Definition: ranges.hpp:389
Unspecified internal type.
Definition: doc.hpp:364
void Next(void)
Goes to the next element in the range.
Definition: ranges.hpp:217
ValueType Front(void)
Returns the element at the front of the range.
State Fold(Range range, State state, Op op)
Folds the range by using a binary functor and a state value.
Definition: ranges.hpp:414
Range Find(Range range, typename Range::ValueType value)
Finds the specified value in a range.
Definition: ranges.hpp:265

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).