13 #ifndef OGLPLUS_OPT_RANGE_HPP
14 #define OGLPLUS_OPT_RANGE_HPP
16 #include <oglplus/config/basic.hpp>
17 #include <oglplus/detail/base_range.hpp>
34 #if OGLPLUS_DOCUMENTATION_ONLY
49 bool Empty(
void)
const;
52 size_t Size(
void)
const;
81 template <
typename Range>
84 typedef decltype(oglplus::aux::IsRange((
Range*)
nullptr)) Type;
92 template <
typename Element>
98 virtual ~_intf(
void){ }
100 virtual _intf* _clone(
void)
const = 0;
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;
109 class _impl :
public _intf
119 _intf* _clone(
void)
const
121 return new _impl(*
this);
124 bool _empty(
void)
const
129 size_t _size(
void)
const
139 Element _front(
void)
const
147 static _intf* _clone(_intf* pimpl)
150 return pimpl->_clone();
153 typedef Element ValueType;
159 template <
typename Range>
161 : _pimpl(
new _impl<Range>(range))
165 : _pimpl(_clone(other._pimpl))
169 : _pimpl(temp._pimpl)
171 temp._pimpl =
nullptr;
176 if(_pimpl)
delete _pimpl;
179 template <
typename Range>
182 if(_pimpl)
delete _pimpl;
183 _pimpl =
new _impl<Range>(range);
189 if(_pimpl)
delete _pimpl;
190 _pimpl = _clone(other._pimpl);
196 if(_pimpl)
delete _pimpl;
197 _pimpl = other._pimpl;
198 other._pimpl =
nullptr;
205 if(!_pimpl)
return true;
206 return _pimpl->_empty();
212 if(!_pimpl)
return 0;
213 return _pimpl->_size();
227 return _pimpl->_front();
231 template <
typename Range>
232 inline AnyRange<typename Range::ValueType> EraseType(
Range range)
234 return AnyRange<typename Range::ValueType>(range);
241 template <
typename Range,
typename Func>
246 "A Range is expected as the first argument"
248 while(!range.
Empty())
264 template <
typename Range>
269 "A Range is expected as the first argument"
271 while(!range.
Empty())
273 if(range.
Front() == value)
break;
279 template <
typename Range>
283 IsRange<Range>::Type::value,
284 "A Range is expected as the first argument"
286 while(!range.
Empty())
288 if(range.
Front() == value)
return true;
294 template <
typename Range,
typename Predicate>
295 inline Range& AdvanceUntil(Range& range, Predicate predicate)
298 IsRange<Range>::Type::value,
299 "A Range is expected as the first argument"
301 while(!range.Empty())
303 if(predicate(range.Front()))
break;
309 template <
typename Range,
typename Predicate>
310 inline std::size_t CountIf(Range range, Predicate predicate)
313 IsRange<Range>::Type::value,
314 "A Range is expected as the first argument"
316 std::size_t result = 0;
317 while(!range.Empty())
319 if(predicate(range.Front())) ++result;
333 template <
typename Range,
typename Predicate>
336 return AdvanceUntil(range, predicate);
339 template <
typename Range,
typename Predicate>
340 inline bool Has(
Range range, Predicate predicate)
342 return !AdvanceUntil(range, predicate).
Empty();
345 template <
typename Range,
typename Transf>
352 typedef decltype(std::declval<Transf>()(
353 std::declval<typename Range::ValueType>())
356 Transformed(Range range, Transf transf)
361 bool Empty(
void)
const
363 return _range.Empty();
366 size_t Size(
void)
const
368 return _range.Size();
376 ValueType Front(
void)
const
378 return _transf(_range.Front());
388 template <
typename Range,
typename Transf>
393 "A Range is expected as the first argument"
395 return Transformed<Range, Transf>(range, transf);
413 template <
typename Range,
typename State,
typename Op>
418 "A Range is expected as the first argument"
420 while(!range.
Empty())
422 state = op(state, range.
Front());
429 template <
typename Range,
typename Predicate>
438 Filtered(
Range range, Predicate pred)
442 oglplus::ranges::AdvanceUntil(_range, _pred);
445 bool Empty(
void)
const
447 return _range.Empty();
450 size_t Size(
void)
const
452 return CountIf(*
this, _pred);
458 oglplus::ranges::AdvanceUntil(_range, _pred);
461 ValueType Front(
void)
const
463 return _range.Front();
473 template <
typename Range,
typename Predicate>
474 inline Filtered<Range, Predicate>
OnlyIf(
Range range, Predicate pred)
478 "A Range is expected as the first argument"
480 return Filtered<Range, Predicate>(range, pred);
483 template <
typename Element,
typename R1,
typename R2>
490 typedef Element ValueType;
492 Concatenated(R1 r1, R2 r2)
497 bool Empty(
void)
const
499 return _r1.Empty() && _r2.Empty();
502 size_t Size(
void)
const
504 return _r1.Size() + _r2.Size();
511 else if(!_r2.Empty())
513 else assert(!Empty());
516 ValueType Front(
void)
const
519 return ValueType(_r1.Front());
520 else if(!_r2.Empty())
521 return ValueType(_r2.Front());
522 else assert(!Empty());
523 return *((ValueType*)
nullptr);
527 template <
typename Element,
typename R1,
typename R2>
528 inline Concatenated<Element, R1, R2> Concatenate(R1 r1, R2 r2)
531 IsRange<R1>::Type::value,
532 "A Range is expected as the first argument"
535 IsRange<R2>::Type::value,
536 "A Range is expected as the second argument"
538 return Concatenated<Element, R1, R2>(r1, r2);
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