rah
rah - Copie.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>
81 {
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 template<typename I, typename R, typename C> struct iterator_facade;
129 
130 template<typename I, typename R>
131 struct iterator_facade<I, R, RAH_STD::forward_iterator_tag>
132 {
133  template <class Reference>
134  struct pointer_type
135  {
136  struct type
137  {
138  Reference m_ref;
139  Reference const* operator->() const { return &m_ref; }
140  operator Reference const*() const { return &m_ref; }
141  };
142  };
143 
144  template <class T>
145  struct pointer_type<T&> // "real" references
146  {
147  using type = T*;
148  };
149 
150  using iterator_category = RAH_STD::forward_iterator_tag;
151  using value_type = RAH_STD::remove_reference_t<R>;
152  using difference_type = intptr_t;
153  using pointer = typename pointer_type<R>::type;
154  using reference = R;
155 
156  static_assert(not RAH_STD::is_reference<value_type>::value, "value_type can't be a reference");
157 
158  I& self() { return *static_cast<I*>(this); }
159  I const& self() const { return *static_cast<I const*>(this); }
160 
161  auto& operator++()
162  {
163  self().increment();
164  return *this;
165  }
166 
167  reference operator*() const
168  {
169  static_assert(RAH_STD::is_same<decltype(self().dereference()), reference>::value, "");
170  return self().dereference();
171  }
172  auto operator->() const { return pointer{ self().dereference() }; }
173  bool operator!=(I other) const { return not self().equal(other); }
174  bool operator==(I other) const { return self().equal(other); }
175 };
176 
177 template<typename I, typename R>
178 struct iterator_facade<I, R, RAH_STD::output_iterator_tag>
179 {
180  using iterator_category = RAH_STD::forward_iterator_tag;
181  using value_type = RAH_STD::remove_reference_t<R>;
182  using difference_type = intptr_t;
183  using pointer = value_type*;
184  using reference = R;
185 
186  static_assert(not RAH_STD::is_reference<value_type>::value, "value_type can't be a reference");
187 
188  I& self() { return *static_cast<I*>(this); }
189  I const& self() const { return *static_cast<I const*>(this); }
190 
191  auto& operator++() { return *this; }
192  auto& operator*() const { return *this; }
193  bool operator!=(I other) const { return true; }
194  bool operator==(I other) const { return false; }
195 
196  template<typename V>
197  auto operator=(V&& value) const
198  {
199  self().put(RAH_STD::forward<V>(value));
200  return self();
201  }
202 };
203 
204 
205 template<typename I, typename R>
206 struct iterator_facade<I, R, RAH_STD::bidirectional_iterator_tag> : iterator_facade<I, R, RAH_STD::forward_iterator_tag>
207 {
208  using iterator_category = RAH_STD::bidirectional_iterator_tag;
209 
210  I& self() { return *static_cast<I*>(this); }
211  I const& self() const { return *static_cast<I const*>(this); }
212 
213  auto& operator--()
214  {
215  self().decrement();
216  return *this;
217  }
218 };
219 
220 template<typename I, typename R>
221 struct iterator_facade<I, R, RAH_STD::random_access_iterator_tag> : iterator_facade<I, R, RAH_STD::bidirectional_iterator_tag>
222 {
223  using iterator_category = RAH_STD::random_access_iterator_tag;
224 
225  I& self() { return *static_cast<I*>(this); }
226  I const& self() const { return *static_cast<I const*>(this); }
227 
228  auto& operator+=(intptr_t increment)
229  {
230  self().advance(increment);
231  return *this;
232  }
233 
234  auto operator+(intptr_t increment)
235  {
236  auto iter = self();
237  iter.advance(increment);
238  return iter;
239  }
240 
241  auto& operator-=(intptr_t increment)
242  {
243  self().advance(-increment);
244  return *this;
245  }
246 
247  auto operator-(intptr_t increment)
248  {
249  auto iter = self();
250  iter.advance(-increment);
251  return iter;
252  }
253 
254  auto operator-(I other) const { return self().distance_to(other); }
255  bool operator<(I other) const { return self().distance_to(other) < 0; }
256  bool operator<=(I other) const { return self().distance_to(other) <= 0; }
257  bool operator>(I other) const { return self().distance_to(other) > 0; }
258  bool operator>=(I other) const { return self().distance_to(other) >= 0; }
259  auto operator[](intptr_t increment) const { return *(self() + increment); }
260 };
261 
262 // ********************************** back_inserter ***********************************************
263 
265 template<typename C>
266 struct back_insert_iterator : iterator_facade<back_insert_iterator<C>, range_ref_type_t<C>, RAH_STD::output_iterator_tag>
267 {
269  back_insert_iterator(C& container) : container_(&container) { }
270  template<typename V> void put(V&& value) const { container_->emplace_back(value); }
271 };
272 
276 template<typename C> auto back_inserter(C&& container)
277 {
278  using Container = RAH_STD::remove_reference_t<C>;
279  auto begin = back_insert_iterator<Container>(container);
280  auto end = back_insert_iterator<Container>(container);
282 }
283 
285 struct is_lesser
286 {
287  template<typename A, typename B> bool operator()(A&& a, B&& b) { return a < b; }
288 };
289 
290 namespace view
291 {
292 
293 namespace details
294 {
295 
296 // Small optional impl for C++14 compilers
297 template<typename T> struct optional
298 {
299  optional() = default;
300  optional(optional const& other)
301  {
302  if (other.has_value())
303  {
304  new(getPtr()) T(other.get());
305  is_allocated_ = true;
306  }
307  }
308  optional& operator = (optional const& other)
309  {
310  if (has_value())
311  {
312  if (other.has_value())
313  {
314  // Handle the case where T is not copy assignable
315  reset();
316  new(getPtr()) T(other.get());
317  is_allocated_ = true;
318  }
319  else
320  reset();
321  }
322  else
323  {
324  if (other.has_value())
325  {
326  new(getPtr()) T(other.get());
327  is_allocated_ = true;
328  }
329  }
330  return *this;
331  }
332  optional& operator = (optional&& other)
333  {
334  if (has_value())
335  {
336  if (other.has_value())
337  {
338  // A lambda with const capture is not move assignable
339  reset();
340  new(getPtr()) T(RAH_STD::move(other.get()));
341  is_allocated_ = true;
342  }
343  else
344  reset();
345  }
346  else
347  {
348  if (other.has_value())
349  {
350  new(getPtr()) T(RAH_STD::move(other.get()));
351  is_allocated_ = true;
352  }
353  }
354  return *this;
355  }
356  optional(T const& other)
357  {
358  new(getPtr()) T(other);
359  is_allocated_ = true;
360  }
361  optional& operator=(T const& other)
362  {
363  new(getPtr()) T(other);
364  is_allocated_ = true;
365  return *this;
366  }
367  optional& operator=(T&& other)
368  {
369  new(getPtr()) T(RAH_STD::move(other));
370  is_allocated_ = true;
371  return *this;
372  }
373  ~optional() { reset(); }
374 
375  bool has_value() const { return is_allocated_; }
376 
377  void reset()
378  {
379  if (is_allocated_)
380  {
381  destruct_value();
382  is_allocated_ = false;
383  }
384  }
385 
386  T& get() { assert(is_allocated_); return *getPtr(); }
387 
388  T const& get() const { assert(is_allocated_); return *getPtr(); }
389 
390  T& operator*() { return get(); }
391  T const& operator*() const { return get(); }
392  T* operator->() { assert(is_allocated_); return getPtr(); }
393  T const* operator->() const { assert(is_allocated_); return getPtr(); }
394 
395 private:
396  T* getPtr() { return (T*)&value_; }
397  T const* getPtr() const { return (T const*)&value_; }
398  void destruct_value() { get().~T(); }
399 
400  RAH_STD::aligned_storage_t<sizeof(T), RAH_STD::alignment_of<T>::value> value_;
401  bool is_allocated_ = false;
402 };
403 }
404 
405 // ********************************** all *********************************************************
406 
407 template<typename R> auto all(R&& range)
408 {
409  return iterator_range<range_begin_type_t<R>>{begin(range), end(range)};
410 }
411 
412 inline auto all()
413 {
414  return make_pipeable([=](auto&& range) {return all(range); });
415 }
416 
417 // ******************************************* take ***********************************************
418 
419 template<typename I>
421  take_iterator<I>,
422  decltype(*fake<I>()),
423  typename RAH_STD::iterator_traits<I>::iterator_category
424 >
425 {
426  I iter_;
427  size_t count_ = size_t();
428 
429  take_iterator() = default;
430  take_iterator(I iter, size_t count) : iter_(iter), count_(count) {}
431 
432  void increment() { ++iter_; ++count_; }
433  void advance(intptr_t off) { iter_ += off; count_ += off; }
434  void decrement() { --iter_; --count_; }
435  auto distance_to(take_iterator r) const { return RAH_STD::min<intptr_t>(iter_ - r.iter_, count_ - r.count_); }
436  auto dereference() const -> decltype(*iter_) { return *iter_; }
437  bool equal(take_iterator r) const { return count_ == r.count_ || iter_ == r.iter_; }
438 };
439 
440 template<typename R> auto take(R&& range, size_t count)
441 {
442  using iterator = take_iterator<range_begin_type_t<R>>;
443  iterator iter1(begin(range), 0);
444  iterator iter2(end(range), count);
445  return make_iterator_range(iter1, iter2);
446 }
447 
448 inline auto take(size_t count)
449 {
450  return make_pipeable([=](auto&& range) {return take(range, count); });
451 }
452 
453 // ******************************************* counted ********************************************
454 
455 template<typename I>
457  counted_iterator<I>,
458  decltype(*fake<I>()),
459  typename RAH_STD::iterator_traits<I>::iterator_category
460 >
461 {
462  I iter_;
463  size_t count_ = size_t();
464 
465  counted_iterator() = default;
466  counted_iterator(I iter, size_t count) : iter_(iter), count_(count) {}
467 
468  void increment() { ++iter_; ++count_; }
469  void advance(intptr_t off) { iter_ += off; count_ += off; }
470  void decrement() { --iter_; --count_; }
471  auto distance_to(counted_iterator r) const { return count_ - r.count_; }
472  auto dereference() const -> decltype(*iter_) { return *iter_; }
473  bool equal(counted_iterator r) const { return count_ == r.count_; }
474 };
475 
476 template<typename I> auto counted(I&& it, size_t n, decltype(++it, 0) = 0)
477 {
479  iterator iter1(it, 0);
480  iterator iter2(it, n);
481  return make_iterator_range(iter1, iter2);
482 }
483 
485 // Obsolete
486 template<typename R> auto counted(R&& range, size_t n, decltype(begin(range), 0) = 0)
487 {
488  return take(range, n);
489 }
490 
491 inline auto counted(size_t n)
492 {
493  return make_pipeable([=](auto&& range) {return take(range, n); });
494 }
496 
497 // ******************************************* unbounded ******************************************
498 
499 template<typename I>
501  unbounded_iterator<I>,
502  decltype(*fake<I>()),
503  typename RAH_STD::iterator_traits<I>::iterator_category
504 >
505 {
506  I iter_;
507  bool end_;
508 
509  unbounded_iterator() = default;
510  unbounded_iterator(I iter, bool end) : iter_(iter), end_(end) {}
511 
512  void increment() { ++iter_; }
513 
514  void advance(intptr_t off) { iter_ += off; }
515  void decrement() { --iter_; }
517  {
518  if (end_)
519  {
520  if (r.end_)
521  return intptr_t{};
522  else
523  return RAH_STD::numeric_limits<intptr_t>::min();
524  }
525  else
526  {
527  if (r.end_)
528  return RAH_STD::numeric_limits<intptr_t>::max();
529  else
530  return iter_ - r.iter_;
531  }
532  }
533 
534  auto dereference() const -> decltype(*iter_) { return *iter_; }
535  bool equal(unbounded_iterator r) const
536  {
537  return end_?
538  r.end_:
539  (r.end_? false: r.iter_ == iter_);
540  }
541 };
542 
543 template<typename I> auto unbounded(I&& it)
544 {
546  iterator iter1(it, false);
547  iterator iter2(it, true);
548  return make_iterator_range(iter1, iter2);
549 }
550 
551 // ********************************** ints ********************************************************
552 
554 template<typename T = size_t>
555 struct ints_iterator : iterator_facade<ints_iterator<T>, T, RAH_STD::random_access_iterator_tag>
556 {
557  T val_ = T();
558 
559  ints_iterator() = default;
560  ints_iterator(T val) : val_(val) {}
561 
562  void increment() { ++val_; }
563  void advance(intptr_t value) { val_ += T(value); }
564  void decrement() { --val_; }
565  auto distance_to(ints_iterator other) const { return (val_ - other.val_); }
566  auto dereference() const { return val_; }
567  bool equal(ints_iterator other) const { return val_ == other.val_; }
568 };
569 
570 template<typename T = size_t> auto ints(T b = 0, T e = RAH_STD::numeric_limits<T>::max())
571 {
572  return iterator_range<ints_iterator<T>>{ { b }, { e }};
573 }
574 
575 // ********************************** iota ********************************************************
576 
578 template<typename T = size_t>
579 struct iota_iterator : iterator_facade<iota_iterator<T>, T, RAH_STD::random_access_iterator_tag>
580 {
581  T val_ = T();
582  T step_ = T(1);
583 
584  iota_iterator() = default;
585  iota_iterator(T val, T step) : val_(val), step_(step) {}
586 
587  void increment() { val_ += step_; }
588  void advance(intptr_t value) { val_ += T(step_ * value); }
589  void decrement() { val_ -= step_; }
590  auto distance_to(iota_iterator other) const { return (val_ - other.val_) / step_; }
591  auto dereference() const { return val_; }
592  bool equal(iota_iterator other) const { return val_ == other.val_; }
593 };
594 
595 template<typename T = size_t> auto iota(T b, T e, T step = 1)
596 {
597  assert(step != 0);
598  auto diff = (e - b);
599  diff = ((diff + (step - 1)) / step) * step;
600  return iterator_range<iota_iterator<T>>{ { b, step}, { b + diff, step }};
601 }
602 
603 // ********************************** repeat ******************************************************
604 
606 template<typename V>
607 struct repeat_iterator : iterator_facade<repeat_iterator<V>, V const&, RAH_STD::forward_iterator_tag>
608 {
609  V val_ = V();
610 
611  repeat_iterator() = default;
612  template<typename U>
613  repeat_iterator(U val) : val_(RAH_STD::forward<U>(val)) {}
614 
615  void increment() { }
616  void advance(intptr_t value) { }
617  void decrement() { }
618  V const& dereference() const { return val_; }
619  bool equal(repeat_iterator) const { return false; }
620 };
621 
622 template<typename V> auto repeat(V&& value)
623 {
625 }
626 
627 // ********************************** join ********************************************************
628 
629 template<typename R>
630 struct join_iterator : iterator_facade<join_iterator<R>, range_ref_type_t<range_ref_type_t<R>>, RAH_STD::forward_iterator_tag>
631 {
636  struct SubRange
637  {
640  };
642 
643  template<typename U>
644  join_iterator(U&& range, Iterator1 rangeIter, Iterator2 subRangeIter, Iterator2 subRangeEnd)
645  : range_(RAH_STD::forward<U>(range))
646  , rangeIter_(rangeIter)
647  , subRange_(SubRange{ subRangeIter, subRangeEnd })
648  {
649  if (rangeIter_ == end(range_))
650  return;
651  next_valid();
652  }
653 
654  template<typename U>
655  join_iterator(U&& range, Iterator1 rangeIter)
656  : range_(RAH_STD::forward<U>(range))
657  , rangeIter_(rangeIter)
658  {
659  }
660 
661  void next_valid()
662  {
663  while (subRange_->subRangeIter == subRange_->subRangeEnd)
664  {
665  ++rangeIter_;
666  if (rangeIter_ == end(range_))
667  return;
668  else
669  {
670  subRange_->subRangeIter = begin(*rangeIter_);
671  subRange_->subRangeEnd = end(*rangeIter_);
672  }
673  }
674  }
675 
676  void increment()
677  {
678  ++subRange_->subRangeIter;
679  next_valid();
680  }
681  auto dereference() const ->decltype(*subRange_->subRangeIter) { return *subRange_->subRangeIter; }
682  bool equal(join_iterator other) const
683  {
684  if (rangeIter_ == end(range_))
685  return rangeIter_ == other.rangeIter_;
686  else
687  return rangeIter_ == other.rangeIter_ && subRange_->subRangeIter == other.subRange_->subRangeIter;
688  }
689 };
690 
691 template<typename R> auto join(R&& range_of_ranges)
692 {
693  auto rangeRef = range_of_ranges | RAH_NAMESPACE::view::all();
694  using join_iterator_type = join_iterator<decltype(rangeRef)>;
695  auto rangeBegin = begin(rangeRef);
696  auto rangeEnd = end(rangeRef);
697  if (empty(rangeRef))
698  {
699  join_iterator_type b(rangeRef, rangeBegin);
700  join_iterator_type e(rangeRef, rangeEnd);
701  return make_iterator_range(b, e);
702  }
703  else
704  {
705  join_iterator_type b(rangeRef, rangeBegin, begin(*rangeBegin), end(*rangeBegin));
706  join_iterator_type e(rangeRef, rangeEnd);
707  return make_iterator_range(b, e);
708  }
709 }
710 
711 inline auto join()
712 {
713  return make_pipeable([](auto&& range) {return join(range); });
714 }
715 
716 // ********************************** cycle ********************************************************
717 
718 template<typename R>
719 struct cycle_iterator : iterator_facade<cycle_iterator<R>, range_ref_type_t<R>, RAH_STD::forward_iterator_tag>
720 {
726 
727  template<typename U>
728  explicit cycle_iterator(U&& range, Iterator iter)
729  : range_(RAH_STD::forward<U>(range))
730  , beginIter_(begin(range_))
731  , endIter_(end(range_))
732  , iter_(iter)
733  {
734  }
735 
736  void increment()
737  {
738  ++iter_;
739  while (iter_ == endIter_)
740  iter_ = begin(range_);
741  }
742  auto dereference() const ->decltype(*iter_) { return *iter_; }
743  bool equal(cycle_iterator) const
744  {
745  return false;
746  }
747 };
748 
749 template<typename R> auto cycle(R&& range)
750 {
751  auto rangeRef = range | RAH_NAMESPACE::view::all();
752  using iterator_type = cycle_iterator<RAH_STD::remove_reference_t<decltype(rangeRef)>>;
753 
754  iterator_type b(rangeRef, begin(rangeRef));
755  iterator_type e(rangeRef, begin(rangeRef));
756  return make_iterator_range(b, e);
757 }
758 
759 inline auto cycle()
760 {
761  return make_pipeable([](auto&& range) {return cycle(range); });
762 }
763 
764 // ********************************** generate ****************************************************
765 
767 template<typename F>
768 struct generate_iterator : iterator_facade<generate_iterator<F>, decltype(fake<F>()()), RAH_STD::forward_iterator_tag>
769 {
771 
772  generate_iterator(F const& func) : func_(func) {}
773 
774  void increment() { }
775  auto dereference() const { return (*func_)(); }
776  bool equal(generate_iterator) const { return false; }
777 };
778 
779 template<typename F> auto generate(F&& func)
780 {
781  using Functor = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
782  return iterator_range<generate_iterator<Functor>>{ { func}, { func }};
783 }
784 
785 template<typename F> auto generate_n(size_t count, F&& func)
786 {
787  return generate(RAH_STD::forward<F>(func)) | take(count);
788 }
789 
790 // ******************************************* transform ******************************************
791 
792 template<typename R, typename F>
794  transform_iterator<R, F>,
795  decltype(fake<F>()(fake<range_ref_type_t<R>>())),
796  range_iter_categ_t<R>
797 >
798 {
801 
802  transform_iterator(range_begin_type_t<R> const& iter, F const& func) : iter_(iter), func_(func) {}
803 
805  {
806  iter_ = ot.iter_;
807  func_ = ot.func_;
808  return *this;
809  }
810 
811  void increment() { ++iter_; }
812  void advance(intptr_t off) { iter_ += off; }
813  void decrement() { --iter_; }
814  auto distance_to(transform_iterator r) const { return iter_ - r.iter_; }
815  auto dereference() const -> decltype((*func_)(*iter_)) { return (*func_)(*iter_); }
816  bool equal(transform_iterator r) const { return iter_ == r.iter_; }
817 };
818 
819 template<typename R, typename F> auto transform(R&& range, F&& func)
820 {
821  using Functor = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
822  using iterator = transform_iterator<RAH_STD::remove_reference_t<R>, Functor>;
823  auto iter1 = begin(range);
824  auto iter2 = end(range);
825  return iterator_range<iterator>{ { iter1, func }, { iter2, func } };
826 }
827 
828 template<typename F> auto transform(F&& func)
829 {
830  return make_pipeable([=](auto&& range) {return transform(range, func); });
831 }
832 
833 // ********************************** for_each ****************************************************
834 
835 template<typename R, typename F> auto for_each(R&& range, F&& func)
836 {
838 }
839 
840 template<typename F>
841 inline auto for_each(F&& func)
842 {
843  return make_pipeable([=](auto&& range) {return RAH_NAMESPACE::view::for_each(range, func); });
844 }
845 
846 // ***************************************** slice ************************************************
847 
848 template<typename R> auto slice(R&& range, intptr_t begin_idx, intptr_t end_idx)
849 {
850  static_assert(not RAH_STD::is_same<range_iter_categ_t<R>, RAH_STD::forward_iterator_tag>::value,
851  "Can't use slice on non-bidirectional iterators. Try to use view::drop and view::take");
852  auto findIter = [](auto b, auto e, intptr_t idx)
853  {
854  if (idx < 0)
855  {
856  idx += 1;
857  RAH_STD::advance(e, idx);
858  return e;
859  }
860  else
861  {
862  RAH_STD::advance(b, idx);
863  return b;
864  }
865  };
866  auto b_in = begin(range);
867  auto e_in = end(range);
868  auto b_out = findIter(b_in, e_in, begin_idx);
869  auto e_out = findIter(b_in, e_in, end_idx);
870  return iterator_range<decltype(b_out)>{ {b_out}, { e_out } };
871 }
872 
873 inline auto slice(intptr_t begin, intptr_t end)
874 {
875  return make_pipeable([=](auto&& range) {return slice(range, begin, end); });
876 }
877 
878 // ***************************************** stride ***********************************************
879 
880 template<typename R>
881 struct stride_iterator : iterator_facade<stride_iterator<R>, range_ref_type_t<R>, range_iter_categ_t<R>>
882 {
885  size_t step_;
886 
888  : iter_(iter), end_(end), step_(step) {}
889 
890  auto increment()
891  {
892  for (size_t i = 0; i < step_ && iter_ != end_; ++i)
893  ++iter_;
894  }
895 
896  auto decrement()
897  {
898  for (size_t i = 0; i < step_; ++i)
899  --iter_;
900  }
901 
902  void advance(intptr_t value) { iter_ += step_ * value; }
903  auto dereference() const -> decltype(*iter_) { return *iter_; }
904  bool equal(stride_iterator other) const { return iter_ == other.iter_; }
905  auto distance_to(stride_iterator other) const { return (iter_ - other.iter_) / step_; }
906 };
907 
908 
909 template<typename R> auto stride(R&& range, size_t step)
910 {
911  auto iter = begin(range);
912  auto endIter = end(range);
914  { iter, endIter, step}, { endIter, endIter, step }};
915 }
916 
917 inline auto stride(size_t step)
918 {
919  return make_pipeable([=](auto&& range) {return stride(range, step); });
920 }
921 
922 // ***************************************** retro ************************************************
923 
924 template<typename R> auto retro(R&& range)
925 {
926  return make_iterator_range(
927  RAH_STD::make_reverse_iterator(end(range)), RAH_STD::make_reverse_iterator(begin(range)));
928 }
929 
930 inline auto retro()
931 {
932  return make_pipeable([=](auto&& range) {return retro(range); });
933 }
934 
935 // ********************************** single ******************************************************
936 
937 template<typename V>
938 auto single(V&& value)
939 {
940  return repeat(value) | take(1);
941 }
942 
943 // *************************** zip ****************************************************************
945 namespace details
946 {
947 template <typename Tuple, typename F, size_t ...Indices>
948 void for_each_impl(Tuple&& tuple, F&& f, RAH_STD::index_sequence<Indices...>)
949 {
950  using swallow = int[];
951  (void)swallow {
952  1,
953  (f(RAH_STD::get<Indices>(RAH_STD::forward<Tuple>(tuple))), void(), int{})...
954  };
955 }
956 
957 template <typename Tuple, typename F>
958 void for_each(Tuple&& tuple, F&& f)
959 {
960  constexpr size_t N = RAH_STD::tuple_size<RAH_STD::remove_reference_t<Tuple>>::value;
961  for_each_impl(RAH_STD::forward<Tuple>(tuple), RAH_STD::forward<F>(f),
962  RAH_STD::make_index_sequence<N>{});
963 }
964 
965 template <class F, typename... Args, size_t... Is>
966 auto transform_each_impl(const RAH_STD::tuple<Args...>& t, F&& f, RAH_STD::index_sequence<Is...>) {
967  return RAH_STD::make_tuple(
968  f(RAH_STD::get<Is>(t))...
969  );
970 }
971 
972 template <class F, typename... Args>
973 auto transform_each(const RAH_STD::tuple<Args...>& t, F&& f) {
974  return transform_each_impl(
975  t, RAH_STD::forward<F>(f), RAH_STD::make_index_sequence<sizeof...(Args)>{});
976 }
977 
978 template <typename... Args, size_t... Is>
979 auto deref_impl(const RAH_STD::tuple<Args...>& t, RAH_STD::index_sequence<Is...>) {
980  return RAH_STD::tuple<typename RAH_STD::iterator_traits<Args>::reference...>(
981  (*RAH_STD::get<Is>(t))...
982  );
983 }
984 
985 template <typename... Args>
986 auto deref(const RAH_STD::tuple<Args...>& t) {
987  return deref_impl(t, RAH_STD::make_index_sequence<sizeof...(Args)>{});
988 }
989 
990 template <size_t Index>
991 struct Equal
992 {
993  template <typename... Args>
994  bool operator()(RAH_STD::tuple<Args...> const& a, RAH_STD::tuple<Args...> const& b) const
995  {
996  return (RAH_STD::get<Index - 1>(a) == RAH_STD::get<Index - 1>(b)) || Equal<Index - 1>{}(a, b);
997  }
998 };
999 
1000 template<>
1001 struct Equal<0>
1002 {
1003  template <typename... Args>
1004  bool operator()(RAH_STD::tuple<Args...> const&, RAH_STD::tuple<Args...> const&) const
1005  {
1006  return false;
1007  }
1008 };
1009 
1010 template <typename... Args>
1011 auto equal(RAH_STD::tuple<Args...> const& a, RAH_STD::tuple<Args...> const& b)
1012 {
1013  return Equal<sizeof...(Args)>{}(a, b);
1014 }
1015 
1016 } // namespace details
1018 
1019 template<typename IterTuple>
1021  zip_iterator<IterTuple>,
1022  decltype(details::deref(fake<IterTuple>())),
1023  RAH_STD::bidirectional_iterator_tag
1024 >
1025 {
1026  IterTuple iters_;
1027  zip_iterator() = default;
1028  zip_iterator(IterTuple const& iters) : iters_(iters) {}
1029  void increment() { details::for_each(iters_, [](auto& iter) { ++iter; }); }
1030  void advance(intptr_t val) { for_each(iters_, [val](auto& iter) { iter += val; }); }
1031  void decrement() { details::for_each(iters_, [](auto& iter) { --iter; }); }
1032  auto dereference() const { return details::deref(iters_); }
1033  auto distance_to(zip_iterator other) const { return RAH_STD::get<0>(iters_) - RAH_STD::get<0>(other.iters_); }
1034  bool equal(zip_iterator other) const { return details::equal(iters_, other.iters_); }
1035 };
1036 
1037 template<typename ...R> auto zip(R&&... _ranges)
1038 {
1039  auto iterTup = RAH_STD::make_tuple(begin(RAH_STD::forward<R>(_ranges))...);
1040  auto endTup = RAH_STD::make_tuple(end(RAH_STD::forward<R>(_ranges))...);
1041  return iterator_range<zip_iterator<decltype(iterTup)>>{ { iterTup }, { endTup }};
1042 }
1043 
1044 // ************************************ chunk *****************************************************
1045 
1046 template<typename R>
1047 struct chunk_iterator : iterator_facade<chunk_iterator<R>, iterator_range<range_begin_type_t<R>>, RAH_STD::forward_iterator_tag>
1048 {
1052  size_t step_;
1053 
1055  range_begin_type_t<R> const& iter,
1056  range_begin_type_t<R> const& iter2,
1057  range_end_type_t<R> const& end,
1058  size_t step = 0)
1059  : iter_(iter), iter2_(iter2), end_(end), step_(step)
1060  {
1061  }
1062 
1063  void increment()
1064  {
1065  iter_ = iter2_;
1066  for (size_t i = 0; i != step_ and iter2_ != end_; ++i)
1067  ++iter2_;
1068  }
1069 
1070  auto dereference() const { return make_iterator_range(iter_, iter2_); }
1071  bool equal(chunk_iterator other) const { return iter_ == other.iter_; }
1072 };
1073 
1074 template<typename R> auto chunk(R&& range, size_t step)
1075 {
1076  auto iter = begin(range);
1077  auto endIter = end(range);
1079  iterator begin = { iter, iter, endIter, step };
1080  begin.increment();
1081  return iterator_range<iterator>{ { begin }, { endIter, endIter, endIter, step }};
1082 }
1083 
1084 inline auto chunk(size_t step)
1085 {
1086  return make_pipeable([=](auto&& range) {return chunk(range, step); });
1087 }
1088 
1089 // ***************************************** filter ***********************************************
1090 
1091 template<typename R, typename F>
1092 struct filter_iterator : iterator_facade<filter_iterator<R, F>, range_ref_type_t<R>, RAH_STD::bidirectional_iterator_tag>
1093 {
1098  details::optional<decltype(iter_.operator->())> value_pointer_;
1099 
1102  range_begin_type_t<R> const& iter,
1103  range_end_type_t<R> const& end,
1104  F const& func)
1105  : begin_(begin), iter_(iter), end_(end), func_(func)
1106  {
1107  next_value();
1108  }
1109 
1110  void next_value()
1111  {
1112  value_pointer_ = iter_.operator->();
1113  while (iter_ != end_ && not (*func_)(**value_pointer_))
1114  {
1115  assert(iter_ != end_);
1116  ++iter_;
1117  value_pointer_ = iter_.operator->();
1118  }
1119  }
1120 
1121  void increment()
1122  {
1123  ++iter_;
1124  next_value();
1125  }
1126 
1127  void decrement()
1128  {
1129  do
1130  {
1131  --iter_;
1132  } while (not (*func_)(*iter_) && iter_ != begin_);
1133  }
1134 
1135  auto dereference() const -> decltype(*iter_) { return **value_pointer_; }
1136  bool equal(filter_iterator other) const { return iter_ == other.iter_; }
1137 };
1138 
1139 template<typename R, typename F> auto filter(R&& range, F&& func)
1140 {
1141  auto iter = begin(range);
1142  auto endIter = end(range);
1143  using Predicate = RAH_STD::remove_cv_t<RAH_STD::remove_reference_t<F>>;
1145  { iter, iter, endIter, func },
1146  { iter, endIter, endIter, func }
1147  };
1148 }
1149 
1150 template<typename F> auto filter(F&& func)
1151 {
1152  return make_pipeable([=](auto&& range) {return filter(range, func); });
1153 }
1154 
1155 // ***************************************** concat ***********************************************
1156 
1157 template<typename IterPair, typename V>
1158 struct concat_iterator : iterator_facade<concat_iterator<IterPair, V>, V, RAH_STD::forward_iterator_tag>
1159 {
1160  IterPair iter_;
1161  IterPair end_;
1163 
1164  concat_iterator(IterPair const& iter, IterPair const& end, size_t range_index)
1165  : iter_(iter), end_(end), range_index_(range_index)
1166  {
1167  }
1168 
1169  void increment()
1170  {
1171  if (range_index_ == 0)
1172  {
1173  auto& i = RAH_STD::get<0>(iter_);
1174  ++i;
1175  if (i == RAH_STD::get<0>(end_))
1176  range_index_ = 1;
1177  }
1178  else
1179  ++RAH_STD::get<1>(iter_);
1180  }
1181 
1182  auto dereference() const -> decltype(*RAH_STD::get<0>(iter_))
1183  {
1184  if (range_index_ == 0)
1185  return *RAH_STD::get<0>(iter_);
1186  else
1187  return *RAH_STD::get<1>(iter_);
1188  }
1189 
1190  bool equal(concat_iterator other) const
1191  {
1192  if (range_index_ != other.range_index_)
1193  return false;
1194  if (range_index_ == 0)
1195  return RAH_STD::get<0>(iter_) == RAH_STD::get<0>(other.iter_);
1196  else
1197  return RAH_STD::get<1>(iter_) == RAH_STD::get<1>(other.iter_);
1198  }
1199 };
1200 
1202 template<typename R1> auto concat(R1&& range1)
1203 {
1204  return RAH_STD::forward<R1>(range1);
1205 }
1206 
1207 template<typename R1, typename R2> auto concat(R1&& range1, R2&& range2)
1208 {
1209  auto begin_range1 = RAH_STD::make_pair(begin(range1), begin(range2));
1210  auto begin_range2 = RAH_STD::make_pair(end(range1), end(range2));
1211  auto end_range1 = RAH_STD::make_pair(end(range1), end(range2));
1212  auto end_range2 = RAH_STD::make_pair(end(range1), end(range2));
1213  return iterator_range<
1215  RAH_STD::pair<range_begin_type_t<R1>, range_begin_type_t<R2>>,
1217  {
1218  { begin_range1, begin_range2, 0 },
1219  { end_range1, end_range2, 1 },
1220  };
1221 }
1222 
1224 template<typename R1, typename R2, typename ...Ranges>
1225 auto concat(R1&& range1, R2&& range2, Ranges&&... ranges)
1226 {
1227  return concat(concat(RAH_STD::forward<R1>(range1), RAH_STD::forward<R2>(range2)), ranges...);
1228 }
1229 
1230 // *************************** enumerate **********************************************************
1231 
1232 template<typename R> auto enumerate(R&& range)
1233 {
1234  size_t const dist = RAH_STD::distance(begin(RAH_STD::forward<R>(range)), end(RAH_STD::forward<R>(range)));
1235  return zip(iota(size_t(0), dist), RAH_STD::forward<R>(range));
1236 }
1237 
1238 inline auto enumerate()
1239 {
1240  return make_pipeable([=](auto&& range) {return enumerate(range); });
1241 }
1242 
1243 // ****************************** map_value ********************************************************
1244 
1245 template<typename R> auto map_value(R&& range)
1246 {
1247  return transform(RAH_STD::forward<R>(range), [](auto&& nvp) -> decltype(RAH_STD::get<1>(RAH_STD::forward<decltype(nvp)>(nvp)))
1248  {
1249  return RAH_STD::get<1>(RAH_STD::forward<decltype(nvp)>(nvp));
1250  });
1251 }
1252 
1253 inline auto map_value()
1254 {
1255  return make_pipeable([=](auto&& range) {return map_value(range); });
1256 }
1257 
1258 // ****************************** map_key **********************************************************
1259 
1260 template<typename R> auto map_key(R&& range)
1261 {
1262  return RAH_NAMESPACE::view::transform(RAH_STD::forward<R>(range), [](auto&& nvp) -> decltype(RAH_STD::get<0>(RAH_STD::forward<decltype(nvp)>(nvp)))
1263  {
1264  return RAH_STD::get<0>(RAH_STD::forward<decltype(nvp)>(nvp));
1265  });
1266 }
1267 
1268 inline auto map_key()
1269 {
1270  return make_pipeable([=](auto&& range) {return map_key(range); });
1271 }
1272 
1273 // *********************************** sort *******************************************************
1274 
1281 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
1282 auto sort(R&& range, P&& pred = {})
1283 {
1284  using value_type = range_value_type_t<R>;
1285  using Container = typename RAH_STD::vector<value_type>;
1286  Container result;
1287  result.reserve(RAH_STD::distance(begin(range), end(range)));
1288  RAH_STD::copy(begin(range), end(range), RAH_STD::back_inserter(result));
1289  RAH_STD::sort(begin(result), end(result), pred);
1290  return result;
1291 }
1292 
1300 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
1301 auto sort(P&& pred = {})
1302 {
1303  return make_pipeable([=](auto&& range) { return view::sort(RAH_STD::forward<decltype(range)>(range), pred); });
1304 }
1305 
1306 } // namespace view
1307 
1308 // ****************************************** empty ***********************************************
1309 
1313 template<typename R> bool empty(R&& range)
1314 {
1315  return begin(range) == end(range);
1316 }
1317 
1322 inline auto empty()
1323 {
1324  return make_pipeable([](auto&& range) {return empty(range); });
1325 }
1326 
1327 // ****************************************** equal_range ***********************************************
1328 
1332 template<typename R, typename V>
1333 auto equal_range(R&& range, V&& value, RAH_STD::enable_if_t<is_range<R>::value, int> = 0)
1334 {
1335  auto pair = RAH_STD::equal_range(begin(range), end(range), RAH_STD::forward<V>(value));
1336  return make_iterator_range(RAH_STD::get<0>(pair), RAH_STD::get<1>(pair));
1337 }
1338 
1343 template<typename V> auto equal_range(V&& value)
1344 {
1345  return make_pipeable([=](auto&& range) {return equal_range(RAH_STD::forward<decltype(range)>(range), value); });
1346 }
1347 
1352 template<typename R, typename V, typename P>
1353 auto equal_range(R&& range, V&& value, P&& pred)
1354 {
1355  auto pair = RAH_STD::equal_range(begin(range), end(range), RAH_STD::forward<V>(value), RAH_STD::forward<P>(pred));
1356  return make_iterator_range(RAH_STD::get<0>(pair), RAH_STD::get<1>(pair));
1357 }
1358 
1364 template<typename V, typename P>
1365 auto equal_range(V&& value, P&& pred, RAH_STD::enable_if_t<!is_range<V>::value, int> = 0)
1366 {
1367  return make_pipeable([=](auto&& range) {return equal_range(RAH_STD::forward<decltype(range)>(range), value, pred); });
1368 }
1369 
1370 // ****************************************** binary_search ***********************************************
1371 
1375 template<typename R, typename V> auto binary_search(R&& range, V&& value)
1376 {
1377  return RAH_STD::binary_search(begin(range), end(range), RAH_STD::forward<V>(value));
1378 }
1379 
1384 template<typename V> auto binary_search(V&& value)
1385 {
1386  return make_pipeable([=](auto&& range) {return binary_search(RAH_STD::forward<decltype(range)>(range), value); });
1387 }
1388 
1389 // ****************************************** transform *******************************************
1390 
1394 template<typename RI, typename RO, typename F>
1395 auto transform(RI&& rangeIn, RO&& rangeOut, F&& unary_op)
1396 {
1397  return RAH_STD::transform(begin(rangeIn), end(rangeIn), begin(rangeOut), RAH_STD::forward<F>(unary_op));
1398 }
1399 
1403 template<typename RI1, typename RI2, typename RO, typename F>
1404 auto transform(RI1&& rangeIn1, RI2&& rangeIn2, RO&& rangeOut, F&& binary_op)
1405 {
1406  return RAH_STD::transform(
1407  begin(rangeIn1), end(rangeIn1),
1408  begin(rangeIn2),
1409  begin(rangeOut),
1410  RAH_STD::forward<F>(binary_op));
1411 }
1412 
1413 // ********************************************* reduce *******************************************
1414 
1418 template<typename R, typename I, typename F> auto reduce(R&& range, I&& init, F&& reducer)
1419 {
1420  return RAH_STD::accumulate(begin(range), end(range), RAH_STD::forward<I>(init), RAH_STD::forward<F>(reducer));
1421 }
1422 
1427 template<typename I, typename F>
1428 auto reduce(I&& init, F&& reducer)
1429 {
1430  return make_pipeable([=](auto&& range) {return reduce(range, init, reducer); });
1431 }
1432 
1433 // ************************* any_of *******************************************
1434 
1438 template<typename R, typename F> bool any_of(R&& range, F&& pred)
1439 {
1440  return RAH_STD::any_of(begin(range), end(range), RAH_STD::forward<F>(pred));
1441 }
1442 
1447 template<typename P> auto any_of(P&& pred)
1448 {
1449  return make_pipeable([=](auto&& range) {return any_of(range, pred); });
1450 }
1451 
1452 // ************************* all_of *******************************************
1453 
1457 template<typename R, typename P> bool all_of(R&& range, P&& pred)
1458 {
1459  return RAH_STD::all_of(begin(range), end(range), RAH_STD::forward<P>(pred));
1460 }
1461 
1466 template<typename P> auto all_of(P&& pred)
1467 {
1468  return make_pipeable([=](auto&& range) {return all_of(range, pred); });
1469 }
1470 
1471 // ************************* none_of *******************************************
1472 
1476 template<typename R, typename P> bool none_of(R&& range, P&& pred)
1477 {
1478  return RAH_STD::none_of(begin(range), end(range), RAH_STD::forward<P>(pred));
1479 }
1480 
1485 template<typename P> auto none_of(P&& pred)
1486 {
1487  return make_pipeable([=](auto&& range) {return none_of(range, pred); });
1488 }
1489 
1490 // ************************* count ****************************************************************
1491 
1495 template<typename R, typename V> auto count(R&& range, V&& value)
1496 {
1497  return RAH_STD::count(begin(range), end(range), RAH_STD::forward<V>(value));
1498 }
1499 
1504 template<typename V> auto count(V&& value)
1505 {
1506  return make_pipeable([=](auto&& range) {return count(range, value); });
1507 }
1508 
1513 template<typename R, typename P> auto count_if(R&& range, P&& pred)
1514 {
1515  return RAH_STD::count_if(begin(range), end(range), RAH_STD::forward<P>(pred));
1516 }
1517 
1521 template<typename P> auto count_if(P&& pred)
1522 {
1523  return make_pipeable([=](auto&& range) {return count_if(range, pred); });
1524 }
1525 
1526 // ************************* foreach **************************************************************
1527 
1531 template<typename R, typename F> auto for_each(R&& range, F&& func)
1532 {
1533  return ::RAH_STD::for_each(begin(range), end(range), RAH_STD::forward<F>(func));
1534 }
1535 
1540 template<typename F> auto for_each(F&& func)
1541 {
1542  return make_pipeable([=](auto&& range) {return for_each(range, func); });
1543 }
1544 
1545 // ***************************** to_container *****************************************************
1546 
1550 template<typename C, typename R> auto to_container(R&& range)
1551 {
1552  return C(begin(range), end(range));
1553 }
1554 
1559 template<typename C> auto to_container()
1560 {
1561  return make_pipeable([=](auto&& range) {return to_container<C>(range); });
1562 }
1563 
1564 // ************************* mismatch *************************************************************
1565 
1569 template<typename R1, typename R2> auto mismatch(R1&& range1, R2&& range2)
1570 {
1571  return RAH_STD::mismatch(begin(range1), end(range1), begin(range2), end(range2));
1572 }
1573 
1574 // ****************************************** find ************************************************
1575 
1579 template<typename R, typename V> auto find(R&& range, V&& value)
1580 {
1581  return RAH_STD::find(begin(range), end(range), RAH_STD::forward<V>(value));
1582 }
1583 
1588 template<typename V> auto find(V&& value)
1589 {
1590  return make_pipeable([=](auto&& range) {return find(range, value); });
1591 }
1592 
1596 template<typename R, typename P> auto find_if(R&& range, P&& pred)
1597 {
1598  return RAH_STD::find_if(begin(range), end(range), RAH_STD::forward<P>(pred));
1599 }
1600 
1605 template<typename P> auto find_if(P&& pred)
1606 {
1607  return make_pipeable([=](auto&& range) {return find_if(range, pred); });
1608 }
1609 
1613 template<typename R, typename P> auto find_if_not(R&& range, P&& pred)
1614 {
1615  return RAH_STD::find_if_not(begin(range), end(range), RAH_STD::forward<P>(pred));
1616 }
1617 
1622 template<typename P> auto find_if_not(P&& pred)
1623 {
1624  return make_pipeable([=](auto&& range) {return find_if_not(range, pred); });
1625 }
1626 
1627 // *************************************** copy ***************************************************
1628 
1633 template<typename R1, typename R2> auto copy(R1&& in, R2&& out)
1634 {
1635  return RAH_STD::copy(begin(in), end(in), begin(out));
1636 }
1637 
1643 template<typename R2> auto copy(R2&& out)
1644 {
1645  auto all_out = out | RAH_NAMESPACE::view::all();
1646  return make_pipeable([=](auto&& in) {return copy(in, all_out); });
1647 }
1648 
1649 // *************************************** fill ***************************************************
1650 
1654 template<typename R1, typename V> auto fill(R1&& in, V&& value)
1655 {
1656  return RAH_STD::fill(begin(in), end(in), value);
1657 }
1658 
1663 template<typename V> auto fill(V&& value)
1664 {
1665  return make_pipeable([=](auto&& out) {return fill(out, value); });
1666 }
1667 
1668 // *************************************** back_insert ***************************************************
1669 
1673 template<typename R1, typename R2> auto back_insert(R1&& in, R2&& out)
1674 {
1675  return copy(in, RAH_NAMESPACE::back_inserter(out));
1676 }
1677 
1682 template<typename R2> auto back_insert(R2&& out)
1683 {
1684  return make_pipeable([&](auto&& in) {return back_insert(in, out); });
1685 }
1686 
1687 // *************************************** copy_if ***************************************************
1688 
1693 template<typename R1, typename R2, typename P> auto copy_if(R1&& in, R2&& out, P&& pred)
1694 {
1695  return RAH_STD::copy_if(begin(in), end(in), begin(out), RAH_STD::forward<P>(pred));
1696 }
1697 
1703 template<typename R2, typename P> auto copy_if(R2&& out, P&& pred)
1704 {
1705  auto all_out = out | RAH_NAMESPACE::view::all();
1706  return make_pipeable([=](auto&& in) {return copy_if(in, all_out, pred); });
1707 }
1708 
1709 // *************************************** size ***************************************************
1710 
1714 template<typename R> auto size(R&& range)
1715 {
1716  return RAH_STD::distance(begin(range), end(range));
1717 }
1718 
1723 inline auto size()
1724 {
1725  return make_pipeable([=](auto&& range) { return size(range); });
1726 }
1727 
1728 // *************************************** equal **************************************************
1729 
1733 template<typename R1, typename R2> auto equal(R1&& range1, R2&& range2)
1734 {
1735 #ifdef EASTL_VERSION
1736  return RAH_STD::identical(begin(range1), end(range1), begin(range2), end(range2));
1737 #else
1738  return RAH_STD::equal(begin(range1), end(range1), begin(range2), end(range2));
1739 #endif
1740 }
1741 
1746 template<typename R1> auto equal(R1&& range2)
1747 {
1748  auto all_range2 = range2 | RAH_NAMESPACE::view::all();
1749  return make_pipeable([=](auto&& range1) { return equal(RAH_STD::forward<decltype(range1)>(range1), all_range2); });
1750 }
1751 
1752 // *********************************** stream_inserter ********************************************
1753 
1754 template<typename S>
1755 struct stream_inserter_iterator : iterator_facade<stream_inserter_iterator<S>, typename S::char_type, RAH_STD::output_iterator_tag>
1756 {
1758  stream_inserter_iterator(S& stream) : stream_(&stream) { }
1759  template<typename V> void put(V&& value) const { (*stream_) << value; }
1760 };
1761 
1765 template<typename S> auto stream_inserter(S&& stream)
1766 {
1767  using Stream = RAH_STD::remove_reference_t<S>;
1768  auto begin = stream_inserter_iterator<Stream>(stream);
1769  auto end = stream_inserter_iterator<Stream>(stream);
1771 }
1772 
1773 // *********************************** remove_if **************************************************
1774 
1779 template<typename R, typename P> auto remove_if(R&& range, P&& pred)
1780 {
1781  return RAH_STD::remove_if(begin(range), end(range), RAH_STD::forward<P>(pred));
1782 }
1783 
1789 template<typename P> auto remove_if(P&& pred)
1790 {
1791  return make_pipeable([=](auto&& range) { return remove_if(range, pred); });
1792 }
1793 
1794 // *********************************** partition **************************************************
1795 
1802 template<typename R, typename P> auto partition(R&& range, P&& pred)
1803 {
1804  return RAH_STD::partition(begin(range), end(range), RAH_STD::forward<P>(pred));
1805 }
1806 
1811 template<typename P> auto partition(P&& pred)
1812 {
1813  return make_pipeable([=](auto&& range) { return partition(range, pred); });
1814 }
1815 
1816 // *********************************** stable_partition *******************************************
1817 
1824 template<typename R, typename P> auto stable_partition(R&& range, P&& pred)
1825 {
1826  return RAH_STD::stable_partition(begin(range), end(range), RAH_STD::forward<P>(pred));
1827 }
1828 
1833 template<typename P> auto stable_partition(P&& pred)
1834 {
1835  return make_pipeable([=](auto&& range) { return stable_partition(range, pred); });
1836 }
1837 
1838 // *********************************** erase ******************************************************
1839 
1844 template<typename C, typename R> auto erase(C&& container, R&& subrange)
1845 {
1846  container.erase(begin(subrange), end(subrange));
1847  return container | RAH_NAMESPACE::view::all();
1848 }
1849 
1855 template<typename R> auto erase(R&& range)
1856 {
1857  auto all_range = range | RAH_NAMESPACE::view::all();
1858  return make_pipeable([=](auto&& cont) { return RAH_NAMESPACE::erase(cont, all_range); });
1859 }
1860 
1861 // *********************************** sort *******************************************************
1862 
1867 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
1868 void sort(R& range, P&& pred = {})
1869 {
1870  RAH_STD::sort(begin(range), end(range), pred);
1871 }
1872 
1878 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
1879 auto sort(P&& pred = {})
1880 {
1881  return make_pipeable([=](auto& range) { return sort(range, pred); });
1882 }
1883 
1884 // *********************************** stable_sort ************************************************
1885 
1890 template<typename R, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<R>::value>>
1891 void stable_sort(R& range, P&& pred = {})
1892 {
1893  RAH_STD::stable_sort(begin(range), end(range), pred);
1894 }
1895 
1901 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
1902 auto stable_sort(P&& pred = {})
1903 {
1904  return make_pipeable([=](auto& range) { return stable_sort(range, pred); });
1905 }
1906 
1907 // *********************************** shuffle *******************************************************
1908 
1912 template<typename R, typename URBG>
1913 void shuffle(R& range, URBG&& g)
1914 {
1915  RAH_STD::shuffle(begin(range), end(range), RAH_STD::forward<URBG>(g));
1916 }
1917 
1922 template<typename URBG>
1923 auto shuffle(URBG&& g)
1924 {
1925  return make_pipeable([&g](auto& range) { return RAH_NAMESPACE::shuffle(range, g); });
1926 }
1927 
1928 // *********************************** unique *****************************************************
1929 
1931 struct is_equal
1932 {
1933  template<typename A, typename B> bool operator()(A&& a, B&& b) { return a == b; }
1934 };
1935 
1941 template<typename R, typename P = is_equal, typename = RAH_STD::enable_if_t<is_range<R>::value>>
1942 auto unique(R&& range, P&& pred = {})
1943 {
1944  return RAH_STD::unique(begin(range), end(range), pred);
1945 }
1946 
1953 template<typename P = is_equal, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
1954 auto unique(P&& pred = {})
1955 {
1956  return make_pipeable([=](auto&& range) { return unique(RAH_STD::forward<decltype(range)>(range), pred); });
1957 }
1958 
1959 // *********************************** set_difference ************************************************
1960 
1965 template<typename IN1, typename IN2, typename OUT>
1966 void set_difference(IN1&& in1, IN2&& in2, OUT&& out)
1967 {
1969  begin(in1), end(in1),
1970  begin(in2), end(in2),
1971  begin(out));
1972 }
1973 
1974 // *********************************** set_intersection ************************************************
1975 
1980 template<typename IN1, typename IN2, typename OUT>
1981 void set_intersection(IN1&& in1, IN2&& in2, OUT&& out)
1982 {
1984  begin(in1), end(in1),
1985  begin(in2), end(in2),
1986  begin(out));
1987 }
1988 
1989 namespace action
1990 {
1991 
1992 // *********************************** unique *****************************************************
1993 
1999 template<typename C, typename P = is_equal, typename = RAH_STD::enable_if_t<is_range<C>::value>>
2000 auto&& unique(C&& container, P&& pred = {})
2001 {
2002  container.erase(RAH_NAMESPACE::unique(container, pred), container.end());
2003  return RAH_STD::forward<C>(container);
2004 }
2005 
2012 template<typename P = is_equal, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2013 auto unique(P&& pred = {})
2014 {
2015  return make_pipeable([=](auto&& range) -> auto&& { return action::unique(RAH_STD::forward<decltype(range)>(range), pred); });
2016 }
2017 
2018 // *********************************** remove_if **************************************************
2019 
2024 template<typename C, typename P> auto&& remove_if(C&& container, P&& pred)
2025 {
2026  container.erase(RAH_NAMESPACE::remove_if(container, RAH_STD::forward<P>(pred)), container.end());
2027  return RAH_STD::forward<C>(container);
2028 }
2029 
2035 template<typename P> auto remove_if(P&& pred)
2036 {
2037  return make_pipeable([=](auto&& range) -> auto&& { return remove_if(RAH_STD::forward<decltype(range)>(range), pred); });
2038 }
2039 
2040 // *********************************** sort *******************************************************
2041 
2047 template<typename C, typename P = is_lesser, typename = RAH_STD::enable_if_t<is_range<C>::value>>
2048 auto&& sort(C&& container, P&& pred = {})
2049 {
2050  RAH_NAMESPACE::sort(container, pred);
2051  return RAH_STD::forward<C>(container);
2052 }
2053 
2060 template<typename P = is_lesser, typename = RAH_STD::enable_if_t<not is_range<P>::value>>
2061 auto sort(P&& pred = {})
2062 {
2063  return make_pipeable([=](auto&& range) -> auto&& { return action::sort(RAH_STD::forward<decltype(range)>(range), pred); });
2064 }
2065 
2066 // *********************************** shuffle *******************************************************
2067 
2072 template<typename C, typename URBG>
2073 auto&& shuffle(C&& container, URBG&& g)
2074 {
2075  URBG gen = RAH_STD::forward<URBG>(g);
2076  RAH_NAMESPACE::shuffle(container, gen);
2077  return RAH_STD::forward<C>(container);
2078 }
2079 
2085 template<typename URBG>
2086 auto shuffle(URBG&& g)
2087 {
2088  return make_pipeable([&](auto&& range) -> auto&& { return action::shuffle(RAH_STD::forward<decltype(range)>(range), g); });
2089 }
2090 
2091 // *************************************** fill ***************************************************
2092 
2096 template<typename R1, typename V> auto fill(R1&& in, V&& value)
2097 {
2098  RAH_STD::fill(begin(in), end(in), value);
2099  return RAH_STD::forward<R1>(in);
2100 }
2101 
2106 template<typename V> auto fill(V&& value)
2107 {
2108  return make_pipeable([=](auto&& out) {return RAH_NAMESPACE::action::fill(out, value); });
2109 }
2110 
2111 } // namespace action
2112 
2113 } // namespace rah
auto filter(F &&func)
Create a view with only elements which are filtered.
Definition: rah - Copie.hpp:1150
void decrement()
Definition: rah - Copie.hpp:564
std ::remove_reference_t< range_ref_type_t< T > > range_value_type_t
Definition: rah - Copie.hpp:66
Definition: rah - Copie.hpp:555
auto & operator++()
Definition: rah - Copie.hpp:191
void decrement()
Definition: rah - Copie.hpp:589
auto distance_to(iota_iterator other) const
Definition: rah - Copie.hpp:590
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 - Copie.hpp:1981
auto dereference() const
Definition: rah - Copie.hpp:775
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 - Copie.hpp:1033
IterPair iter_
Definition: rah - Copie.hpp:1160
auto unique(P &&pred={})
Remove all but first successuve values which are equals.
Definition: rah - Copie.hpp:2013
counted_iterator(I iter, size_t count)
Definition: rah - Copie.hpp:466
auto distance_to(counted_iterator r) const
Definition: rah - Copie.hpp:471
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:534
T val_
Definition: rah - Copie.hpp:557
T * operator->()
Definition: rah - Copie.hpp:392
Definition: rah - Copie.hpp:500
void advance(intptr_t val)
Definition: rah - Copie.hpp:1030
concat_iterator(IterPair const &iter, IterPair const &end, size_t range_index)
Definition: rah - Copie.hpp:1164
auto concat(R1 &&range1, R2 &&range2, Ranges &&... ranges)
Definition: rah - Copie.hpp:1225
I end_iter
Definition: rah - Copie.hpp:83
bool operator()(A &&a, B &&b)
Definition: rah - Copie.hpp:287
optional(optional const &other)
Definition: rah - Copie.hpp:300
auto generate(F &&func)
Create an infinite range, repetitively calling func.
Definition: rah - Copie.hpp:779
auto operator+(intptr_t increment)
Definition: rah - Copie.hpp:234
optional & operator=(T const &other)
Definition: rah - Copie.hpp:361
range_begin_type_t< R > iter_
Definition: rah - Copie.hpp:799
auto dereference() const -> decltype(*subRange_->subRangeIter)
Definition: rah - Copie.hpp:681
ints_iterator(T val)
Definition: rah - Copie.hpp:560
details::optional< F > func_
Definition: rah - Copie.hpp:770
decltype(end(fake< T >())) range_end_type_t
Definition: rah - Copie.hpp:60
bool equal(chunk_iterator other) const
Definition: rah - Copie.hpp:1071
T val_
Definition: rah - Copie.hpp:581
transform_iterator(range_begin_type_t< R > const &iter, F const &func)
Definition: rah - Copie.hpp:802
bool equal(filter_iterator other) const
Definition: rah - Copie.hpp:1136
auto back_insert(R2 &&out)
Insert in in back of front
Definition: rah - Copie.hpp:1682
auto enumerate()
Pair each element of a range with its index.
Definition: rah - Copie.hpp:1238
auto retro()
Create a view that traverses the source range in reverse order.
Definition: rah - Copie.hpp:930
auto all()
Create a view on the whole range.
Definition: rah - Copie.hpp:412
void increment()
Definition: rah - Copie.hpp:615
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:436
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:742
#define RAH_STD
Definition: rah - Copie.hpp:29
void decrement()
Definition: rah - Copie.hpp:515
void advance(intptr_t value)
Definition: rah - Copie.hpp:563
filter_iterator(range_begin_type_t< R > const &begin, range_begin_type_t< R > const &iter, range_end_type_t< R > const &end, F const &func)
Definition: rah - Copie.hpp:1100
Definition: rah - Copie.hpp:72
Apply the '<' operator on two values of any type.
Definition: rah - Copie.hpp:285
I end() const
Definition: rah - Copie.hpp:87
join_iterator(U &&range, Iterator1 rangeIter, Iterator2 subRangeIter, Iterator2 subRangeEnd)
Definition: rah - Copie.hpp:644
Definition: rah - Copie.hpp:630
auto reduce(I &&init, F &&reducer)
Executes a reducer function on each element of the range, resulting in a single output value.
Definition: rah - Copie.hpp:1428
#define assert(CONDITION)
Definition: test.cpp:40
range_end_type_t< R > end_
Definition: rah - Copie.hpp:1051
Definition: rah - Copie.hpp:1158
void increment()
Definition: rah - Copie.hpp:676
bool operator==(I other) const
Definition: rah - Copie.hpp:194
bool equal(concat_iterator other) const
Definition: rah - Copie.hpp:1190
auto transform(RI1 &&rangeIn1, RI2 &&rangeIn2, RO &&rangeOut, F &&binary_op)
The binary operation binary_op is applied to pairs of elements from two ranges.
Definition: rah - Copie.hpp:1404
void increment()
Definition: rah - Copie.hpp:432
I begin() const
Definition: rah - Copie.hpp:85
void increment()
Definition: rah - Copie.hpp:1169
bool equal(unbounded_iterator r) const
Definition: rah - Copie.hpp:535
auto count_if(P &&pred)
Counts elements for which predicate pred returns true.
Definition: rah - Copie.hpp:1521
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:1135
Definition: rah - Copie.hpp:1047
auto copy_if(R2 &&out, P &&pred)
Copies the elements for which the predicate pred returns true.
Definition: rah - Copie.hpp:1703
IterTuple iters_
Definition: rah - Copie.hpp:1026
bool equal(generate_iterator) const
Definition: rah - Copie.hpp:776
auto for_each(F &&func)
Applies the given function func to each element of the range.
Definition: rah - Copie.hpp:1540
auto take(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:448
unbounded_iterator(I iter, bool end)
Definition: rah - Copie.hpp:510
auto stable_sort(P &&pred={})
Sorts the elements in the range in ascending order.
Definition: rah - Copie.hpp:1902
auto operator[](intptr_t increment) const
Definition: rah - Copie.hpp:259
constexpr intptr_t End
Used with rah::view::slice to point to the end.
Definition: rah - Copie.hpp:45
void increment()
Definition: rah - Copie.hpp:1029
auto count(V &&value)
Counts the elements that are equal to value.
Definition: rah - Copie.hpp:1504
auto none_of(P &&pred)
Checks if unary predicate pred returns true for no elements in the range.
Definition: rah - Copie.hpp:1485
auto any_of(P &&pred)
Checks if unary predicate pred returns true for at least one element in the range.
Definition: rah - Copie.hpp:1447
repeat_iterator(U val)
Definition: rah - Copie.hpp:613
void increment()
Definition: rah - Copie.hpp:1121
auto mismatch(R1 &&range1, R2 &&range2)
Finds the first position where two ranges differ.
Definition: rah - Copie.hpp:1569
I iter_
Definition: rah - Copie.hpp:426
I end()
Definition: rah - Copie.hpp:88
auto equal_range(V &&value, P &&pred, std ::enable_if_t<!is_range< V >::value, int >=0)
Returns a range containing all elements equivalent to value in the range.
Definition: rah - Copie.hpp:1365
bool equal(stride_iterator other) const
Definition: rah - Copie.hpp:904
auto distance_to(ints_iterator other) const
Definition: rah - Copie.hpp:565
void decrement()
Definition: rah - Copie.hpp:617
Definition: rah - Copie.hpp:881
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:903
zip_iterator(IterTuple const &iters)
Definition: rah - Copie.hpp:1028
range_begin_type_t< R > iter_
Definition: rah - Copie.hpp:1049
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 - Copie.hpp:772
optional(T const &other)
Definition: rah - Copie.hpp:356
auto distance_to(stride_iterator other) const
Definition: rah - Copie.hpp:905
auto map_value()
Given a range of std::pair-std::tuple, create a view consisting of just the first element of the pair...
Definition: rah - Copie.hpp:1253
typename pointer_type< R >::type pointer
Definition: rah - Copie.hpp:153
I begin(iterator_range< I > const &r)
Get the begin iterator of the range.
Definition: rah - Copie.hpp:102
void advance(intptr_t value)
Definition: rah - Copie.hpp:616
auto binary_search(V &&value)
Checks if an element equivalent to value appears within the range.
Definition: rah - Copie.hpp:1384
bool equal(take_iterator r) const
Definition: rah - Copie.hpp:437
Definition: rah - Copie.hpp:607
R range_
Definition: rah - Copie.hpp:721
bool equal(repeat_iterator) const
Definition: rah - Copie.hpp:619
size_t step_
Definition: rah - Copie.hpp:885
auto size()
Get the size of range.
Definition: rah - Copie.hpp:1723
~optional()
Definition: rah - Copie.hpp:373
Definition: rah - Copie.hpp:1755
size_t step_
Definition: rah - Copie.hpp:1052
auto dereference() const -> decltype(*iter_)
Definition: rah - Copie.hpp:472
void advance(intptr_t value)
Definition: rah - Copie.hpp:588
auto operator=(V &&value) const
Definition: rah - Copie.hpp:197
auto dereference() const -> decltype(*std ::get< 0 >(iter_))
Definition: rah - Copie.hpp:1182
auto make_iterator_range(I b, I e)
Create a rah::iterator_range with two given iterators.
Definition: rah - Copie.hpp:92
auto & operator++()
Definition: rah - Copie.hpp:161
bool equal(counted_iterator r) const
Definition: rah - Copie.hpp:473
I end(iterator_range< I > const &r)
Get the "past the" end iterator of the range.
Definition: rah - Copie.hpp:104
T const & get() const
Definition: rah - Copie.hpp:388
void next_valid()
Definition: rah - Copie.hpp:661
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
Definition: rah - Copie.hpp:768
void advance(intptr_t value)
Definition: rah - Copie.hpp:902
void increment()
Definition: rah - Copie.hpp:468
void decrement()
Definition: rah - Copie.hpp:813
void increment()
Definition: rah - Copie.hpp:811
auto join()
Given a range of ranges, join them into a flattened sequence of elements.
Definition: rah - Copie.hpp:711
auto make_pipeable(MakeRange &&make_range)
Call to create a "pipeable" function (UFCS style in c++)
Definition: rah - Copie.hpp:115
bool end_
Definition: rah - Copie.hpp:507
std ::remove_reference_t< R > value_type
Definition: rah - Copie.hpp:181
auto operator-(intptr_t increment)
Definition: rah - Copie.hpp:247
transform_iterator & operator=(transform_iterator const &ot)
Definition: rah - Copie.hpp:804
auto dereference() const
Definition: rah - Copie.hpp:1032
back_insert_iterator(C &container)
Definition: rah - Copie.hpp:269
bool operator>=(I other) const
Definition: rah - Copie.hpp:258
bool operator!=(I other) const
Definition: rah - Copie.hpp:193
auto dereference() const
Definition: rah - Copie.hpp:591
decltype(begin(fake< T >())) range_begin_type_t
Definition: rah - Copie.hpp:57
size_t count_
Definition: rah - Copie.hpp:463
auto stride(size_t step)
Create a view consisting of every Nth element, starting with the first.
Definition: rah - Copie.hpp:917
std ::forward_iterator_tag iterator_category
Definition: rah - Copie.hpp:180
I iter_
Definition: rah - Copie.hpp:506
cycle_iterator(U &&range, Iterator iter)
Definition: rah - Copie.hpp:728
bool equal(transform_iterator r) const
Definition: rah - Copie.hpp:816
Definition: rah - Copie.hpp:456
bool operator>(I other) const
Definition: rah - Copie.hpp:257
range_begin_type_t< R > iter_
Definition: rah - Copie.hpp:1095
Definition: rah - Copie.hpp:297
details::optional< SubRange > subRange_
Definition: rah - Copie.hpp:641
bool equal(join_iterator other) const
Definition: rah - Copie.hpp:682
Inerit to make an iterator.
Definition: rah - Copie.hpp:128
auto & operator-=(intptr_t increment)
Definition: rah - Copie.hpp:241
bool operator!=(I other) const
Definition: rah - Copie.hpp:173
auto operator|(R &&range, pipeable< MakeRange > const &adapter) -> decltype(adapter.func(std ::forward< R >(range)))
Definition: rah - Copie.hpp:121
Iterator beginIter_
Definition: rah - Copie.hpp:723
auto operator->() const
Definition: rah - Copie.hpp:172
stream_inserter_iterator(S &stream)
Definition: rah - Copie.hpp:1758
S * stream_
Definition: rah - Copie.hpp:1757
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 - Copie.hpp:1966
range_begin_type_t< R > iter_
Definition: rah - Copie.hpp:883
auto equal(R1 &&range2)
Determines if two sets of elements are the same.
Definition: rah - Copie.hpp:1746
optional & operator=(T &&other)
Definition: rah - Copie.hpp:367
range_begin_type_t< R > iter2_
Definition: rah - Copie.hpp:1050
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 - Copie.hpp:469
auto dereference() const
Definition: rah - Copie.hpp:566
auto chunk(size_t step)
Create a view where each element is a range of N elements of the input range.
Definition: rah - Copie.hpp:1084
Apply the '==' operator on two values of any type.
Definition: rah - Copie.hpp:1931
T & fake()
Used in decltype to get an instance of a type.
Definition: rah - Copie.hpp:54
Iterator1 rangeIter_
Definition: rah - Copie.hpp:635
auto dereference() const
Definition: rah - Copie.hpp:1070
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 - Copie.hpp:1054
void increment()
Definition: rah - Copie.hpp:1063
auto stable_partition(P &&pred)
Definition: rah - Copie.hpp:1833
auto all_of(P &&pred)
Checks if unary predicate pred returns true for all elements in the range.
Definition: rah - Copie.hpp:1466
value_type * pointer
Definition: rah - Copie.hpp:183
Definition: rah - Copie.hpp:1092
void put(V &&value) const
Definition: rah - Copie.hpp:270
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 - Copie.hpp:1127
auto decrement()
Definition: rah - Copie.hpp:896
take_iterator(I iter, size_t count)
Definition: rah - Copie.hpp:430
auto operator-(I other) const
Definition: rah - Copie.hpp:254
void next_value()
Definition: rah - Copie.hpp:1110
auto empty()
Check if the range if empty.
Definition: rah - Copie.hpp:1322
void decrement()
Definition: rah - Copie.hpp:434
Func func
Definition: rah - Copie.hpp:111
Definition: rah - Copie.hpp:719
auto remove_if(P &&pred)
Keep only elements for which pred(elt) is false .
Definition: rah - Copie.hpp:2035
auto sort(P &&pred={})
Sort a range in place, using the given predicate.
Definition: rah - Copie.hpp:2061
auto copy(R2 &&out)
Copy in range into an other.
Definition: rah - Copie.hpp:1643
bool operator==(I other) const
Definition: rah - Copie.hpp:174
void increment()
Definition: rah - Copie.hpp:774
IterPair end_
Definition: rah - Copie.hpp:1161
intptr_t difference_type
Definition: rah - Copie.hpp:182
bool equal(cycle_iterator) const
Definition: rah - Copie.hpp:743
stride_iterator(range_begin_type_t< R > const &iter, range_end_type_t< R > const &end, size_t step)
Definition: rah - Copie.hpp:887
details::optional< F > func_
Definition: rah - Copie.hpp:800
details::optional< F > func_
Definition: rah - Copie.hpp:1097
V const & dereference() const
Definition: rah - Copie.hpp:618
Definition: rah - Copie.hpp:1020
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 - Copie.hpp:1031
Reference const * operator->() const
Definition: rah - Copie.hpp:139
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
Allow to call a custom function when called whith the 'pipe' syntax on a range.
Definition: rah - Copie.hpp:109
I begin()
Definition: rah - Copie.hpp:86
bool equal(ints_iterator other) const
Definition: rah - Copie.hpp:567
range_begin_type_t< decltype(*fake< Iterator1 >())> Iterator2
Definition: rah - Copie.hpp:634
auto find_if(P &&pred)
Finds the first element satisfying specific criteria.
Definition: rah - Copie.hpp:1605
void increment()
Definition: rah - Copie.hpp:512
T & get()
Definition: rah - Copie.hpp:386
void advance(intptr_t off)
Definition: rah - Copie.hpp:812
auto find_if_not(P &&pred)
Finds the first element not satisfying specific criteria.
Definition: rah - Copie.hpp:1622
Iterator endIter_
Definition: rah - Copie.hpp:724
Iterator iter_
Definition: rah - Copie.hpp:725
#define RAH_NAMESPACE
Definition: rah - Copie.hpp:39
auto distance_to(transform_iterator r) const
Definition: rah - Copie.hpp:814
auto cycle()
Returns an infinite range that endlessly repeats the source range.
Definition: rah - Copie.hpp:759
auto slice(intptr_t begin, intptr_t end)
Create a view that is a sub-range of a range.
Definition: rah - Copie.hpp:873
void reset()
Definition: rah - Copie.hpp:377
auto distance_to(take_iterator r) const
Definition: rah - Copie.hpp:435
range_end_type_t< R > end_
Definition: rah - Copie.hpp:1096
auto map_key()
Given a range of std::pair-std::tuple, create a view consisting of just the second element of the pai...
Definition: rah - Copie.hpp:1268
Iterator2 subRangeIter
Definition: rah - Copie.hpp:638
decltype(*begin(fake< T >())) range_ref_type_t
Definition: rah - Copie.hpp:63
Definition: rah - Copie.hpp:793
rah ::details::optional< Reference > type
Definition: rah.hpp:248
bool has_value() const
Definition: rah - Copie.hpp:375
void increment()
Definition: rah - Copie.hpp:587
Definition: rah - Copie.hpp:420
auto & operator+=(intptr_t increment)
Definition: rah - Copie.hpp:228
T const * operator->() const
Definition: rah - Copie.hpp:393
auto fill(V &&value)
Assigns the given value to the elements in the range [first, last)
Definition: rah - Copie.hpp:2106
void put(V &&value) const
Definition: rah - Copie.hpp:1759
void increment()
Definition: rah - Copie.hpp:736
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
range_end_type_t< R > end_
Definition: rah - Copie.hpp:884
std ::remove_reference_t< R > value_type
Definition: rah - Copie.hpp:151
auto to_container()
Return a container of type C, filled with the content of range.
Definition: rah - Copie.hpp:1559
auto partition(P &&pred)
Definition: rah - Copie.hpp:1811
Definition: rah - Copie.hpp:579
bool operator<=(I other) const
Definition: rah - Copie.hpp:256
auto & operator--()
Definition: rah - Copie.hpp:213
C * container_
Definition: rah - Copie.hpp:268
bool operator<(I other) const
Definition: rah - Copie.hpp:255
std ::forward_iterator_tag iterator_category
Definition: rah - Copie.hpp:150
range_begin_type_t< R > begin_
Definition: rah - Copie.hpp:1094
auto shuffle(URBG &&g)
Reorders the elements in the given range such that each possible permutation of those elements has eq...
Definition: rah - Copie.hpp:2086
I begin_iter
Definition: rah - Copie.hpp:82
size_t count_
Definition: rah - Copie.hpp:427
void advance(intptr_t off)
Definition: rah - Copie.hpp:433
auto distance_to(unbounded_iterator r) const
Definition: rah - Copie.hpp:516
Definition: rah - Copie.hpp:266
range_begin_type_t< R > Iterator1
Definition: rah - Copie.hpp:633
join_iterator(U &&range, Iterator1 rangeIter)
Definition: rah - Copie.hpp:655
range_begin_type_t< R > Iterator
Definition: rah - Copie.hpp:722
auto find(V &&value)
Finds the first element equal to value.
Definition: rah - Copie.hpp:1588
iota_iterator(T val, T step)
Definition: rah - Copie.hpp:585
auto dereference() const -> decltype((*func_)(*iter_))
Definition: rah - Copie.hpp:815
void decrement()
Definition: rah - Copie.hpp:470
size_t range_index_
Definition: rah - Copie.hpp:1162
bool equal(zip_iterator other) const
Definition: rah - Copie.hpp:1034
void increment()
Definition: rah - Copie.hpp:562
Iterator2 subRangeEnd
Definition: rah - Copie.hpp:639
bool equal(iota_iterator other) const
Definition: rah - Copie.hpp:592
R range_
Definition: rah - Copie.hpp:632
bool operator()(A &&a, B &&b)
Definition: rah - Copie.hpp:1933
void advance(intptr_t off)
Definition: rah - Copie.hpp:514
I iter_
Definition: rah - Copie.hpp:462
auto erase(R &&range)
Erase a sub-range of a given container.
Definition: rah - Copie.hpp:1855
auto increment()
Definition: rah - Copie.hpp:890
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