rah
rah.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2019 Loïc HAMOT
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include <cassert>
10 #include <ciso646>
11 
12 #ifndef RAH_DONT_USE_STD
13 
14 #ifdef MSVC
15 #pragma warning(push, 0)
16 #endif
17 #include <type_traits>
18 #include <iterator>
19 #include <tuple>
20 #include <algorithm>
21 #include <numeric>
22 #include <vector>
23 #include <array>
24 #ifdef MSVC
25 #pragma warning(pop)
26 #endif
27 
28 #ifndef RAH_STD
29 #define RAH_STD std
30 #endif
31 
32 #else
33 
34 #include "rah_custom_std.hpp"
35 
36 #endif
37 
38 #ifndef RAH_NAMESPACE
39 #define RAH_NAMESPACE rah
40 #endif
41 
42 namespace RAH_NAMESPACE
43 {
44 
45 constexpr intptr_t End = -1;
46 
47 // **************************** range traits ******************************************************
48 
49 template<class T, size_t N> T* begin(T(&array)[N]) { return (T*)array; }
50 
51 template<class T, size_t N> T* end(T(&array)[N]) noexcept { return array + N; }
52 
54 template<typename T> T& fake() { return *((RAH_STD::remove_reference_t<T>*)nullptr); }
55 
56 template<typename T>
57 using range_begin_type_t = decltype(begin(fake<T>()));
58 
59 template<typename T>
60 using range_end_type_t = decltype(end(fake<T>()));
61 
62 template<typename T>
63 using range_ref_type_t = decltype(*begin(fake<T>()));
64 
65 template<typename T>
66 using range_value_type_t = RAH_STD::remove_reference_t<range_ref_type_t<T>>;
67 
68 template<typename R>
69 using range_iter_categ_t = typename RAH_STD::iterator_traits<range_begin_type_t<R>>::iterator_category;
70 
71 template<typename R, typename = int>
72 struct is_range { static constexpr bool value = false; };
73 
74 template<typename R>
75 struct is_range <R, decltype(begin(fake<R>()), end(fake<R>()), 0)> { static constexpr bool value = true; };
76 
77 // ******************************** iterator_range ************************************************
78 
79 template<typename I>
80 struct iterator_range
81 {
82  I begin_iter;
83  I end_iter;
84 
85  I begin() const { return begin_iter; }
86  I begin() { return begin_iter; }
87  I end() const { return end_iter; }
88  I end() { return end_iter; }
89 };
90 
91 template<typename I>
92 auto make_iterator_range(I b, I e)
93 {
94  return iterator_range<I>{b, e};
95 }
96 
98 template<typename I> I begin(iterator_range<I>& r) { return r.begin_iter; }
100 template<typename I> I end(iterator_range<I>& r) { return r.end_iter; }
102 template<typename I> I begin(iterator_range<I> const& r) { return r.begin_iter; }
104 template<typename I> I end(iterator_range<I> const& r) { return r.end_iter; }
105 
106 // **************************************** pipeable **********************************************
107 
108 template<typename Func>
109 struct pipeable
110 {
111  Func func;
112 };
113 
114 template<typename MakeRange>
115 auto make_pipeable(MakeRange&& make_range)
116 {
117  return pipeable<MakeRange>{ make_range };
118 }
119 
120 template<typename R, typename MakeRange>
121 auto operator | (R&& range, pipeable<MakeRange> const& adapter) ->decltype(adapter.func(RAH_STD::forward<R>(range)))
122 {
123  return adapter.func(RAH_STD::forward<R>(range));
124 }
125 
126 // ************************************ iterator_facade *******************************************
127 
128 namespace details
129 {
130 
131 // Small optional impl for C++14 compilers
132 template<typename T> struct optional
133 {
134  optional() = default;
135  optional(optional const& other)
136  {
137  if (other.has_value())
138  {
139  new(getPtr()) T(other.get());
140  is_allocated_ = true;
141  }
142  }
143  optional& operator = (optional const& other)
144  {
145  if (has_value())
146  {
147  if (other.has_value())
148  {
149  // Handle the case where T is not copy assignable
150  reset();
151  new(getPtr()) T(other.get());
152  is_allocated_ = true;
153  }
154  else
155  reset();
156  }
157  else
158  {
159  if (other.has_value())
160  {
161  new(getPtr()) T(other.get());
162  is_allocated_ = true;
163  }
164  }
165  return *this;
166  }
167  optional& operator = (optional&& other)
168  {
169  if (has_value())
170  {
171  if (other.has_value())
172  {
173  // A lambda with const capture is not move assignable
174  reset();
175  new(getPtr()) T(RAH_STD::move(other.get()));
176  is_allocated_ = true;
177  }
178  else
179  reset();
180  }
181  else
182  {
183  if (other.has_value())
184  {
185  new(getPtr()) T(RAH_STD::move(other.get()));
186  is_allocated_ = true;
187  }
188  }
189  return *this;
190  }
191  optional(T const& other)
192  {
193  new(getPtr()) T(other);
194  is_allocated_ = true;
195  }
196  optional& operator=(T const& other)
197  {
198  new(getPtr()) T(other);
199  is_allocated_ = true;
200  return *this;
201  }
202  optional& operator=(T&& other)
203  {
204  new(getPtr()) T(RAH_STD::move(other));
205  is_allocated_ = true;
206  return *this;
207  }
208  ~optional() { reset(); }
209 
210  bool has_value() const { return is_allocated_; }
211 
212  void reset()
213  {
214  if (is_allocated_)
215  {
216  destruct_value();
217  is_allocated_ = false;
218  }
219  }
220 
221  T& get() { assert(is_allocated_); return *getPtr(); }
222 
223  T const& get() const { assert(is_allocated_); return *getPtr(); }
224 
225  T& operator*() { return get(); }
226  T const& operator*() const { return get(); }
227  T* operator->() { assert(is_allocated_); return getPtr(); }
228  T const* operator->() const { assert(is_allocated_); return getPtr(); }
229 
230 private:
231  T* getPtr() { return (T*)&value_; }
232  T const* getPtr() const { return (T const*)&value_; }
233  void destruct_value() { get().~T(); }
234 
235  RAH_STD::aligned_storage_t<sizeof(T), RAH_STD::alignment_of<T>::value> value_;
236  bool is_allocated_ = false;
237 };
238 }
239 
240 template<typename I, typename R, typename C> struct iterator_facade;
241 
242 template<typename I, typename R>
243 struct iterator_facade<I, R, RAH_STD::forward_iterator_tag>
244 {
245  template <class Reference>
246  struct pointer_type
247  {
248  using type = RAH_NAMESPACE::details::optional<Reference>;
249  template<typename Ref>
250  static type to_pointer(Ref&& ref)
251  {
252  return RAH_STD::forward<Ref>(ref);
253  }
254  };
255 
256  template <class T>
257  struct pointer_type<T&> // "real" references
258  {
259  using type = T*;
260  template<typename Ref>
261  static type to_pointer(Ref&& ref)
262  {
263  return &ref;
264  }
265  };
266 
267  using iterator_category = RAH_STD::forward_iterator_tag;
268  using value_type = RAH_STD::remove_reference_t<R>;
269  using difference_type = intptr_t;
270  using pointer = typename pointer_type<R>::type;
271  using reference = R;
272 
273  static_assert(not RAH_STD::is_reference<value_type>::value, "value_type can't be a reference");
274 
275  I& self() { return *static_cast<I*>(this); }
276  I const& self() const { return *static_cast<I const*>(this); }
277 
278  auto& operator++()
279  {
280  self().increment();
281  return *this;
282  }
283 
284  reference operator*() const
285  {
286  static_assert(RAH_STD::is_same<decltype(self().dereference()), reference>::value, "");
287  return self().dereference();
288  }
289  auto operator->() const { return pointer_type<R>::to_pointer(self().dereference()); }
290  bool operator!=(I other) const { return not self().equal(other); }
291  bool operator==(I other) const { return self().equal(other); }
292 };
293 
294 template<typename I, typename R>
295 struct iterator_facade<I, R, RAH_STD::output_iterator_tag>
296 {
297  using iterator_category = RAH_STD::forward_iterator_tag;
298  using value_type = RAH_STD::remove_reference_t<R>;
299  using difference_type = intptr_t;
300  using pointer = value_type*;
301  using reference = R;
302 
303  static_assert(not RAH_STD::is_reference<value_type>::value, "value_type can't be a reference");
304 
305  I& self() { return *static_cast<I*>(this); }
306  I const& self() const { return *static_cast<I const*>(this); }
307 
308  auto& operator++() { return *this; }
309  auto& operator*() const { return *this; }
310  bool operator!=(I other) const { return true; }
311  bool operator==(I other) const { return false; }
312 
313  template<typename V>
314  auto operator=(V&& value) const
315  {
316  self().put(RAH_STD::forward<V>(value));
317  return self();
318  }
319 };
320 
321 
322 template<typename I, typename R>
323 struct iterator_facade<I, R, RAH_STD::bidirectional_iterator_tag> : iterator_facade<I, R, RAH_STD::forward_iterator_tag>
324 {
325  using iterator_category = RAH_STD::bidirectional_iterator_tag;
326 
327  I& self() { return *static_cast<I*>(this); }
328  I const& self() const { return *static_cast<I const*>(this); }
329 
330  auto& operator--()
331  {
332  self().decrement();
333  return *this;
334  }
335 };
336 
337 template<typename I, typename R>
338 struct iterator_facade<I, R, RAH_STD::random_access_iterator_tag> : iterator_facade<I, R, RAH_STD::bidirectional_iterator_tag>
339 {
340  using iterator_category = RAH_STD::random_access_iterator_tag;
341 
342  I& self() { return *static_cast<I*>(this); }
343  I const& self() const { return *static_cast<I const*>(this); }
344 
345  auto& operator+=(intptr_t increment)
346  {
347  self().advance(increment);
348  return *this;
349  }
350 
351  auto operator+(intptr_t increment)
352  {
353  auto iter = self();
354  iter.advance(increment);
355  return iter;
356  }
357 
358  auto& operator-=(intptr_t increment)
359  {
360  self().advance(-increment);
361  return *this;
362  }
363 
364  auto operator-(intptr_t increment)
365  {
366  auto iter = self();
367  iter.advance(-increment);
368  return iter;
369  }
370 
371  auto operator-(I other) const { return self().distance_to(other); }
372  bool operator<(I other) const { return self().distance_to(other) < 0; }
373  bool operator<=(I other) const { return self().distance_to(other) <= 0; }
374  bool operator>(I other) const { return self().distance_to(other) > 0; }
375  bool operator>=(I other) const { return self().distance_to(other) >= 0; }
376  auto operator[](intptr_t increment) const { return *(self() + increment); }
377 };
378 
379 // ********************************** back_inserter ***********************************************
380 
382 template<typename C>
383 struct back_insert_iterator : iterator_facade<back_insert_iterator<C>, range_ref_type_t<C>, RAH_STD::output_iterator_tag>
384 {
385  C* container_;
386  back_insert_iterator(C& container) : container_(&container) { }
387  template<typename V> void put(V&& value) const { container_->emplace_back(value); }
388 };
389 
393 template<typename C> auto back_inserter(C&& container)
394 {
395  using Container = RAH_STD::remove_reference_t<C>;
396  auto begin = back_insert_iterator<Container>(container);
397  auto end = back_insert_iterator<Container>(container);
399 }
400 
402 struct is_lesser
403 {
404  template<typename A, typename B> bool operator()(A&& a, B&& b) { return a < b; }
405 };
406 
407 namespace view
408 {
409 
410 
411 // ********************************** all *********************************************************
412 
413 template<typename R> auto all(R&& range)
414 {
415  return iterator_range<range_begin_type_t<R>>{begin(range), end(range)};
416 }
417 
418 inline auto all()
419 {
420  return make_pipeable([=](auto&& range) {return all(range); });
421 }
422 
423 // ******************************************* take ***********************************************
424 
425 template<typename I>
426 struct take_iterator : iterator_facade<
427  take_iterator<I>,
428  decltype(*fake<I>()),
429  typename RAH_STD::iterator_traits<I>::iterator_category
430 >
431 {
432  I iter_;
433  size_t count_ = size_t();
434 
435  take_iterator() = default;
436  take_iterator(I iter, size_t count) : iter_(iter), count_(count) {}
437 
438  void increment() { ++iter_; ++count_; }
439  void advance(intptr_t off) { iter_ += off; count_ += off; }
440  void decrement() { --iter_; --count_; }
441  auto distance_to(take_iterator r) const { return RAH_STD::min<intptr_t>(iter_ - r.iter_, count_ - r.count_); }
442  auto dereference() const -> decltype(*iter_) { return *iter_; }
443  bool equal(take_iterator r) const { return count_ == r.count_ || iter_ == r.iter_; }
444 };
445 
446 template<typename R> auto take(R&& range, size_t count)
447 {
448  using iterator = take_iterator<range_begin_type_t<R>>;
449  iterator iter1(begin(range), 0);
450  iterator iter2(end(range), count);
451  return make_iterator_range(iter1, iter2);
452 }
453 
454 inline auto take(size_t count)
455 {
456  return make_pipeable([=](auto&& range) {return take(range, count); });
457 }
458 
459 // ******************************************* sliding ********************************************
460 
461 template<typename I>
463  sliding_iterator<I>,
464  iterator_range<I>,
465  typename RAH_STD::iterator_traits<I>::iterator_category
466 >
467 {
468  // Actually store a closed range [begin, last]
469  // to avoid to exceed the end iterator of the underlying range
472 
473  sliding_iterator() = default;
474  sliding_iterator(I subRangeBegin, I subRangeLast)
475  : subRangeBegin_(subRangeBegin)
476  , subRangeLast_(subRangeLast)
477  {
478  }
479 
480  void increment() { ++subRangeBegin_; ++subRangeLast_; }
481  void advance(intptr_t off) { subRangeBegin_ += off; subRangeLast_ += off; }
482  void decrement() { --subRangeBegin_; --subRangeLast_; }
483  auto distance_to(sliding_iterator const& r) const { return subRangeBegin_ - r.subRangeBegin_; }
484  auto dereference() const
485  {
486  I endIter = subRangeLast_;
487  ++endIter;
488  return make_iterator_range(subRangeBegin_, endIter);
489  }
490  bool equal(sliding_iterator const& r) const { return subRangeBegin_ == r.subRangeBegin_; }
491 };
492 
493 template<typename R> auto sliding(R&& range, size_t n)
494 {
495  size_t const closedSubRangeSize = n - 1;
496  auto const rangeEnd = end(range);
497  using iterator = sliding_iterator<range_begin_type_t<R>>;
498  auto subRangeBegin = begin(range);
499  auto subRangeLast = subRangeBegin;
500  for (size_t i = 0; i != closedSubRangeSize; ++i)
501  {
502  if (subRangeLast == rangeEnd)
503  return make_iterator_range(iterator(rangeEnd, rangeEnd), iterator(rangeEnd, rangeEnd));
504  ++subRangeLast;
505  }
506 
507  auto endSubRangeBegin = rangeEnd;
508  RAH_STD::advance(endSubRangeBegin, -intptr_t(n - 1));
509 
510  iterator iter1(subRangeBegin, subRangeLast);
511  iterator iter2(endSubRangeBegin, rangeEnd);
512  return make_iterator_range(iter1, iter2);
513 }
514 
515 inline auto sliding(size_t n)
516 {
517  return make_pipeable([=](auto&& range) {return sliding(range, n); });
518 }
519 
520 // ******************************************* drop_exactly ***************************************
521 
522 template<typename R> auto drop_exactly(R&& range, size_t count)
523 {
524  auto iter1 = begin(range);
525  auto iter2 = end(range);
526  RAH_STD::advance(iter1, count);
527  return make_iterator_range(iter1, iter2);
528 }
529 
530 inline auto drop_exactly(size_t count)
531 {
532  return make_pipeable([=](auto&& range) {return drop_exactly(range, count); });
533 }
534 
535 // ******************************************* drop ***********************************************
536 
537 template<typename R> auto drop(R&& range, size_t count)
538 {
539  auto iter1 = begin(range);
540  auto iter2 = end(range);
541  for(size_t i = 0; i < count; ++i)
542  {
543  if (iter1 == iter2)
544  break;
545  ++iter1;
546  }
547  return make_iterator_range(iter1, iter2);
548 }
549 
550 inline auto drop(size_t count)
551 {
552  return make_pipeable([=](auto&& range) {return drop(range, count); });
553 }
554 
555 // ******************************************* counted ********************************************
556 
557 template<typename I>
558 struct counted_iterator : iterator_facade<
559  counted_iterator<I>,
560  decltype(*fake<I>()),
561  typename RAH_STD::iterator_traits<I>::iterator_category
562 >
563 {
564  I iter_;
565  size_t count_ = size_t();
566 
567  counted_iterator() = default;
568  counted_iterator(I iter, size_t count) : iter_(iter), count_(count) {}
569 
570  void increment() { ++iter_; ++count_; }
571  void advance(intptr_t off) { iter_ += off; count_ += off; }
572  void decrement() { --iter_; --count_; }
573  auto distance_to(counted_iterator r) const { return count_ - r.count_; }
574  auto dereference() const -> decltype(*iter_) { return *iter_; }
575  bool equal(counted_iterator r) const { return count_ == r.count_; }
576 };
577 
578 template<typename I> auto counted(I&& it, size_t n, decltype(++it, 0) = 0)
579 {
580  using iterator = counted_iterator<RAH_STD::remove_reference_t<I>>;
581  iterator iter1(it, 0);
582  iterator iter2(it, n);
583  return make_iterator_range(iter1, iter2);
584 }
585 
587 // Obsolete
588 template<typename R> auto counted(R&& range, size_t n, decltype(begin(range), 0) = 0)
589 {
590  return take(range, n);
591 }
592 
593 inline auto counted(size_t n)
594 {
595  return make_pipeable([=](auto&& range) {return take(range, n); });
596 }
598 
599 // ******************************************* unbounded ******************************************
600 
601 template<typename I>
602 struct unbounded_iterator : iterator_facade<
603  unbounded_iterator<I>,
604  decltype(*fake<I>()),
605  typename RAH_STD::iterator_traits<I>::iterator_category
606 >
607 {
608  I iter_;
609  bool end_;
610 
611  unbounded_iterator() = default;
612  unbounded_iterator(I iter, bool end) : iter_(iter), end_(end) {}
613 
614  void increment() { ++iter_; }
615 
616  void advance(intptr_t off) { iter_ += off; }
617  void decrement() { --iter_; }
619  {
620  if (end_)
621  {
622  if (r.end_)
623  return intptr_t{};
624  else
625  return RAH_STD::numeric_limits<intptr_t>::min();
626  }
627  else
628  {
629  if (r.end_)
630  return RAH_STD::numeric_limits<intptr_t>::max();
631  else
632  return iter_ - r.iter_;
633  }
634  }
635 
636  auto dereference() const -> decltype(*iter_) { return *iter_; }
637  bool equal(unbounded_iterator r) const
638  {
639  return end_?
640  r.end_:
641  (r.end_? false: r.iter_ == iter_);
642  }
643 };
644 
645 template<typename I> auto unbounded(I&& it)
646 {
647  using iterator = unbounded_iterator<RAH_STD::remove_reference_t<I>>;
648  iterator iter1(it, false);
649  iterator iter2(it, true);
650  return make_iterator_range(iter1, iter2);
651 }
652 
653 // ********************************** ints ********************************************************
654 
656 template<typename T = size_t>
657 struct ints_iterator : iterator_facade<ints_iterator<T>, T, RAH_STD::random_access_iterator_tag>
658 {
659  T val_ = T();
660 
661  ints_iterator() = default;
662  ints_iterator(T val) : val_(val) {}
663 
664  void increment() { ++val_; }
665  void advance(intptr_t value) { val_ += T(value); }
666  void decrement() { --val_; }
667  auto distance_to(ints_iterator other) const { return (val_ - other.val_); }
668  auto dereference() const { return val_; }
669  bool equal(ints_iterator other) const { return val_ == other.val_; }
670 };
671 
672 template<typename T = size_t> auto ints(T b = 0, T e = RAH_STD::numeric_limits<T>::max())
673 {
674  return iterator_range<ints_iterator<T>>{ { b }, { e }};
675 }
676 
677 template<typename T = size_t> auto closed_ints(T b = 0, T e = RAH_STD::numeric_limits<T>::max() - 1)
678 {
679  return iterator_range<ints_iterator<T>>{ { b }, { e + 1 }};
680 }
681 
682 // ********************************** iota ********************************************************
683 
685 template<typename T = size_t>
686 struct iota_iterator : iterator_facade<iota_iterator<T>, T, RAH_STD::random_access_iterator_tag>
687 {
688  T val_ = T();
689  T step_ = T(1);
690 
691  iota_iterator() = default;
692  iota_iterator(T val, T step) : val_(val), step_(step) {}
693 
694  void increment() { val_ += step_; }
695  void advance(intptr_t value) { val_ += T(step_ * value); }
696  void decrement() { val_ -= step_; }
697  auto distance_to(iota_iterator other) const { return (val_ - other.val_) / step_; }
698  auto dereference() const { return val_; }
699  bool equal(iota_iterator other) const { return val_ == other.val_; }
700 };
701 
702 template<typename T = size_t> auto iota(T b, T e, T step = 1)
703 {
704  assert(step != 0);
705  auto diff = (e - b);
706  diff = ((diff + (step - 1)) / step) * step;
707  return iterator_range<iota_iterator<T>>{ { b, step}, { b + diff, step }};
708 }
709 
710 // ********************************** repeat ******************************************************
711 
713 template<typename V>
714 struct repeat_iterator : iterator_facade<repeat_iterator<V>, V const&, RAH_STD::forward_iterator_tag>
715 {
716  V val_ = V();
717 
718  repeat_iterator() = default;
719  template<typename U>
720  repeat_iterator(U val) : val_(RAH_STD::forward<U>(val)) {}
721 
722  void increment() { }
723  void advance(intptr_t value) { }
724  void decrement() { }
725  V const& dereference() const { return val_; }
726  bool equal(repeat_iterator) const { return false; }
727 };
728 
729 template<typename V> auto repeat(V&& value)
730 {
732 }
733 
734 // ********************************** join ********************************************************
735 
736 template<typename R>
737 struct join_iterator : iterator_facade<join_iterator<R>, range_ref_type_t<range_ref_type_t<R>>, RAH_STD::forward_iterator_tag>
738 {
739  R range_;
742  Iterator1 rangeIter_;
743  struct SubRange
744  {
745  Iterator2 subRangeIter;
746  Iterator2 subRangeEnd;
747  };
748  RAH_NAMESPACE::details::optional<SubRange> subRange_;
749 
750  template<typename U>
751  join_iterator(U&& range, Iterator1 rangeIter, Iterator2 subRangeIter, Iterator2 subRangeEnd)
752  : range_(RAH_STD::forward<U>(range))
753  , rangeIter_(rangeIter)
754  , subRange_(SubRange{ subRangeIter, subRangeEnd })
755  {
756  if (rangeIter_ == end(range_))
757  return;
758  next_valid();
759  }
760 
761  template<typename U>
762  join_iterator(U&& range, Iterator1 rangeIter)
763  : range_(RAH_STD::forward<U>(range))
764  , rangeIter_(rangeIter)
765  {
766  }
767 
768  void next_valid()
769  {
770  while (subRange_->subRangeIter == subRange_->subRangeEnd)
771  {
772  ++rangeIter_;
773  if (rangeIter_ == end(range_))
774  return;
775  else
776  {
777  auto&& subRange = *rangeIter_;
778  subRange_->subRangeIter = begin(subRange);
779  subRange_->subRangeEnd = end(subRange);
780  }
781  }
782  }
783 
784  void increment()
785  {
786  ++subRange_->subRangeIter;
787  next_valid();
788  }
789  auto dereference() const ->decltype(*subRange_->subRangeIter) { return *subRange_->subRangeIter; }
790  bool equal(join_iterator other) const
791  {
792  if (rangeIter_ == end(range_))
793  return rangeIter_ == other.rangeIter_;
794  else
795  return rangeIter_ == other.rangeIter_ && subRange_->subRangeIter == other.subRange_->subRangeIter;
796  }
797 };
798 
799 template<typename R> auto join(R&& range_of_ranges)
800 {
801  auto rangeRef = range_of_ranges | RAH_NAMESPACE::view::all();
802  using join_iterator_type = join_iterator<decltype(rangeRef)>;
803  auto rangeBegin = begin(rangeRef);
804  auto rangeEnd = end(rangeRef);
805  if (empty(rangeRef))
806  {
807  join_iterator_type b(rangeRef, rangeBegin);
808  join_iterator_type e(rangeRef, rangeEnd);
809  return make_iterator_range(b, e);
810  }
811  else
812  {
813  auto&& firstSubRange = *rangeBegin;
814  join_iterator_type b(rangeRef, rangeBegin, begin(firstSubRange), end(firstSubRange));
815  join_iterator_type e(rangeRef, rangeEnd);
816  return make_iterator_range(b, e);
817  }
818 }
819 
820 inline auto join()
821 {
822  return make_pipeable([](auto&& range) {return join(range); });
823 }
824 
825 // ********************************** cycle ********************************************************
826 
827 template<typename R>
828 struct cycle_iterator : iterator_facade<cycle_iterator<R>, range_ref_type_t<R>, RAH_STD::forward_iterator_tag>
829 {
830  R range_;
832  Iterator beginIter_;
833  Iterator endIter_;
834  Iterator iter_;
835 
836  template<typename U>
837  explicit cycle_iterator(U&& range, Iterator iter)
838  : range_(RAH_STD::forward<U>(range))
839  , beginIter_(begin(range_))
840  , endIter_(end(range_))
841  , iter_(iter)
842  {
843  }
844 
845  void increment()
846  {
847  ++iter_;
848  while (iter_ == endIter_)
849  iter_ = begin(range_);
850  }
851  auto dereference() const ->decltype(*iter_) { return *iter_; }
852  bool equal(cycle_iterator) const
853  {
854  return false;
855  }
856 };
857 
858 template<typename R> auto cycle(R&& range)
859 {
860  auto rangeRef = range | RAH_NAMESPACE::view::all();
861  using iterator_type = cycle_iterator<RAH_STD::remove_reference_t<decltype(rangeRef)>>;
862 
863  iterator_type b(rangeRef, begin(rangeRef));
864  iterator_type e(rangeRef, begin(rangeRef));
865  return make_iterator_range(b, e);
866 }
867 
868 inline auto cycle()
869 {
870  return make_pipeable([](auto&& range) {return cycle(range); });
871 }
872 
873 // ********************************** generate ****************************************************
874 
876 template<typename F>
877 struct generate_iterator : iterator_facade<generate_iterator<F>, decltype(fake<F>()()), RAH_STD::forward_iterator_tag>
878 {
879  mutable RAH_NAMESPACE::details::optional<F> func_;
880 
881  generate_iterator(F const& func) : func_(func) {}
882 
883  void increment() { }
884  auto dereference() const { return (*func_)(); }
885  bool equal(generate_iterator) const { return false; }
886 };
887 
888 template<typename F> auto generate(F&& func)
889 {
890  using Functor = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
891  return iterator_range<generate_iterator<Functor>>{ { func}, { func }};
892 }
893 
894 template<typename F> auto generate_n(size_t count, F&& func)
895 {
896  return generate(RAH_STD::forward<F>(func)) | take(count);
897 }
898 
899 // ******************************************* transform ******************************************
900 
901 template<typename R, typename F>
902 struct transform_iterator : iterator_facade<
903  transform_iterator<R, F>,
904  decltype(fake<F>()(fake<range_ref_type_t<R>>())),
905  range_iter_categ_t<R>
906 >
907 {
908  range_begin_type_t<R> iter_;
909  RAH_NAMESPACE::details::optional<F> func_;
910 
911  transform_iterator(range_begin_type_t<R> const& iter, F const& func) : iter_(iter), func_(func) {}
912 
914  {
915  iter_ = ot.iter_;
916  func_ = ot.func_;
917  return *this;
918  }
919 
920  void increment() { ++iter_; }
921  void advance(intptr_t off) { iter_ += off; }
922  void decrement() { --iter_; }
923  auto distance_to(transform_iterator r) const { return iter_ - r.iter_; }
924  auto dereference() const -> decltype((*func_)(*iter_)) { return (*func_)(*iter_); }
925  bool equal(transform_iterator r) const { return iter_ == r.iter_; }
926 };
927 
928 template<typename R, typename F> auto transform(R&& range, F&& func)
929 {
930  using Functor = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
931  using iterator = transform_iterator<RAH_STD::remove_reference_t<R>, Functor>;
932  auto iter1 = begin(range);
933  auto iter2 = end(range);
934  return iterator_range<iterator>{ { iter1, func }, { iter2, func } };
935 }
936 
937 template<typename F> auto transform(F&& func)
938 {
939  return make_pipeable([=](auto&& range) {return transform(range, func); });
940 }
941 
942 // ******************************************* set_difference *************************************
943 
944 template<typename InputIt1, typename InputIt2>
946  set_difference_iterator<InputIt1, InputIt2>,
947  typename RAH_STD::iterator_traits<InputIt1>::reference,
948  RAH_STD::forward_iterator_tag
949 >
950 {
951  InputIt1 first1_;
952  InputIt1 last1_;
953  InputIt2 first2_;
954  InputIt2 last2_;
955 
956  set_difference_iterator(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
957  : first1_(first1) , last1_(last1) , first2_(first2), last2_(last2)
958  {
959  next_value();
960  }
961 
962  void next_value()
963  {
964  while (first2_ != last2_ and first1_ != last1_)
965  {
966  if (*first1_ < *first2_)
967  break;
968  else if (*first1_ == *first2_)
969  {
970  ++first1_;
971  ++first2_;
972  }
973  else
974  ++first2_;
975  }
976  }
977 
978  void increment()
979  {
980  ++first1_;
981  next_value();
982  }
983  auto dereference() const -> decltype(*first1_) { return *first1_; }
984  bool equal(set_difference_iterator r) const { return first1_ == r.first1_; }
985 };
986 
987 template<typename R1, typename R2> auto set_difference(R1&& range1, R2&& range2)
988 {
989  using Iter1 = range_begin_type_t<R1>;
990  using Iter2 = range_begin_type_t<R2>;
991  using Iterator = set_difference_iterator<Iter1, Iter2>;
992  return iterator_range<Iterator>{
993  { Iterator(begin(range1), end(range1), begin(range2), end(range2)) },
994  { Iterator(end(range1), end(range1), end(range2), end(range2)) },
995  };
996 }
997 
998 template<typename R2> auto set_difference(R2&& range2)
999 {
1000  return make_pipeable([r2 = range2 | view::all()](auto&& range) {return set_difference(range, r2); });
1001 }
1002 
1003 // ********************************** for_each ****************************************************
1004 
1005 template<typename R, typename F> auto for_each(R&& range, F&& func)
1006 {
1008 }
1009 
1010 template<typename F>
1011 inline auto for_each(F&& func)
1012 {
1013  return make_pipeable([=](auto&& range) {return RAH_NAMESPACE::view::for_each(range, func); });
1014 }
1015 
1016 // ***************************************** slice ************************************************
1017 
1018 template<typename R> auto slice(R&& range, intptr_t begin_idx, intptr_t end_idx)
1019 {
1020  static_assert(not RAH_STD::is_same<range_iter_categ_t<R>, RAH_STD::forward_iterator_tag>::value,
1021  "Can't use slice on non-bidirectional iterators. Try to use view::drop and view::take");
1022  auto findIter = [](auto b, auto e, intptr_t idx)
1023  {
1024  if (idx < 0)
1025  {
1026  idx += 1;
1027  RAH_STD::advance(e, idx);
1028  return e;
1029  }
1030  else
1031  {
1032  RAH_STD::advance(b, idx);
1033  return b;
1034  }
1035  };
1036  auto b_in = begin(range);
1037  auto e_in = end(range);
1038  auto b_out = findIter(b_in, e_in, begin_idx);
1039  auto e_out = findIter(b_in, e_in, end_idx);
1040  return iterator_range<decltype(b_out)>{ {b_out}, { e_out } };
1041 }
1042 
1043 inline auto slice(intptr_t begin, intptr_t end)
1044 {
1045  return make_pipeable([=](auto&& range) {return slice(range, begin, end); });
1046 }
1047 
1048 // ***************************************** stride ***********************************************
1049 
1050 template<typename R>
1051 struct stride_iterator : iterator_facade<stride_iterator<R>, range_ref_type_t<R>, range_iter_categ_t<R>>
1052 {
1053  range_begin_type_t<R> iter_;
1054  range_end_type_t<R> end_;
1055  size_t step_;
1056 
1058  : iter_(iter), end_(end), step_(step) {}
1059 
1060  auto increment()
1061  {
1062  for (size_t i = 0; i < step_ && iter_ != end_; ++i)
1063  ++iter_;
1064  }
1065 
1066  auto decrement()
1067  {
1068  for (size_t i = 0; i < step_; ++i)
1069  --iter_;
1070  }
1071 
1072  void advance(intptr_t value) { iter_ += step_ * value; }
1073  auto dereference() const -> decltype(*iter_) { return *iter_; }
1074  bool equal(stride_iterator other) const { return iter_ == other.iter_; }
1075  auto distance_to(stride_iterator other) const { return (iter_ - other.iter_) / step_; }
1076 };
1077 
1078 
1079 template<typename R> auto stride(R&& range, size_t step)
1080 {
1081  auto iter = begin(range);
1082  auto endIter = end(range);
1084  { iter, endIter, step}, { endIter, endIter, step }};
1085 }
1086 
1087 inline auto stride(size_t step)
1088 {
1089  return make_pipeable([=](auto&& range) {return stride(range, step); });
1090 }
1091 
1092 // ***************************************** retro ************************************************
1093 
1094 template<typename R> auto retro(R&& range)
1095 {
1096  return make_iterator_range(
1097  RAH_STD::make_reverse_iterator(end(range)), RAH_STD::make_reverse_iterator(begin(range)));
1098 }
1099 
1100 inline auto retro()
1101 {
1102  return make_pipeable([=](auto&& range) {return retro(range); });
1103 }
1104 
1105 // ********************************** single ******************************************************
1106 
1107 template<typename V>
1108 auto single(V&& value)
1109 {
1110  return repeat(value) | take(1);
1111 }
1112 
1113 // *************************** zip ****************************************************************
1115 namespace details
1116 {
1117 template <typename Tuple, typename F, size_t ...Indices>
1118 void for_each_impl(Tuple&& tuple, F&& f, RAH_STD::index_sequence<Indices...>)
1119 {
1120  using swallow = int[];
1121  (void)swallow {
1122  1,
1123  (f(RAH_STD::get<Indices>(RAH_STD::forward<Tuple>(tuple))), void(), int{})...
1124  };
1125 }
1126 
1127 template <typename Tuple, typename F>
1128 void for_each(Tuple&& tuple, F&& f)
1129 {
1130  constexpr size_t N = RAH_STD::tuple_size<RAH_STD::remove_reference_t<Tuple>>::value;
1131  for_each_impl(RAH_STD::forward<Tuple>(tuple), RAH_STD::forward<F>(f),
1132  RAH_STD::make_index_sequence<N>{});
1133 }
1134 
1135 template <class F, typename... Args, size_t... Is>
1136 auto transform_each_impl(const RAH_STD::tuple<Args...>& t, F&& f, RAH_STD::index_sequence<Is...>) {
1137  return RAH_STD::make_tuple(
1138  f(RAH_STD::get<Is>(t))...
1139  );
1140 }
1141 
1142 template <class F, typename... Args>
1143 auto transform_each(const RAH_STD::tuple<Args...>& t, F&& f) {
1144  return transform_each_impl(
1145  t, RAH_STD::forward<F>(f), RAH_STD::make_index_sequence<sizeof...(Args)>{});
1146 }
1147 
1148 template <typename... Args, size_t... Is>
1149 auto deref_impl(const RAH_STD::tuple<Args...>& t, RAH_STD::index_sequence<Is...>) {
1150  return RAH_STD::tuple<typename RAH_STD::iterator_traits<Args>::reference...>(
1151  (*RAH_STD::get<Is>(t))...
1152  );
1153 }
1154 
1155 template <typename... Args>
1156 auto deref(const RAH_STD::tuple<Args...>& t) {
1157  return deref_impl(t, RAH_STD::make_index_sequence<sizeof...(Args)>{});
1158 }
1159 
1160 template <size_t Index>
1161 struct Equal
1162 {
1163  template <typename... Args>
1164  bool operator()(RAH_STD::tuple<Args...> const& a, RAH_STD::tuple<Args...> const& b) const
1165  {
1166  return (RAH_STD::get<Index - 1>(a) == RAH_STD::get<Index - 1>(b)) || Equal<Index - 1>{}(a, b);
1167  }
1168 };
1169 
1170 template<>
1171 struct Equal<0>
1172 {
1173  template <typename... Args>
1174  bool operator()(RAH_STD::tuple<Args...> const&, RAH_STD::tuple<Args...> const&) const
1175  {
1176  return false;
1177  }
1178 };
1179 
1180 template <typename... Args>
1181 auto equal(RAH_STD::tuple<Args...> const& a, RAH_STD::tuple<Args...> const& b)
1182 {
1183  return Equal<sizeof...(Args)>{}(a, b);
1184 }
1185 
1186 } // namespace details
1188 
1189 template<typename IterTuple>
1190 struct zip_iterator : iterator_facade<
1191  zip_iterator<IterTuple>,
1192  decltype(details::deref(fake<IterTuple>())),
1193  RAH_STD::bidirectional_iterator_tag
1194 >
1195 {
1196  IterTuple iters_;
1197  zip_iterator() = default;
1198  zip_iterator(IterTuple const& iters) : iters_(iters) {}
1199  void increment() { details::for_each(iters_, [](auto& iter) { ++iter; }); }
1200  void advance(intptr_t val) { for_each(iters_, [val](auto& iter) { iter += val; }); }
1201  void decrement() { details::for_each(iters_, [](auto& iter) { --iter; }); }
1202  auto dereference() const { return details::deref(iters_); }
1203  auto distance_to(zip_iterator other) const { return RAH_STD::get<0>(iters_) - RAH_STD::get<0>(other.iters_); }
1204  bool equal(zip_iterator other) const { return details::equal(iters_, other.iters_); }
1205 };
1206 
1207 template<typename ...R> auto zip(R&&... _ranges)
1208 {
1209  auto iterTup = RAH_STD::make_tuple(begin(RAH_STD::forward<R>(_ranges))...);
1210  auto endTup = RAH_STD::make_tuple(end(RAH_STD::forward<R>(_ranges))...);
1211  return iterator_range<zip_iterator<decltype(iterTup)>>{ { iterTup }, { endTup }};
1212 }
1213 
1214 // ************************************ chunk *****************************************************
1215 
1216 template<typename R>
1217 struct chunk_iterator : iterator_facade<chunk_iterator<R>, iterator_range<range_begin_type_t<R>>, RAH_STD::forward_iterator_tag>
1218 {
1219  range_begin_type_t<R> iter_;
1220  range_begin_type_t<R> iter2_;
1221  range_end_type_t<R> end_;
1222  size_t step_;
1223 
1225  range_begin_type_t<R> const& iter,
1226  range_begin_type_t<R> const& iter2,
1227  range_end_type_t<R> const& end,
1228  size_t step = 0)
1229  : iter_(iter), iter2_(iter2), end_(end), step_(step)
1230  {
1231  }
1232 
1233  void increment()
1234  {
1235  iter_ = iter2_;
1236  for (size_t i = 0; i != step_ and iter2_ != end_; ++i)
1237  ++iter2_;
1238  }
1239 
1240  auto dereference() const { return make_iterator_range(iter_, iter2_); }
1241  bool equal(chunk_iterator other) const { return iter_ == other.iter_; }
1242 };
1243 
1244 template<typename R> auto chunk(R&& range, size_t step)
1245 {
1246  auto iter = begin(range);
1247  auto endIter = end(range);
1248  using iterator = chunk_iterator<RAH_STD::remove_reference_t<R>>;
1249  iterator begin = { iter, iter, endIter, step };
1250  begin.increment();
1251  return iterator_range<iterator>{ { begin }, { endIter, endIter, endIter, step }};
1252 }
1253 
1254 inline auto chunk(size_t step)
1255 {
1256  return make_pipeable([=](auto&& range) {return chunk(range, step); });
1257 }
1258 
1259 // ***************************************** filter ***********************************************
1260 
1261 template<typename R, typename F>
1262 struct filter_iterator : iterator_facade<filter_iterator<R, F>, range_ref_type_t<R>, RAH_STD::bidirectional_iterator_tag>
1263 {
1267  range_end_type_t<R> end_;
1268  RAH_NAMESPACE::details::optional<F> func_;
1269  typename RAH_STD::iterator_traits<range_begin_type_t<R>>::pointer value_pointer_;
1270 
1271  // Get a pointer to the pointed value,
1272  // OR a pointer to a copy of the pointed value (when not a reference iterator)
1273  template <class I> struct get_pointer
1274  {
1275  static auto get(I const& iter) { return iter.operator->(); }
1276  };
1277  template <class V> struct get_pointer<V*>
1278  {
1279  static auto get(V* ptr) { return ptr; }
1280  };
1281 
1284  range_begin_type_t<R> const& iter,
1285  range_end_type_t<R> const& end,
1286  F func)
1287  : begin_(begin), iter_(iter), end_(end), func_(func)
1288  {
1289  next_value();
1290  }
1291 
1292  void next_value()
1293  {
1294  while (iter_ != end_ && not (*func_)(*(value_pointer_ = get_pointer<Iterator>::get(iter_))))
1295  {
1296  assert(iter_ != end_);
1297  ++iter_;
1298  }
1299  }
1300 
1301  void increment()
1302  {
1303  ++iter_;
1304  next_value();
1305  }
1306 
1307  void decrement()
1308  {
1309  do
1310  {
1311  --iter_;
1312  } while (not (*func_)(*iter_) && iter_ != begin_);
1313  }
1314 
1315  auto dereference() const -> decltype(*iter_) { return *value_pointer_; }
1316  bool equal(filter_iterator other) const { return iter_ == other.iter_; }
1317 };
1318 
1319 template<typename R, typename F> auto filter(R&& range, F&& func)
1320 {
1321  auto iter = begin(range);
1322  auto endIter = end(range);
1323  using Predicate = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
1325  { iter, iter, endIter, func },
1326  { iter, endIter, endIter, func }
1327  };
1328 }
1329 
1330 template<typename F> auto filter(F&& func)
1331 {
1332  return make_pipeable([=](auto&& range) {return filter(range, func); });
1333 }
1334 
1335 // ***************************************** concat ***********************************************
1336 
1337 template<typename IterPair, typename V>
1338 struct concat_iterator : iterator_facade<concat_iterator<IterPair, V>, V, RAH_STD::forward_iterator_tag>
1339 {
1340  IterPair iter_;
1341  IterPair end_;
1342  size_t range_index_;
1343 
1344  concat_iterator(IterPair const& iter, IterPair const& end, size_t range_index)
1345  : iter_(iter), end_(end), range_index_(range_index)
1346  {
1347  }
1348 
1349  void increment()
1350  {
1351  if (range_index_ == 0)
1352  {
1353  auto& i = RAH_STD::get<0>(iter_);
1354  ++i;
1355  if (i == RAH_STD::get<0>(end_))
1356  range_index_ = 1;
1357  }
1358  else
1359  ++RAH_STD::get<1>(iter_);
1360  }
1361 
1362  auto dereference() const -> decltype(*RAH_STD::get<0>(iter_))
1363  {
1364  if (range_index_ == 0)
1365  return *RAH_STD::get<0>(iter_);
1366  else
1367  return *RAH_STD::get<1>(iter_);
1368  }
1369 
1370  bool equal(concat_iterator other) const
1371  {
1372  if (range_index_ != other.range_index_)
1373  return false;
1374  if (range_index_ == 0)
1375  return RAH_STD::get<0>(iter_) == RAH_STD::get<0>(other.iter_);
1376  else
1377  return RAH_STD::get<1>(iter_) == RAH_STD::get<1>(other.iter_);
1378  }
1379 };
1380 
1382 template<typename R1> auto concat(R1&& range1)
1383 {
1384  return RAH_STD::forward<R1>(range1);
1385 }
1386 
1387 template<typename R1, typename R2> auto concat(R1&& range1, R2&& range2)
1388 {
1389  auto begin_range1 = RAH_STD::make_pair(begin(range1), begin(range2));
1390  auto begin_range2 = RAH_STD::make_pair(end(range1), end(range2));
1391  auto end_range1 = RAH_STD::make_pair(end(range1), end(range2));
1392  auto end_range2 = RAH_STD::make_pair(end(range1), end(range2));
1393  return iterator_range<
1394  concat_iterator<
1395  RAH_STD::pair<range_begin_type_t<R1>, range_begin_type_t<R2>>,
1396  range_ref_type_t<R1>>>
1397  {
1398  { begin_range1, begin_range2, 0 },
1399  { end_range1, end_range2, 1 },
1400  };
1401 }
1402 
1404 template<typename R1, typename R2, typename ...Ranges>
1405 auto concat(R1&& range1, R2&& range2, Ranges&&... ranges)
1406 {
1407  return concat(concat(RAH_STD::forward<R1>(range1), RAH_STD::forward<R2>(range2)), ranges...);
1408 }
1409 
1410 // *************************** enumerate **********************************************************
1411 
1412 template<typename R> auto enumerate(R&& range)
1413 {
1414  size_t const dist = RAH_STD::distance(begin(RAH_STD::forward<R>(range)), end(RAH_STD::forward<R>(range)));
1415  return zip(iota(size_t(0), dist), RAH_STD::forward<R>(range));
1416 }
1417 
1418 inline auto enumerate()
1419 {
1420  return make_pipeable([=](auto&& range) {return enumerate(range); });
1421 }
1422 
1423 // ****************************** map_value ********************************************************
1424 
1425 template<typename R> auto map_value(R&& range)
1426 {
1427  return transform(RAH_STD::forward<R>(range), [](auto&& nvp) -> decltype(RAH_STD::get<1>(RAH_STD::forward<decltype(nvp)>(nvp)))
1428  {
1429  return RAH_STD::get<1>(RAH_STD::forward<decltype(nvp)>(nvp));
1430  });
1431 }
1432 
1433 inline auto map_value()
1434 {
1435  return make_pipeable([=](auto&& range) {return map_value(range); });
1436 }
1437 
1438 // ****************************** map_key **********************************************************
1439 
1440 template<typename R> auto map_key(R&& range)
1441 {
1442  return RAH_NAMESPACE::view::transform(RAH_STD::forward<R>(range), [](auto&& nvp) -> decltype(RAH_STD::get<0>(RAH_STD::forward<decltype(nvp)>(nvp)))
1443  {
1444  return RAH_STD::get<0>(RAH_STD::forward<decltype(nvp)>(nvp));
1445  });
1446 }
1447 
1448 inline auto map_key()
1449 {
1450  return make_pipeable([=](auto&& range) {return map_key(range); });
1451 }
1452 
1453 // *********************************** sort *******************************************************
1454 
1461 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
1462 auto sort(R&& range, P&& pred = {})
1463 {
1464  using value_type = range_value_type_t<R>;
1465  using Container = typename RAH_STD::vector<value_type>;
1466  Container result;
1467  result.reserve(RAH_STD::distance(begin(range), end(range)));
1468  RAH_STD::copy(begin(range), end(range), RAH_STD::back_inserter(result));
1469  RAH_STD::sort(begin(result), end(result), pred);
1470  return result;
1471 }
1472 
1480 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
1481 auto sort(P&& pred = {})
1482 {
1483  return make_pipeable([=](auto&& range) { return view::sort(RAH_STD::forward<decltype(range)>(range), pred); });
1484 }
1485 
1486 } // namespace view
1487 
1488 // ****************************************** empty ***********************************************
1489 
1493 template<typename R> bool empty(R&& range)
1494 {
1495  return begin(range) == end(range);
1496 }
1497 
1502 inline auto empty()
1503 {
1504  return make_pipeable([](auto&& range) {return empty(range); });
1505 }
1506 
1507 // ****************************************** equal_range ***********************************************
1508 
1512 template<typename R, typename V>
1513 auto equal_range(R&& range, V&& value, RAH_STD::enable_if_t<is_range<R>::value, int> = 0)
1514 {
1515  auto pair = RAH_STD::equal_range(begin(range), end(range), RAH_STD::forward<V>(value));
1516  return make_iterator_range(RAH_STD::get<0>(pair), RAH_STD::get<1>(pair));
1517 }
1518 
1523 template<typename V> auto equal_range(V&& value)
1524 {
1525  return make_pipeable([=](auto&& range) {return equal_range(RAH_STD::forward<decltype(range)>(range), value); });
1526 }
1527 
1532 template<typename R, typename V, typename P>
1533 auto equal_range(R&& range, V&& value, P&& pred)
1534 {
1535  auto pair = RAH_STD::equal_range(begin(range), end(range), RAH_STD::forward<V>(value), RAH_STD::forward<P>(pred));
1536  return make_iterator_range(RAH_STD::get<0>(pair), RAH_STD::get<1>(pair));
1537 }
1538 
1544 template<typename V, typename P>
1545 auto equal_range(V&& value, P&& pred, RAH_STD::enable_if_t<!is_range<V>::value, int> = 0)
1546 {
1547  return make_pipeable([=](auto&& range) {return equal_range(RAH_STD::forward<decltype(range)>(range), value, pred); });
1548 }
1549 
1550 // ****************************************** binary_search ***********************************************
1551 
1555 template<typename R, typename V> auto binary_search(R&& range, V&& value)
1556 {
1557  return RAH_STD::binary_search(begin(range), end(range), RAH_STD::forward<V>(value));
1558 }
1559 
1564 template<typename V> auto binary_search(V&& value)
1565 {
1566  return make_pipeable([=](auto&& range) {return binary_search(RAH_STD::forward<decltype(range)>(range), value); });
1567 }
1568 
1569 // ****************************************** transform *******************************************
1570 
1574 template<typename RI, typename RO, typename F>
1575 auto transform(RI&& rangeIn, RO&& rangeOut, F&& unary_op)
1576 {
1577  return RAH_STD::transform(begin(rangeIn), end(rangeIn), begin(rangeOut), RAH_STD::forward<F>(unary_op));
1578 }
1579 
1583 template<typename RI1, typename RI2, typename RO, typename F>
1584 auto transform(RI1&& rangeIn1, RI2&& rangeIn2, RO&& rangeOut, F&& binary_op)
1585 {
1586  return RAH_STD::transform(
1587  begin(rangeIn1), end(rangeIn1),
1588  begin(rangeIn2),
1589  begin(rangeOut),
1590  RAH_STD::forward<F>(binary_op));
1591 }
1592 
1593 // ********************************************* reduce *******************************************
1594 
1598 template<typename R, typename I, typename F> auto reduce(R&& range, I&& init, F&& reducer)
1599 {
1600  return RAH_STD::accumulate(begin(range), end(range), RAH_STD::forward<I>(init), RAH_STD::forward<F>(reducer));
1601 }
1602 
1607 template<typename I, typename F>
1608 auto reduce(I&& init, F&& reducer)
1609 {
1610  return make_pipeable([=](auto&& range) {return reduce(range, init, reducer); });
1611 }
1612 
1613 // ************************* any_of *******************************************
1614 
1618 template<typename R, typename F> bool any_of(R&& range, F&& pred)
1619 {
1620  return RAH_STD::any_of(begin(range), end(range), RAH_STD::forward<F>(pred));
1621 }
1622 
1627 template<typename P> auto any_of(P&& pred)
1628 {
1629  return make_pipeable([=](auto&& range) {return any_of(range, pred); });
1630 }
1631 
1632 // ************************* all_of *******************************************
1633 
1637 template<typename R, typename P> bool all_of(R&& range, P&& pred)
1638 {
1639  return RAH_STD::all_of(begin(range), end(range), RAH_STD::forward<P>(pred));
1640 }
1641 
1646 template<typename P> auto all_of(P&& pred)
1647 {
1648  return make_pipeable([=](auto&& range) {return all_of(range, pred); });
1649 }
1650 
1651 // ************************* none_of *******************************************
1652 
1656 template<typename R, typename P> bool none_of(R&& range, P&& pred)
1657 {
1658  return RAH_STD::none_of(begin(range), end(range), RAH_STD::forward<P>(pred));
1659 }
1660 
1665 template<typename P> auto none_of(P&& pred)
1666 {
1667  return make_pipeable([=](auto&& range) {return none_of(range, pred); });
1668 }
1669 
1670 // ************************* count ****************************************************************
1671 
1675 template<typename R, typename V> auto count(R&& range, V&& value)
1676 {
1677  return RAH_STD::count(begin(range), end(range), RAH_STD::forward<V>(value));
1678 }
1679 
1684 template<typename V> auto count(V&& value)
1685 {
1686  return make_pipeable([=](auto&& range) {return count(range, value); });
1687 }
1688 
1693 template<typename R, typename P> auto count_if(R&& range, P&& pred)
1694 {
1695  return RAH_STD::count_if(begin(range), end(range), RAH_STD::forward<P>(pred));
1696 }
1697 
1701 template<typename P> auto count_if(P&& pred)
1702 {
1703  return make_pipeable([=](auto&& range) {return count_if(range, pred); });
1704 }
1705 
1706 // ************************* foreach **************************************************************
1707 
1711 template<typename R, typename F> auto for_each(R&& range, F&& func)
1712 {
1713  return ::RAH_STD::for_each(begin(range), end(range), RAH_STD::forward<F>(func));
1714 }
1715 
1720 template<typename F> auto for_each(F&& func)
1721 {
1722  return make_pipeable([=](auto&& range) {return for_each(range, func); });
1723 }
1724 
1725 // ***************************** to_container *****************************************************
1726 
1730 template<typename C, typename R> auto to_container(R&& range)
1731 {
1732  return C(begin(range), end(range));
1733 }
1734 
1739 template<typename C> auto to_container()
1740 {
1741  return make_pipeable([=](auto&& range) {return to_container<C>(range); });
1742 }
1743 
1744 // ************************* mismatch *************************************************************
1745 
1749 template<typename R1, typename R2> auto mismatch(R1&& range1, R2&& range2)
1750 {
1751  return RAH_STD::mismatch(begin(range1), end(range1), begin(range2), end(range2));
1752 }
1753 
1754 // ****************************************** find ************************************************
1755 
1759 template<typename R, typename V> auto find(R&& range, V&& value)
1760 {
1761  return RAH_STD::find(begin(range), end(range), RAH_STD::forward<V>(value));
1762 }
1763 
1768 template<typename V> auto find(V&& value)
1769 {
1770  return make_pipeable([=](auto&& range) {return find(range, value); });
1771 }
1772 
1776 template<typename R, typename P> auto find_if(R&& range, P&& pred)
1777 {
1778  return RAH_STD::find_if(begin(range), end(range), RAH_STD::forward<P>(pred));
1779 }
1780 
1785 template<typename P> auto find_if(P&& pred)
1786 {
1787  return make_pipeable([=](auto&& range) {return find_if(range, pred); });
1788 }
1789 
1793 template<typename R, typename P> auto find_if_not(R&& range, P&& pred)
1794 {
1795  return RAH_STD::find_if_not(begin(range), end(range), RAH_STD::forward<P>(pred));
1796 }
1797 
1802 template<typename P> auto find_if_not(P&& pred)
1803 {
1804  return make_pipeable([=](auto&& range) {return find_if_not(range, pred); });
1805 }
1806 
1807 // ************************************* max_element **********************************************
1808 
1812 template<typename R, RAH_STD::enable_if_t<is_range<R>::value, int> = 0>
1813 auto max_element(R&& range)
1814 {
1815  return RAH_STD::max_element(begin(range), end(range));
1816 }
1817 
1822 inline auto max_element()
1823 {
1824  return make_pipeable([=](auto&& range) {return max_element(range); });
1825 }
1826 
1830 template<typename R, typename P> auto max_element(R&& range, P&& pred)
1831 {
1832  return RAH_STD::max_element(begin(range), end(range), RAH_STD::forward<P>(pred));
1833 }
1834 
1839 template<typename P, RAH_STD::enable_if_t<!is_range<P>::value, int> = 0>
1840 auto max_element(P&& pred)
1841 {
1842  return make_pipeable([=](auto&& range) {return max_element(range, pred); });
1843 }
1844 
1845 // ************************************* min_element **********************************************
1846 
1850 template<typename R, RAH_STD::enable_if_t<is_range<R>::value, int> = 0>
1851 auto min_element(R&& range)
1852 {
1853  return RAH_STD::min_element(begin(range), end(range));
1854 }
1855 
1860 inline auto min_element()
1861 {
1862  return make_pipeable([=](auto&& range) {return min_element(range); });
1863 }
1864 
1868 template<typename R, typename P> auto min_element(R&& range, P&& pred)
1869 {
1870  return RAH_STD::min_element(begin(range), end(range), RAH_STD::forward<P>(pred));
1871 }
1872 
1877 template<typename P, RAH_STD::enable_if_t<!is_range<P>::value, int> = 0>
1878 auto min_element(P&& pred)
1879 {
1880  return make_pipeable([=](auto&& range) {return min_element(range, pred); });
1881 }
1882 
1883 // *************************************** copy ***************************************************
1884 
1889 template<typename R1, typename R2> auto copy(R1&& in, R2&& out)
1890 {
1891  return RAH_STD::copy(begin(in), end(in), begin(out));
1892 }
1893 
1899 template<typename R2> auto copy(R2&& out)
1900 {
1901  auto all_out = out | RAH_NAMESPACE::view::all();
1902  return make_pipeable([=](auto&& in) {return copy(in, all_out); });
1903 }
1904 
1905 // *************************************** fill ***************************************************
1906 
1910 template<typename R1, typename V> auto fill(R1&& in, V&& value)
1911 {
1912  return RAH_STD::fill(begin(in), end(in), value);
1913 }
1914 
1919 template<typename V> auto fill(V&& value)
1920 {
1921  return make_pipeable([=](auto&& out) {return fill(out, value); });
1922 }
1923 
1924 // *************************************** back_insert ***************************************************
1925 
1929 template<typename R1, typename R2> auto back_insert(R1&& in, R2&& out)
1930 {
1931  return copy(in, RAH_NAMESPACE::back_inserter(out));
1932 }
1933 
1938 template<typename R2> auto back_insert(R2&& out)
1939 {
1940  return make_pipeable([&](auto&& in) {return back_insert(in, out); });
1941 }
1942 
1943 // *************************************** copy_if ***************************************************
1944 
1949 template<typename R1, typename R2, typename P> auto copy_if(R1&& in, R2&& out, P&& pred)
1950 {
1951  return RAH_STD::copy_if(begin(in), end(in), begin(out), RAH_STD::forward<P>(pred));
1952 }
1953 
1959 template<typename R2, typename P> auto copy_if(R2&& out, P&& pred)
1960 {
1961  auto all_out = out | RAH_NAMESPACE::view::all();
1962  return make_pipeable([=](auto&& in) {return copy_if(in, all_out, pred); });
1963 }
1964 
1965 // *************************************** size ***************************************************
1966 
1970 template<typename R> auto size(R&& range)
1971 {
1972  return RAH_STD::distance(begin(range), end(range));
1973 }
1974 
1979 inline auto size()
1980 {
1981  return make_pipeable([=](auto&& range) { return size(range); });
1982 }
1983 
1984 // *************************************** equal **************************************************
1985 
1989 template<typename R1, typename R2> auto equal(R1&& range1, R2&& range2)
1990 {
1991 #ifdef EASTL_VERSION
1992  return RAH_STD::identical(begin(range1), end(range1), begin(range2), end(range2));
1993 #else
1994  return RAH_STD::equal(begin(range1), end(range1), begin(range2), end(range2));
1995 #endif
1996 }
1997 
2002 template<typename R1> auto equal(R1&& range2)
2003 {
2004  auto all_range2 = range2 | RAH_NAMESPACE::view::all();
2005  return make_pipeable([=](auto&& range1) { return equal(RAH_STD::forward<decltype(range1)>(range1), all_range2); });
2006 }
2007 
2008 // *********************************** stream_inserter ********************************************
2009 
2010 template<typename S>
2011 struct stream_inserter_iterator : iterator_facade<stream_inserter_iterator<S>, typename S::char_type, RAH_STD::output_iterator_tag>
2012 {
2013  S* stream_;
2014  stream_inserter_iterator(S& stream) : stream_(&stream) { }
2015  template<typename V> void put(V&& value) const { (*stream_) << value; }
2016 };
2017 
2021 template<typename S> auto stream_inserter(S&& stream)
2022 {
2023  using Stream = RAH_STD::remove_reference_t<S>;
2024  auto begin = stream_inserter_iterator<Stream>(stream);
2025  auto end = stream_inserter_iterator<Stream>(stream);
2027 }
2028 
2029 // *********************************** remove_if **************************************************
2030 
2035 template<typename R, typename P> auto remove_if(R&& range, P&& pred)
2036 {
2037  return RAH_STD::remove_if(begin(range), end(range), RAH_STD::forward<P>(pred));
2038 }
2039 
2045 template<typename P> auto remove_if(P&& pred)
2046 {
2047  return make_pipeable([=](auto&& range) { return remove_if(range, pred); });
2048 }
2049 
2050 // *********************************** remove *****************************************************
2051 
2056 template<typename R, typename V> auto remove(R&& range, V&& value)
2057 {
2058  return RAH_STD::remove(begin(range), end(range), RAH_STD::forward<V>(value));
2059 }
2060 
2066 template<typename V> auto remove(V&& value)
2067 {
2068  return make_pipeable([=](auto&& range) { return remove(RAH_STD::forward<decltype(range)>(range), value); });
2069 }
2070 
2071 // *********************************** partition **************************************************
2072 
2079 template<typename R, typename P> auto partition(R&& range, P&& pred)
2080 {
2081  return RAH_STD::partition(begin(range), end(range), RAH_STD::forward<P>(pred));
2082 }
2083 
2088 template<typename P> auto partition(P&& pred)
2089 {
2090  return make_pipeable([=](auto&& range) { return partition(range, pred); });
2091 }
2092 
2093 // *********************************** stable_partition *******************************************
2094 
2101 template<typename R, typename P> auto stable_partition(R&& range, P&& pred)
2102 {
2103  return RAH_STD::stable_partition(begin(range), end(range), RAH_STD::forward<P>(pred));
2104 }
2105 
2110 template<typename P> auto stable_partition(P&& pred)
2111 {
2112  return make_pipeable([=](auto&& range) { return stable_partition(range, pred); });
2113 }
2114 
2115 // *********************************** erase ******************************************************
2116 
2121 template<typename C, typename R> auto erase(C&& container, R&& subrange)
2122 {
2123  container.erase(begin(subrange), end(subrange));
2124  return container | RAH_NAMESPACE::view::all();
2125 }
2126 
2132 template<typename R> auto erase(R&& range)
2133 {
2134  auto all_range = range | RAH_NAMESPACE::view::all();
2135  return make_pipeable([=](auto&& cont) { return RAH_NAMESPACE::erase(cont, all_range); });
2136 }
2137 
2138 // *********************************** sort *******************************************************
2139 
2144 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
2145 void sort(R& range, P&& pred = {})
2146 {
2147  RAH_STD::sort(begin(range), end(range), pred);
2148 }
2149 
2155 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2156 auto sort(P&& pred = {})
2157 {
2158  return make_pipeable([=](auto& range) { return sort(range, pred); });
2159 }
2160 
2161 // *********************************** stable_sort ************************************************
2162 
2167 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
2168 void stable_sort(R& range, P&& pred = {})
2169 {
2170  RAH_STD::stable_sort(begin(range), end(range), pred);
2171 }
2172 
2178 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2179 auto stable_sort(P&& pred = {})
2180 {
2181  return make_pipeable([=](auto& range) { return stable_sort(range, pred); });
2182 }
2183 
2184 // *********************************** shuffle *******************************************************
2185 
2189 template<typename R, typename URBG>
2190 void shuffle(R& range, URBG&& g)
2191 {
2192  RAH_STD::shuffle(begin(range), end(range), RAH_STD::forward<URBG>(g));
2193 }
2194 
2199 template<typename URBG>
2200 auto shuffle(URBG&& g)
2201 {
2202  return make_pipeable([&g](auto& range) { return RAH_NAMESPACE::shuffle(range, g); });
2203 }
2204 
2205 // *********************************** unique *****************************************************
2206 
2208 struct is_equal
2209 {
2210  template<typename A, typename B> bool operator()(A&& a, B&& b) { return a == b; }
2211 };
2212 
2218 template<typename R, typename P = is_equal, typename = RAH_STD::enable_if_t<is_range<R>::value>>
2219 auto unique(R&& range, P&& pred = {})
2220 {
2221  return RAH_STD::unique(begin(range), end(range), pred);
2222 }
2223 
2230 template<typename P = is_equal, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2231 auto unique(P&& pred = {})
2232 {
2233  return make_pipeable([=](auto&& range) { return unique(RAH_STD::forward<decltype(range)>(range), pred); });
2234 }
2235 
2236 // *********************************** set_difference ************************************************
2237 
2242 template<typename IN1, typename IN2, typename OUT_>
2243 void set_difference(IN1&& in1, IN2&& in2, OUT_&& out)
2244 {
2246  begin(in1), end(in1),
2247  begin(in2), end(in2),
2248  begin(out));
2249 }
2250 
2251 // *********************************** set_intersection ************************************************
2252 
2257 template<typename IN1, typename IN2, typename OUT_>
2258 void set_intersection(IN1&& in1, IN2&& in2, OUT_&& out)
2259 {
2261  begin(in1), end(in1),
2262  begin(in2), end(in2),
2263  begin(out));
2264 }
2265 
2266 namespace action
2267 {
2268 
2269 // *********************************** unique *****************************************************
2270 
2276 template<typename C, typename P = is_equal, typename = RAH_STD::enable_if_t<is_range<C>::value>>
2277 auto&& unique(C&& container, P&& pred = {})
2278 {
2279  container.erase(RAH_NAMESPACE::unique(container, pred), container.end());
2280  return RAH_STD::forward<C>(container);
2281 }
2282 
2289 template<typename P = is_equal, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2290 auto unique(P&& pred = {})
2291 {
2292  return make_pipeable([=](auto&& range) -> auto&& { return action::unique(RAH_STD::forward<decltype(range)>(range), pred); });
2293 }
2294 
2295 // *********************************** remove_if **************************************************
2296 
2301 template<typename C, typename P> auto&& remove_if(C&& container, P&& pred)
2302 {
2303  container.erase(RAH_NAMESPACE::remove_if(container, RAH_STD::forward<P>(pred)), container.end());
2304  return RAH_STD::forward<C>(container);
2305 }
2306 
2312 template<typename P> auto remove_if(P&& pred)
2313 {
2314  return make_pipeable([=](auto&& range) -> auto&& { return remove_if(RAH_STD::forward<decltype(range)>(range), pred); });
2315 }
2316 
2317 // *********************************** remove *****************************************************
2318 
2323 template<typename C, typename V> auto&& remove(C&& container, V&& value)
2324 {
2325  container.erase(RAH_NAMESPACE::remove(container, RAH_STD::forward<V>(value)), container.end());
2326  return RAH_STD::forward<C>(container);
2327 }
2328 
2334 template<typename V> auto remove(V&& value)
2335 {
2336  return make_pipeable([=](auto&& range) -> auto&& { return remove(RAH_STD::forward<decltype(range)>(range), value); });
2337 }
2338 
2339 // *********************************** sort *******************************************************
2340 
2346 template<typename C, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<C>::value>>
2347 auto&& sort(C&& container, P&& pred = {})
2348 {
2349  RAH_NAMESPACE::sort(container, pred);
2350  return RAH_STD::forward<C>(container);
2351 }
2352 
2359 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2360 auto sort(P&& pred = {})
2361 {
2362  return make_pipeable([=](auto&& range) -> auto&& { return action::sort(RAH_STD::forward<decltype(range)>(range), pred); });
2363 }
2364 
2365 // *********************************** shuffle *******************************************************
2366 
2371 template<typename C, typename URBG>
2372 auto&& shuffle(C&& container, URBG&& g)
2373 {
2374  URBG gen = RAH_STD::forward<URBG>(g);
2375  RAH_NAMESPACE::shuffle(container, gen);
2376  return RAH_STD::forward<C>(container);
2377 }
2378 
2384 template<typename URBG>
2385 auto shuffle(URBG&& g)
2386 {
2387  return make_pipeable([&](auto&& range) -> auto&& { return action::shuffle(RAH_STD::forward<decltype(range)>(range), g); });
2388 }
2389 
2390 // *************************************** fill ***************************************************
2391 
2395 template<typename R1, typename V> auto fill(R1&& in, V&& value)
2396 {
2397  RAH_STD::fill(begin(in), end(in), value);
2398  return RAH_STD::forward<R1>(in);
2399 }
2400 
2405 template<typename V> auto fill(V&& value)
2406 {
2407  return make_pipeable([=](auto&& out) {return RAH_NAMESPACE::action::fill(out, value); });
2408 }
2409 
2410 } // namespace action
2411 
2412 } // namespace rah
auto sliding(size_t n)
Given a range and a count n, place a window over the first n elements of the underlying range.
Definition: rah.hpp:515
void decrement()
Definition: rah.hpp:666
std ::remove_reference_t< range_ref_type_t< T > > range_value_type_t
Definition: rah - Copie.hpp:66
Definition: rah - Copie.hpp:555
void decrement()
Definition: rah.hpp:696
auto distance_to(iota_iterator other) const
Definition: rah.hpp:697
auto dereference() const
Definition: rah.hpp:884
Definition: rah - Copie.hpp:80
auto generate_n(size_t count, F &&func)
Definition: rah - Copie.hpp:785
auto distance_to(zip_iterator other) const
Definition: rah.hpp:1203
counted_iterator(I iter, size_t count)
Definition: rah.hpp:568
auto distance_to(counted_iterator r) const
Definition: rah.hpp:573
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:636
Definition: rah - Copie.hpp:500
void stable_sort(R &range, P &&pred={})
Sorts the elements in the range in ascending order.
Definition: rah - Copie.hpp:1891
auto map_key(R &&range)
Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pai...
Definition: rah - Copie.hpp:1260
void advance(intptr_t val)
Definition: rah.hpp:1200
concat_iterator(IterPair const &iter, IterPair const &end, size_t range_index)
Definition: rah.hpp:1344
auto binary_search(R &&range, V &&value)
Checks if an element equivalent to value appears within the range.
Definition: rah - Copie.hpp:1375
auto max_element(P &&pred)
Finds the greatest element in the range.
Definition: rah.hpp:1840
void set_difference(IN1 &&in1, IN2 &&in2, OUT_ &&out)
Copies the elements from the sorted range in1 which are not found in the sorted range in2 to the rang...
Definition: rah.hpp:2243
rah ::details::optional< SubRange > subRange_
Definition: rah.hpp:748
bool operator()(A &&a, B &&b)
Definition: rah.hpp:404
auto generate(F &&func)
Create an infinite range, repetitively calling func.
Definition: rah - Copie.hpp:779
static type to_pointer(Ref &&ref)
Definition: rah.hpp:250
auto stable_partition(R &&range, P &&pred)
Reorders the elements in the range in such a way that all elements for which the predicate pred retur...
Definition: rah - Copie.hpp:1824
auto operator+(intptr_t increment)
Definition: rah.hpp:351
bool has_value() const
Definition: rah.hpp:210
auto dereference() const -> decltype(*subRange_->subRangeIter)
Definition: rah.hpp:789
ints_iterator(T val)
Definition: rah.hpp:662
decltype(end(fake< T >())) range_end_type_t
Definition: rah - Copie.hpp:60
bool equal(chunk_iterator other) const
Definition: rah.hpp:1241
transform_iterator(range_begin_type_t< R > const &iter, F const &func)
Definition: rah.hpp:911
bool equal(filter_iterator other) const
Definition: rah.hpp:1316
auto fill(R1 &&in, V &&value)
Assigns the given value to the elements in the range [first, last)
Definition: rah - Copie.hpp:1654
T const * operator->() const
Definition: rah.hpp:228
auto drop_exactly(size_t count)
Given a source range and an integral count, return a range consisting of all but the first count elem...
Definition: rah.hpp:530
auto transform(R &&range, F &&func)
Create a view applying a transformation to each element of the input range.
Definition: rah - Copie.hpp:819
InputIt1 last1_
Definition: rah.hpp:952
auto closed_ints(T b=0, T e=std ::numeric_limits< T >::max() - 1)
Generate a range of monotonically increasing ints.
Definition: rah.hpp:677
void increment()
Definition: rah.hpp:722
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:442
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:851
auto equal_range(R &&range, V &&value, std ::enable_if_t< is_range< R >::value, int >=0)
Returns a range containing all elements equivalent to value in the range.
Definition: rah - Copie.hpp:1333
auto chunk(R &&range, size_t step)
Create a view where each element is a range of N elements of the input range.
Definition: rah - Copie.hpp:1074
void decrement()
Definition: rah.hpp:617
void advance(intptr_t value)
Definition: rah.hpp:665
Iterator iter_
Definition: rah.hpp:1266
I end() const
Definition: rah.hpp:87
bool equal(sliding_iterator const &r) const
Definition: rah.hpp:490
Definition: rah.hpp:462
join_iterator(U &&range, Iterator1 rangeIter, Iterator2 subRangeIter, Iterator2 subRangeEnd)
Definition: rah.hpp:751
Definition: rah - Copie.hpp:630
#define assert(CONDITION)
Definition: test.cpp:40
rah ::details::optional< F > func_
Definition: rah.hpp:909
Definition: rah - Copie.hpp:1158
void increment()
Definition: rah.hpp:784
bool operator==(I other) const
Definition: rah.hpp:311
bool equal(concat_iterator other) const
Definition: rah.hpp:1370
void increment()
Definition: rah.hpp:438
I begin() const
Definition: rah.hpp:85
bool none_of(R &&range, P &&pred)
Checks if unary predicate pred returns true for no elements in the range.
Definition: rah - Copie.hpp:1476
range_begin_type_t< R > Iterator
Definition: rah.hpp:1264
void increment()
Definition: rah.hpp:1349
bool equal(unbounded_iterator r) const
Definition: rah.hpp:637
rah ::details::optional< F > func_
Definition: rah.hpp:1268
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:1315
Definition: rah - Copie.hpp:1047
optional & operator=(T &&other)
Definition: rah.hpp:202
bool equal(generate_iterator) const
Definition: rah.hpp:885
void set_intersection(IN1 &&in1, IN2 &&in2, OUT_ &&out)
Copies the elements from the sorted range in1 which are also found in the sorted range in2 to the ran...
Definition: rah.hpp:2258
unbounded_iterator(I iter, bool end)
Definition: rah.hpp:612
auto operator[](intptr_t increment) const
Definition: rah.hpp:376
constexpr intptr_t End
Used with rah::view::slice to point to the end.
Definition: rah - Copie.hpp:45
void increment()
Definition: rah.hpp:1199
auto copy_if(R1 &&in, R2 &&out, P &&pred)
Copies the elements for which the predicate pred returns true.
Definition: rah - Copie.hpp:1693
repeat_iterator(U val)
Definition: rah.hpp:720
void increment()
Definition: rah.hpp:1301
auto mismatch(R1 &&range1, R2 &&range2)
Finds the first position where two ranges differ.
Definition: rah - Copie.hpp:1569
auto size(R &&range)
Get the size of range.
Definition: rah - Copie.hpp:1714
auto dereference() const
Definition: rah.hpp:484
I end()
Definition: rah.hpp:88
auto enumerate(R &&range)
Pair each element of a range with its index.
Definition: rah - Copie.hpp:1232
auto min_element(P &&pred)
Finds the smallest element in the range.
Definition: rah.hpp:1878
bool equal(stride_iterator other) const
Definition: rah.hpp:1074
auto distance_to(ints_iterator other) const
Definition: rah.hpp:667
auto all(R &&range)
Create a view on the whole range.
Definition: rah - Copie.hpp:407
auto dereference() const -> decltype(*first1_)
Definition: rah.hpp:983
void decrement()
Definition: rah.hpp:724
Definition: rah - Copie.hpp:881
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:1073
Definition: rah.hpp:945
zip_iterator(IterTuple const &iters)
Definition: rah.hpp:1198
typename std ::iterator_traits< range_begin_type_t< R > >::iterator_category range_iter_categ_t
Definition: rah - Copie.hpp:69
generate_iterator(F const &func)
Definition: rah.hpp:881
auto distance_to(stride_iterator other) const
Definition: rah.hpp:1075
typename pointer_type< R >::type pointer
Definition: rah - Copie.hpp:153
void advance(intptr_t value)
Definition: rah.hpp:723
bool equal(take_iterator r) const
Definition: rah.hpp:443
T * operator->()
Definition: rah.hpp:227
Definition: rah - Copie.hpp:607
bool equal(repeat_iterator) const
Definition: rah.hpp:726
#define RAH_STD
Definition: rah.hpp:29
I subRangeLast_
Definition: rah.hpp:471
InputIt2 last2_
Definition: rah.hpp:954
auto dereference() const -> decltype(*iter_)
Definition: rah.hpp:574
void advance(intptr_t value)
Definition: rah.hpp:695
auto operator=(V &&value) const
Definition: rah.hpp:314
auto cycle(R &&range)
Returns an infinite range that endlessly repeats the source range.
Definition: rah - Copie.hpp:749
auto dereference() const -> decltype(*std ::get< 0 >(iter_))
Definition: rah.hpp:1362
auto make_iterator_range(I b, I e)
Create a rah::iterator_range with two given iterators.
Definition: rah - Copie.hpp:92
Iterator begin_
Definition: rah.hpp:1265
auto join(R &&range_of_ranges)
Given a range of ranges, join them into a flattened sequence of elements.
Definition: rah - Copie.hpp:691
bool equal(counted_iterator r) const
Definition: rah.hpp:575
auto sort(R &&range, P &&pred={})
Make a sorted view of a range.
Definition: rah - Copie.hpp:1282
auto take(R &&range, size_t count)
Given a source range and an integral count, return a range consisting of the first count elements fro...
Definition: rah - Copie.hpp:440
void next_valid()
Definition: rah.hpp:768
auto iota(T b, T e, T step=1)
Generate a range of sequential integers, increasing by a defined step.
Definition: rah - Copie.hpp:595
auto count_if(R &&range, P &&pred)
Counts elements for which predicate pred returns true.
Definition: rah - Copie.hpp:1513
Definition: rah - Copie.hpp:768
void advance(intptr_t value)
Definition: rah.hpp:1072
auto back_insert(R1 &&in, R2 &&out)
Insert in in back of front
Definition: rah - Copie.hpp:1673
void increment()
Definition: rah.hpp:570
void decrement()
Definition: rah.hpp:922
T * begin(T(&array)[N])
Definition: rah - Copie.hpp:49
void increment()
Definition: rah.hpp:920
auto make_pipeable(MakeRange &&make_range)
Call to create a "pipeable" function (UFCS style in c++)
Definition: rah - Copie.hpp:115
std ::remove_reference_t< R > value_type
Definition: rah - Copie.hpp:181
auto operator-(intptr_t increment)
Definition: rah.hpp:364
transform_iterator & operator=(transform_iterator const &ot)
Definition: rah.hpp:913
auto reduce(R &&range, I &&init, F &&reducer)
Executes a reducer function on each element of the range, resulting in a single output value.
Definition: rah - Copie.hpp:1418
auto dereference() const
Definition: rah.hpp:1202
back_insert_iterator(C &container)
Definition: rah.hpp:386
auto find_if(R &&range, P &&pred)
Finds the first element satisfying specific criteria.
Definition: rah - Copie.hpp:1596
optional(T const &other)
Definition: rah.hpp:191
bool operator>=(I other) const
Definition: rah.hpp:375
bool operator!=(I other) const
Definition: rah.hpp:310
auto find(R &&range, V &&value)
Finds the first element equal to value.
Definition: rah - Copie.hpp:1579
auto dereference() const
Definition: rah.hpp:698
decltype(begin(fake< T >())) range_begin_type_t
Definition: rah - Copie.hpp:57
auto concat(R1 &&range1)
return the same range
Definition: rah - Copie.hpp:1202
std ::forward_iterator_tag iterator_category
Definition: rah - Copie.hpp:180
auto retro(R &&range)
Create a view that traverses the source range in reverse order.
Definition: rah - Copie.hpp:924
auto stride(R &&range, size_t step)
Create a view consisting of every Nth element, starting with the first.
Definition: rah - Copie.hpp:909
cycle_iterator(U &&range, Iterator iter)
Definition: rah.hpp:837
void reset()
Definition: rah.hpp:212
bool equal(transform_iterator r) const
Definition: rah.hpp:925
void advance(intptr_t off)
Definition: rah.hpp:481
Definition: rah - Copie.hpp:456
auto equal(R1 &&range1, R2 &&range2)
Determines if two sets of elements are the same.
Definition: rah - Copie.hpp:1733
bool operator>(I other) const
Definition: rah.hpp:374
I subRangeBegin_
Definition: rah.hpp:470
bool equal(join_iterator other) const
Definition: rah.hpp:790
Inerit to make an iterator.
Definition: rah - Copie.hpp:128
auto & operator-=(intptr_t increment)
Definition: rah.hpp:358
bool operator!=(I other) const
Definition: rah.hpp:290
auto operator|(R &&range, pipeable< MakeRange > const &adapter) -> decltype(adapter.func(std ::forward< R >(range)))
Definition: rah - Copie.hpp:121
auto operator->() const
Definition: rah.hpp:289
stream_inserter_iterator(S &stream)
Definition: rah.hpp:2014
sliding_iterator(I subRangeBegin, I subRangeLast)
Definition: rah.hpp:474
InputIt1 first1_
Definition: rah.hpp:951
Definition: rah.hpp:132
void decrement()
Definition: rah.hpp:482
auto back_inserter(C &&container)
Make a range which insert into the back of the a container.
Definition: rah - Copie.hpp:276
void advance(intptr_t off)
Definition: rah.hpp:571
auto dereference() const
Definition: rah.hpp:668
optional & operator=(T const &other)
Definition: rah.hpp:196
T & fake()
Used in decltype to get an instance of a type.
Definition: rah - Copie.hpp:54
auto dereference() const
Definition: rah.hpp:1240
chunk_iterator(range_begin_type_t< R > const &iter, range_begin_type_t< R > const &iter2, range_end_type_t< R > const &end, size_t step=0)
Definition: rah.hpp:1224
bool empty(R &&range)
Check if the range if empty.
Definition: rah - Copie.hpp:1313
void increment()
Definition: rah.hpp:1233
auto distance_to(sliding_iterator const &r) const
Definition: rah.hpp:483
value_type * pointer
Definition: rah - Copie.hpp:183
Definition: rah - Copie.hpp:1092
void put(V &&value) const
Definition: rah.hpp:387
auto ints(T b=0, T e=std ::numeric_limits< T >::max())
Generate a range of monotonically increasing ints.
Definition: rah - Copie.hpp:570
intptr_t difference_type
Definition: rah - Copie.hpp:152
void decrement()
Definition: rah.hpp:1307
auto decrement()
Definition: rah.hpp:1066
take_iterator(I iter, size_t count)
Definition: rah.hpp:436
auto operator-(I other) const
Definition: rah.hpp:371
auto drop(size_t count)
Given a source range and an integral count, return a range consisting of all but the first count elem...
Definition: rah.hpp:550
void next_value()
Definition: rah.hpp:1292
void decrement()
Definition: rah.hpp:440
optional(optional const &other)
Definition: rah.hpp:135
Definition: rah - Copie.hpp:719
T const & get() const
Definition: rah.hpp:223
InputIt2 first2_
Definition: rah.hpp:953
bool operator==(I other) const
Definition: rah.hpp:291
void increment()
Definition: rah.hpp:883
intptr_t difference_type
Definition: rah - Copie.hpp:182
bool equal(cycle_iterator) const
Definition: rah.hpp:852
stride_iterator(range_begin_type_t< R > const &iter, range_end_type_t< R > const &end, size_t step)
Definition: rah.hpp:1057
V const & dereference() const
Definition: rah.hpp:725
void increment()
Definition: rah.hpp:978
Definition: rah - Copie.hpp:1020
bool equal(set_difference_iterator r) const
Definition: rah.hpp:984
Definition: rah - Copie.hpp:636
auto stream_inserter(S &&stream)
Make a range which output to a stream.
Definition: rah - Copie.hpp:1765
void decrement()
Definition: rah.hpp:1201
auto counted(I &&it, size_t n, decltype(++it, 0)=0)
Given an iterator it and a count n, create a range that starts at it and includes the next n elements...
Definition: rah - Copie.hpp:476
I begin()
Definition: rah.hpp:86
bool equal(ints_iterator other) const
Definition: rah.hpp:669
range_begin_type_t< decltype(*fake< Iterator1 >())> Iterator2
Definition: rah - Copie.hpp:634
void increment()
Definition: rah.hpp:614
void advance(intptr_t off)
Definition: rah.hpp:921
auto remove_if(R &&range, P &&pred)
Keep at the begining of the range only elements for which pred(elt) is false .
Definition: rah - Copie.hpp:1779
auto distance_to(transform_iterator r) const
Definition: rah.hpp:923
void next_value()
Definition: rah.hpp:962
static auto get(V *ptr)
Definition: rah.hpp:1279
bool all_of(R &&range, P &&pred)
Checks if unary predicate pred returns true for all elements in the range.
Definition: rah - Copie.hpp:1457
auto remove(V &&value)
Keep only elements not equal to value.
Definition: rah.hpp:2334
auto distance_to(take_iterator r) const
Definition: rah.hpp:441
decltype(*begin(fake< T >())) range_ref_type_t
Definition: rah - Copie.hpp:63
~optional()
Definition: rah.hpp:208
Definition: rah - Copie.hpp:793
rah ::details::optional< Reference > type
Definition: rah.hpp:248
auto to_container(R &&range)
Return a container of type C, filled with the content of range.
Definition: rah - Copie.hpp:1550
auto slice(R &&range, intptr_t begin_idx, intptr_t end_idx)
Create a view that is a sub-range of a range.
Definition: rah - Copie.hpp:848
auto filter(R &&range, F &&func)
Create a view with only elements which are filtered.
Definition: rah - Copie.hpp:1139
void increment()
Definition: rah.hpp:694
auto map_value(R &&range)
Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair...
Definition: rah - Copie.hpp:1245
Definition: rah - Copie.hpp:420
auto & operator+=(intptr_t increment)
Definition: rah.hpp:345
auto partition(R &&range, P &&pred)
Reorders the elements in the range in such a way that all elements for which the predicate pred retur...
Definition: rah - Copie.hpp:1802
void put(V &&value) const
Definition: rah.hpp:2015
void increment()
Definition: rah.hpp:845
void shuffle(R &range, URBG &&g)
Reorders the elements in the given range such that each possible permutation of those elements has eq...
Definition: rah - Copie.hpp:1913
auto zip(R &&... _ranges)
Given N ranges, return a new range where Mth element is the result of calling std::make_tuple on the ...
Definition: rah - Copie.hpp:1037
std ::remove_reference_t< R > value_type
Definition: rah - Copie.hpp:151
Definition: rah - Copie.hpp:579
bool operator<=(I other) const
Definition: rah.hpp:373
auto copy(R1 &&in, R2 &&out)
Copy in range into an other.
Definition: rah - Copie.hpp:1633
bool any_of(R &&range, F &&pred)
Checks if unary predicate pred returns true for at least one element in the range.
Definition: rah - Copie.hpp:1438
bool operator<(I other) const
Definition: rah.hpp:372
std ::forward_iterator_tag iterator_category
Definition: rah - Copie.hpp:150
T * end(T(&array)[N]) noexcept
Definition: rah - Copie.hpp:51
filter_iterator(range_begin_type_t< R > const &begin, range_begin_type_t< R > const &iter, range_end_type_t< R > const &end, F func)
Definition: rah.hpp:1282
void advance(intptr_t off)
Definition: rah.hpp:439
auto distance_to(unbounded_iterator r) const
Definition: rah.hpp:618
rah ::details::optional< F > func_
Definition: rah.hpp:879
T & get()
Definition: rah.hpp:221
set_difference_iterator(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
Definition: rah.hpp:956
auto count(R &&range, V &&value)
Counts the elements that are equal to value.
Definition: rah - Copie.hpp:1495
range_begin_type_t< R > Iterator1
Definition: rah - Copie.hpp:633
join_iterator(U &&range, Iterator1 rangeIter)
Definition: rah.hpp:762
auto unique(R &&range, P &&pred={})
Remove all but first successuve values which are equals.
Definition: rah - Copie.hpp:1942
auto erase(C &&container, R &&subrange)
Erase a sub-range of a given container.
Definition: rah - Copie.hpp:1844
range_begin_type_t< R > Iterator
Definition: rah - Copie.hpp:722
iota_iterator(T val, T step)
Definition: rah.hpp:692
void increment()
Definition: rah.hpp:480
auto dereference() const -> decltype((*func_)(*iter_))
Definition: rah.hpp:924
void decrement()
Definition: rah.hpp:572
bool equal(zip_iterator other) const
Definition: rah.hpp:1204
void increment()
Definition: rah.hpp:664
#define RAH_NAMESPACE
Definition: rah.hpp:39
static auto get(I const &iter)
Definition: rah.hpp:1275
bool equal(iota_iterator other) const
Definition: rah.hpp:699
bool operator()(A &&a, B &&b)
Definition: rah.hpp:2210
void advance(intptr_t off)
Definition: rah.hpp:616
auto for_each(R &&range, F &&func)
Lazily applies an unary function to each element in the source range that returns another range (poss...
Definition: rah - Copie.hpp:835
std ::iterator_traits< range_begin_type_t< R > >::pointer value_pointer_
Definition: rah.hpp:1269
auto increment()
Definition: rah.hpp:1060
auto repeat(V &&value)
Generate an infinite range of the given value.
Definition: rah - Copie.hpp:622
auto unbounded(I &&it)
Given an iterator, return an infinite range that begins at that position.
Definition: rah - Copie.hpp:543
auto single(V &&value)
Given value, create a view containing one element.
Definition: rah - Copie.hpp:938
auto find_if_not(R &&range, P &&pred)
Finds the first element not satisfying specific criteria.
Definition: rah - Copie.hpp:1613