diff --git a/octa/array.h b/octa/array.h index aec94b2..dd5894e 100644 --- a/octa/array.h +++ b/octa/array.h @@ -25,6 +25,8 @@ struct Array { using ConstPointer = const T *; using Range = octa::PointerRange; using ConstRange = octa::PointerRange; + using ReverseRange = octa::ReverseRange; + using ConstReverseRange = octa::ReverseRange; T &operator[](Size i) { return p_buf[i]; } const T &operator[](Size i) const { return p_buf[i]; } @@ -57,6 +59,19 @@ struct Array { ConstRange each() const { return ConstRange(p_buf, p_buf + N); } + ConstRange ceach() const { + return ConstRange(p_buf, p_buf + N); + } + + ReverseRange reach() { + return each().reach(); + } + ConstReverseRange reach() const { + return each().reach(); + } + ConstReverseRange creach() const { + return ceach().reach(); + } void swap(Array &v) { octa::swap_ranges(each(), v.each()); diff --git a/octa/initializer_list.h b/octa/initializer_list.h index 75c832f..15b941c 100644 --- a/octa/initializer_list.h +++ b/octa/initializer_list.h @@ -43,6 +43,25 @@ octa::PointerRange each(std::initializer_list init) { return octa::PointerRange(init.begin(), init.end()); } +template +octa::PointerRange ceach(std::initializer_list init) { + return octa::PointerRange(init.begin(), init.end()); +} + +template +octa::ReverseRange> +reach(std::initializer_list init) { + return octa::ReverseRange>(init.begin(), + init.end()); +} + +template +octa::ReverseRange> +ceach(std::initializer_list init) { + return octa::ReverseRange>(init.begin(), + init.end()); +} + } #endif \ No newline at end of file diff --git a/octa/range.h b/octa/range.h index 0062ac3..8a81bba 100644 --- a/octa/range.h +++ b/octa/range.h @@ -284,6 +284,8 @@ namespace detail { } } +template struct ReverseRange; + template struct InputRange { @@ -320,11 +322,45 @@ template reach() const { + return ReverseRange(each()); + } + RangeHalf half() const { return RangeHalf(*((B *)this)); } }; +template +auto each(T &r) -> decltype(r.each()) { + return r.each(); +} + +template +auto each(const T &r) -> decltype(r.each()) { + return r.each(); +} + +template +auto ceach(const T &r) -> decltype(r.each()) { + return r.each(); +} + +template +auto reach(T &r) -> decltype(r.reach()) { + return r.reach(); +} + +template +auto reach(const T &r) -> decltype(r.reach()) { + return r.reach(); +} + +template +auto creach(const T &r) -> decltype(r.reach()) { + return r.reach(); +} + template struct OutputRange { @@ -412,11 +448,6 @@ public: } }; -template -ReverseRange make_reverse_range(const T &it) { - return ReverseRange(it); -} - template struct MoveRange: InputRange, RangeCategory, RangeValue, RangeValue &&, RangeSize, @@ -644,6 +675,16 @@ private: T *p_beg, *p_end; }; +template +PointerRange each(T (&array)[N]) { + return PointerRange(array, N); +} + +template +ReverseRange> reach(T (&array)[N]) { + return ReverseRange>(PointerRange(array, N)); +} + template struct EnumeratedValue { S index; @@ -858,21 +899,6 @@ ChunksRange chunks(const T &it, RangeSize chs) { return ChunksRange(it, chs); } -template -auto each(T &r) -> decltype(r.each()) { - return r.each(); -} - -template -auto each(const T &r) -> decltype(r.each()) { - return r.each(); -} - -template -PointerRange each(T (&array)[N]) { - return PointerRange(array, N); -} - // range of template using RangeOf = decltype(octa::each(octa::declval())); diff --git a/octa/string.h b/octa/string.h index 154240a..62b485c 100644 --- a/octa/string.h +++ b/octa/string.h @@ -149,6 +149,8 @@ public: using ConstPointer = const T *; using Range = octa::StringRangeBase; using ConstRange = octa::StringRangeBase; + using ReverseRange = octa::ReverseRange; + using ConstReverseRange = octa::ReverseRange; using Allocator = A; StringBase(const A &a = A()): p_buf(1, '\0', a) {} @@ -294,6 +296,19 @@ public: ConstRange each() const { return ConstRange(p_buf.data(), size()); } + ConstRange ceach() const { + return ConstRange(p_buf.data(), size()); + } + + ReverseRange reach() { + return each().reach(); + } + ConstReverseRange reach() const { + return each().reach(); + } + ConstReverseRange creach() const { + return ceach().reach(); + } void swap(StringBase &v) { p_buf.swap(v); diff --git a/octa/vector.h b/octa/vector.h index 88a7d17..0c0ca82 100644 --- a/octa/vector.h +++ b/octa/vector.h @@ -127,6 +127,8 @@ public: using ConstPointer = const T *; using Range = octa::PointerRange; using ConstRange = octa::PointerRange; + using ReverseRange = octa::ReverseRange; + using ConstReverseRange = octa::ReverseRange; using Allocator = A; Vector(const A &a = A()): p_buf(nullptr, a), p_len(0), p_cap(0) {} @@ -411,6 +413,19 @@ public: ConstRange each() const { return ConstRange(p_buf.p_ptr, p_buf.p_ptr + p_len); } + ConstRange ceach() const { + return ConstRange(p_buf.p_ptr, p_buf.p_ptr + p_len); + } + + ReverseRange reach() { + return each().reach(); + } + ConstReverseRange reach() const { + return each().reach(); + } + ConstReverseRange creach() const { + return ceach().reach(); + } void swap(Vector &v) { octa::swap(p_len, v.p_len);