deassify algorithm.h

master
Daniel Kolesa 2015-06-03 22:54:18 +01:00
parent ae05420994
commit d442ba2508
1 changed files with 538 additions and 537 deletions

View File

@ -18,22 +18,22 @@ namespace octa {
/* partitioning */ /* partitioning */
template<typename _R, typename _U> template<typename _R, typename _U>
_R partition(_R __range, _U __pred) { _R partition(_R range, _U pred) {
_R __ret = __range; _R ret = range;
for (; !__range.empty(); __range.pop_front()) { for (; !range.empty(); range.pop_front()) {
if (__pred(__range.front())) { if (pred(range.front())) {
octa::swap(__range.front(), __ret.front()); octa::swap(range.front(), ret.front());
__ret.pop_front(); ret.pop_front();
} }
} }
return __ret; return ret;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
bool is_partitioned(_R __range, _P __pred) { bool is_partitioned(_R range, _P pred) {
for (; !__range.empty() && __pred(__range.front()); __range.pop_front()); for (; !range.empty() && pred(range.front()); range.pop_front());
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__pred(__range.front())) return false; if (pred(range.front())) return false;
return true; return true;
} }
@ -41,375 +41,375 @@ namespace octa {
namespace detail { namespace detail {
template<typename _R, typename _C> template<typename _R, typename _C>
void insort(_R __range, _C __compare) { void insort(_R range, _C compare) {
octa::RangeSize<_R> __rlen = __range.size(); octa::RangeSize<_R> rlen = range.size();
for (octa::RangeSize<_R> __i = 1; __i < __rlen; ++__i) { for (octa::RangeSize<_R> i = 1; i < rlen; ++i) {
octa::RangeSize<_R> __j = __i; octa::RangeSize<_R> j = i;
octa::RangeReference<_R> __v = __range[__i]; octa::RangeReference<_R> v = range[i];
while (__j > 0 && !__compare(__range[__j - 1], __v)) { while (j > 0 && !compare(range[j - 1], v)) {
__range[__j] = __range[__j - 1]; range[j] = range[j - 1];
--__j; --j;
} }
__range[__j] = __v; range[j] = v;
} }
} }
template<typename _T, typename _U> template<typename _T, typename _U>
struct UnaryCompare { struct UnaryCompare {
const _T &__val; const _T &val;
_U __comp; _U comp;
bool operator()(const _T &__v) const { return __comp(__v, __val); } bool operator()(const _T &v) const { return comp(v, val); }
}; };
template<typename _R, typename _C> template<typename _R, typename _C>
void hs_sift_down(_R __range, octa::RangeSize<_R> __s, void hs_sift_down(_R range, octa::RangeSize<_R> s,
octa::RangeSize<_R> __e, _C __compare) { octa::RangeSize<_R> e, _C compare) {
octa::RangeSize<_R> __r = __s; octa::RangeSize<_R> r = s;
while ((__r * 2 + 1) <= __e) { while ((r * 2 + 1) <= e) {
octa::RangeSize<_R> __ch = __r * 2 + 1; octa::RangeSize<_R> ch = r * 2 + 1;
octa::RangeSize<_R> __sw = __r; octa::RangeSize<_R> sw = r;
if (__compare(__range[__sw], __range[__ch])) if (compare(range[sw], range[ch]))
__sw = __ch; sw = ch;
if (((__ch + 1) <= __e) && __compare(__range[__sw], __range[__ch + 1])) if (((ch + 1) <= e) && compare(range[sw], range[ch + 1]))
__sw = __ch + 1; sw = ch + 1;
if (__sw != __r) { if (sw != r) {
octa::swap(__range[__r], __range[__sw]); octa::swap(range[r], range[sw]);
__r = __sw; r = sw;
} else return; } else return;
} }
} }
template<typename _R, typename _C> template<typename _R, typename _C>
void heapsort(_R __range, _C __compare) { void heapsort(_R range, _C compare) {
octa::RangeSize<_R> __len = __range.size(); octa::RangeSize<_R> len = range.size();
octa::RangeSize<_R> __st = (__len - 2) / 2; octa::RangeSize<_R> st = (len - 2) / 2;
for (;;) { for (;;) {
octa::detail::hs_sift_down(__range, __st, __len - 1, __compare); octa::detail::hs_sift_down(range, st, len - 1, compare);
if (__st-- == 0) break; if (st-- == 0) break;
} }
octa::RangeSize<_R> __e = __len - 1; octa::RangeSize<_R> e = len - 1;
while (__e > 0) { while (e > 0) {
octa::swap(__range[__e], __range[0]); octa::swap(range[e], range[0]);
--__e; --e;
octa::detail::hs_sift_down(__range, 0, __e, __compare); octa::detail::hs_sift_down(range, 0, e, compare);
} }
} }
template<typename _R, typename _C> template<typename _R, typename _C>
void introloop(_R __range, _C __compare, RangeSize<_R> __depth) { void introloop(_R range, _C compare, RangeSize<_R> depth) {
if (__range.size() <= 10) { if (range.size() <= 10) {
octa::detail::insort(__range, __compare); octa::detail::insort(range, compare);
return; return;
} }
if (__depth == 0) { if (depth == 0) {
octa::detail::heapsort(__range, __compare); octa::detail::heapsort(range, compare);
return; return;
} }
octa::RangeReference<_R> __p = __range[__range.size() / 2]; octa::RangeReference<_R> p = range[range.size() / 2];
octa::swap(__p, __range.back()); octa::swap(p, range.back());
_R __r = octa::partition(__range, _R r = octa::partition(range,
octa::detail::UnaryCompare<decltype(__p), _C>{ __p, __compare }); octa::detail::UnaryCompare<decltype(p), _C>{ p, compare });
_R __l = __range.slice(0, __range.size() - __r.size()); _R l = range.slice(0, range.size() - r.size());
octa::swap(__r.front(), __r.back()); octa::swap(r.front(), r.back());
octa::detail::introloop(__l, __compare, __depth - 1); octa::detail::introloop(l, compare, depth - 1);
octa::detail::introloop(__r, __compare, __depth - 1); octa::detail::introloop(r, compare, depth - 1);
} }
template<typename _R, typename _C> template<typename _R, typename _C>
void introsort(_R __range, _C __compare) { void introsort(_R range, _C compare) {
octa::detail::introloop(__range, __compare, octa::RangeSize<_R>(2 octa::detail::introloop(range, compare, octa::RangeSize<_R>(2
* (log(__range.size()) / log(2)))); * (log(range.size()) / log(2))));
}
} }
} /* namespace detail */
template<typename _R, typename _C> template<typename _R, typename _C>
void sort(_R __range, _C __compare) { void sort(_R range, _C compare) {
octa::detail::introsort(__range, __compare); octa::detail::introsort(range, compare);
} }
template<typename _R> template<typename _R>
void sort(_R __range) { void sort(_R range) {
sort(__range, octa::Less<RangeValue<_R>>()); sort(range, octa::Less<RangeValue<_R>>());
} }
/* min/max(_element) */ /* min/max(_element) */
template<typename _T> template<typename _T>
inline const _T &min(const _T &__a, const _T &__b) { inline const _T &min(const _T &a, const _T &b) {
return (__a < __b) ? __a : __b; return (a < b) ? a : b;
} }
template<typename _T, typename _C> template<typename _T, typename _C>
inline const _T &min(const _T &__a, const _T &__b, _C __compare) { inline const _T &min(const _T &a, const _T &b, _C compare) {
return __compare(__a, __b) ? __a : __b; return compare(a, b) ? a : b;
} }
template<typename _T> template<typename _T>
inline const _T &max(const _T &__a, const _T &__b) { inline const _T &max(const _T &a, const _T &b) {
return (__a < __b) ? __b : __a; return (a < b) ? b : a;
} }
template<typename _T, typename _C> template<typename _T, typename _C>
inline const _T &max(const _T &__a, const _T &__b, _C __compare) { inline const _T &max(const _T &a, const _T &b, _C compare) {
return __compare(__a, __b) ? __b : __a; return compare(a, b) ? b : a;
} }
template<typename _R> template<typename _R>
inline _R min_element(_R __range) { inline _R min_element(_R range) {
_R __r = __range; _R r = range;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (octa::min(__r.front(), __range.front()) == __range.front()) if (octa::min(r.front(), range.front()) == range.front())
__r = __range; r = range;
return __r; return r;
} }
template<typename _R, typename _C> template<typename _R, typename _C>
inline _R min_element(_R __range, _C __compare) { inline _R min_element(_R range, _C compare) {
_R __r = __range; _R r = range;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (octa::min(__r.front(), __range.front(), __compare) == __range.front()) if (octa::min(r.front(), range.front(), compare) == range.front())
__r = __range; r = range;
return __r; return r;
} }
template<typename _R> template<typename _R>
inline _R max_element(_R __range) { inline _R max_element(_R range) {
_R __r = __range; _R r = range;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (octa::max(__r.front(), __range.front()) == __range.front()) if (octa::max(r.front(), range.front()) == range.front())
__r = __range; r = range;
return __r; return r;
} }
template<typename _R, typename _C> template<typename _R, typename _C>
inline _R max_element(_R __range, _C __compare) { inline _R max_element(_R range, _C compare) {
_R __r = __range; _R r = range;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (octa::max(__r.front(), __range.front(), __compare) == __range.front()) if (octa::max(r.front(), range.front(), compare) == range.front())
__r = __range; r = range;
return __r; return r;
} }
template<typename _T> template<typename _T>
inline _T min(std::initializer_list<_T> __il) { inline _T min(std::initializer_list<_T> il) {
return octa::min_element(octa::each(__il)).front(); return octa::min_element(octa::each(il)).front();
} }
template<typename _T, typename _C> template<typename _T, typename _C>
inline _T min(std::initializer_list<_T> __il, _C __compare) { inline _T min(std::initializer_list<_T> il, _C compare) {
return octa::min_element(octa::each(__il), __compare).front(); return octa::min_element(octa::each(il), compare).front();
} }
template<typename _T> template<typename _T>
inline _T max(std::initializer_list<_T> __il) { inline _T max(std::initializer_list<_T> il) {
return octa::max_element(octa::each(__il)).front(); return octa::max_element(octa::each(il)).front();
} }
template<typename _T, typename _C> template<typename _T, typename _C>
inline _T max(std::initializer_list<_T> __il, _C __compare) { inline _T max(std::initializer_list<_T> il, _C compare) {
return octa::max_element(octa::each(__il), __compare).front(); return octa::max_element(octa::each(il), compare).front();
} }
/* clamp */ /* clamp */
template<typename _T, typename _U> template<typename _T, typename _U>
inline _T clamp(const _T &__v, const _U &__lo, const _U &__hi) { inline _T clamp(const _T &v, const _U &lo, const _U &hi) {
return octa::max(_T(__lo), octa::min(__v, _T(__hi))); return octa::max(_T(lo), octa::min(v, _T(hi)));
} }
template<typename _T, typename _U, typename _C> template<typename _T, typename _U, typename _C>
inline _T clamp(const _T &__v, const _U &__lo, const _U &__hi, _C __compare) { inline _T clamp(const _T &v, const _U &lo, const _U &hi, _C compare) {
return octa::max(_T(__lo), octa::min(__v, _T(__hi), __compare), __compare); return octa::max(_T(lo), octa::min(v, _T(hi), compare), compare);
} }
/* algos that don't change the range */ /* algos that don't change the range */
template<typename _R, typename _F> template<typename _R, typename _F>
_F for_each(_R __range, _F __func) { _F for_each(_R range, _F func) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__func(__range.front()); func(range.front());
return octa::move(__func); return octa::move(func);
} }
template<typename _R, typename _P> template<typename _R, typename _P>
bool all_of(_R __range, _P __pred) { bool all_of(_R range, _P pred) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (!__pred(__range.front())) return false; if (!pred(range.front())) return false;
return true; return true;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
bool any_of(_R __range, _P __pred) { bool any_of(_R range, _P pred) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__pred(__range.front())) return true; if (pred(range.front())) return true;
return false; return false;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
bool none_of(_R __range, _P __pred) { bool none_of(_R range, _P pred) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__pred(__range.front())) return false; if (pred(range.front())) return false;
return true; return true;
} }
template<typename _R, typename _T> template<typename _R, typename _T>
_R find(_R __range, const _T &__v) { _R find(_R range, const _T &v) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__range.front() == __v) if (range.front() == v)
break; break;
return __range; return range;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
_R find_if(_R __range, _P __pred) { _R find_if(_R range, _P pred) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__pred(__range.front())) if (pred(range.front()))
break; break;
return __range; return range;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
_R find_if_not(_R __range, _P __pred) { _R find_if_not(_R range, _P pred) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (!__pred(__range.front())) if (!pred(range.front()))
break; break;
return __range; return range;
} }
template<typename _R, typename _T> template<typename _R, typename _T>
RangeSize<_R> count(_R __range, const _T &__v) { RangeSize<_R> count(_R range, const _T &v) {
RangeSize<_R> __ret = 0; RangeSize<_R> ret = 0;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__range.front() == __v) if (range.front() == v)
++__ret; ++ret;
return __ret; return ret;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
RangeSize<_R> count_if(_R __range, _P __pred) { RangeSize<_R> count_if(_R range, _P pred) {
RangeSize<_R> __ret = 0; RangeSize<_R> ret = 0;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (__pred(__range.front())) if (pred(range.front()))
++__ret; ++ret;
return __ret; return ret;
} }
template<typename _R, typename _P> template<typename _R, typename _P>
RangeSize<_R> count_if_not(_R __range, _P __pred) { RangeSize<_R> count_if_not(_R range, _P pred) {
RangeSize<_R> __ret = 0; RangeSize<_R> ret = 0;
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
if (!__pred(__range.front())) if (!pred(range.front()))
++__ret; ++ret;
return __ret; return ret;
} }
template<typename _R> template<typename _R>
bool equal(_R __range1, _R __range2) { bool equal(_R range1, _R range2) {
for (; !__range1.empty(); __range1.pop_front()) { for (; !range1.empty(); range1.pop_front()) {
if (__range2.empty() || (__range1.front() != __range2.front())) if (range2.empty() || (range1.front() != range2.front()))
return false; return false;
__range2.pop_front(); range2.pop_front();
} }
return __range2.empty(); return range2.empty();
} }
/* algos that modify ranges or work with output ranges */ /* algos that modify ranges or work with output ranges */
template<typename _R1, typename _R2> template<typename _R1, typename _R2>
_R2 copy(_R1 __irange, _R2 __orange) { _R2 copy(_R1 irange, _R2 orange) {
for (; !__irange.empty(); __irange.pop_front()) for (; !irange.empty(); irange.pop_front())
__orange.put(__irange.front()); orange.put(irange.front());
return __orange; return orange;
} }
template<typename _R1, typename _R2, typename _P> template<typename _R1, typename _R2, typename _P>
_R2 copy_if(_R1 __irange, _R2 __orange, _P __pred) { _R2 copy_if(_R1 irange, _R2 orange, _P pred) {
for (; !__irange.empty(); __irange.pop_front()) for (; !irange.empty(); irange.pop_front())
if (__pred(__irange.front())) if (pred(irange.front()))
__orange.put(__irange.front()); orange.put(irange.front());
return __orange; return orange;
} }
template<typename _R1, typename _R2, typename _P> template<typename _R1, typename _R2, typename _P>
_R2 copy_if_not(_R1 __irange, _R2 __orange, _P __pred) { _R2 copy_if_not(_R1 irange, _R2 orange, _P pred) {
for (; !__irange.empty(); __irange.pop_front()) for (; !irange.empty(); irange.pop_front())
if (!__pred(__irange.front())) if (!pred(irange.front()))
__orange.put(__irange.front()); orange.put(irange.front());
return __orange; return orange;
} }
template<typename _R1, typename _R2> template<typename _R1, typename _R2>
_R2 move(_R1 __irange, _R2 __orange) { _R2 move(_R1 irange, _R2 orange) {
for (; !__irange.empty(); __irange.pop_front()) for (; !irange.empty(); irange.pop_front())
__orange.put(octa::move(__irange.front())); orange.put(octa::move(irange.front()));
return __orange; return orange;
} }
template<typename _R> template<typename _R>
void reverse(_R __range) { void reverse(_R range) {
while (!__range.empty()) { while (!range.empty()) {
octa::swap(__range.front(), __range.back()); octa::swap(range.front(), range.back());
__range.pop_front(); range.pop_front();
__range.pop_back(); range.pop_back();
} }
} }
template<typename _R1, typename _R2> template<typename _R1, typename _R2>
_R2 reverse_copy(_R1 __irange, _R2 __orange) { _R2 reverse_copy(_R1 irange, _R2 orange) {
for (; !__irange.empty(); __irange.pop_back()) for (; !irange.empty(); irange.pop_back())
__orange.put(__irange.back()); orange.put(irange.back());
return __orange; return orange;
} }
template<typename _R, typename _T> template<typename _R, typename _T>
void fill(_R __range, const _T &__v) { void fill(_R range, const _T &v) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__range.front() = __v; range.front() = v;
} }
template<typename _R, typename _F> template<typename _R, typename _F>
void generate(_R __range, _F __gen) { void generate(_R range, _F gen) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__range.front() = __gen(); range.front() = gen();
} }
template<typename _R1, typename _R2> template<typename _R1, typename _R2>
octa::Pair<_R1, _R2> swap_ranges(_R1 __range1, _R2 __range2) { octa::Pair<_R1, _R2> swap_ranges(_R1 range1, _R2 range2) {
while (!__range1.empty() && !__range2.empty()) { while (!range1.empty() && !range2.empty()) {
octa::swap(__range1.front(), __range2.front()); octa::swap(range1.front(), range2.front());
__range1.pop_front(); range1.pop_front();
__range2.pop_front(); range2.pop_front();
} }
return octa::make_pair(__range1, __range2); return octa::make_pair(range1, range2);
} }
template<typename _R, typename _T> template<typename _R, typename _T>
void iota(_R __range, _T __value) { void iota(_R range, _T value) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__range.front() = __value++; range.front() = value++;
} }
template<typename _R, typename _T> template<typename _R, typename _T>
_T foldl(_R __range, _T __init) { _T foldl(_R range, _T init) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__init = __init + __range.front(); init = init + range.front();
return __init; return init;
} }
template<typename _R, typename _T, typename _F> template<typename _R, typename _T, typename _F>
_T foldl(_R __range, _T __init, _F __func) { _T foldl(_R range, _T init, _F func) {
for (; !__range.empty(); __range.pop_front()) for (; !range.empty(); range.pop_front())
__init = __func(__init, __range.front()); init = func(init, range.front());
return __init; return init;
} }
template<typename _R, typename _T> template<typename _R, typename _T>
_T foldr(_R __range, _T __init) { _T foldr(_R range, _T init) {
for (; !__range.empty(); __range.pop_back()) for (; !range.empty(); range.pop_back())
__init = __init + __range.back(); init = init + range.back();
return __init; return init;
} }
template<typename _R, typename _T, typename _F> template<typename _R, typename _T, typename _F>
_T foldr(_R __range, _T __init, _F __func) { _T foldr(_R range, _T init, _F func) {
for (; !__range.empty(); __range.pop_back()) for (; !range.empty(); range.pop_back())
__init = __func(__init, __range.back()); init = func(init, range.back());
return __init; return init;
} }
template<typename _T, typename _R> template<typename _T, typename _R>
@ -417,77 +417,77 @@ namespace octa {
MapRange<_T, _R>, octa::RangeCategory<_T>, _R, _R, octa::RangeSize<_T> MapRange<_T, _R>, octa::RangeCategory<_T>, _R, _R, octa::RangeSize<_T>
> { > {
private: private:
_T __range; _T p_range;
octa::Function<_R(octa::RangeReference<_T>)> __func; octa::Function<_R(octa::RangeReference<_T>)> p_func;
public: public:
MapRange(): __range(), __func() {} MapRange(): p_range(), p_func() {}
template<typename _F> template<typename _F>
MapRange(const _T &__range, const _F &__func): MapRange(const _T &range, const _F &func):
__range(__range), __func(__func) {} p_range(range), p_func(func) {}
MapRange(const MapRange &__it): MapRange(const MapRange &it):
__range(__it.__range), __func(__it.__func) {} p_range(it.p_range), p_func(it.p_func) {}
MapRange(MapRange &&__it): MapRange(MapRange &&it):
__range(move(__it.__range)), __func(move(__it.__func)) {} p_range(move(it.p_range)), p_func(move(it.p_func)) {}
MapRange &operator=(const MapRange &__v) { MapRange &operator=(const MapRange &v) {
__range = __v.__range; p_range = v.p_range;
__func = __v.__func; p_func = v.p_func;
return *this; return *this;
} }
MapRange &operator=(MapRange &&__v) { MapRange &operator=(MapRange &&v) {
__range = move(__v.__range); p_range = move(v.p_range);
__func = move(__v.__func); p_func = move(v.p_func);
return *this; return *this;
} }
bool empty() const { return __range.empty(); } bool empty() const { return p_range.empty(); }
octa::RangeSize<_T> size() const { return __range.size(); } octa::RangeSize<_T> size() const { return p_range.size(); }
bool equals_front(const MapRange &__r) const { bool equals_front(const MapRange &r) const {
return __range.equals_front(__r.__range); return p_range.equals_front(r.p_range);
} }
bool equals_back(const MapRange &__r) const { bool equals_back(const MapRange &r) const {
return __range.equals_front(__r.__range); return p_range.equals_front(r.p_range);
} }
octa::RangeDifference<_T> distance_front(const MapRange &__r) const { octa::RangeDifference<_T> distance_front(const MapRange &r) const {
return __range.distance_front(__r.__range); return p_range.distance_front(r.p_range);
} }
octa::RangeDifference<_T> distance_back(const MapRange &__r) const { octa::RangeDifference<_T> distance_back(const MapRange &r) const {
return __range.distance_back(__r.__range); return p_range.distance_back(r.p_range);
} }
bool pop_front() { return __range.pop_front(); } bool pop_front() { return p_range.pop_front(); }
bool pop_back() { return __range.pop_back(); } bool pop_back() { return p_range.pop_back(); }
bool push_front() { return __range.pop_front(); } bool push_front() { return p_range.pop_front(); }
bool push_back() { return __range.push_back(); } bool push_back() { return p_range.push_back(); }
octa::RangeSize<_T> pop_front_n(octa::RangeSize<_T> __n) { octa::RangeSize<_T> pop_front_n(octa::RangeSize<_T> n) {
__range.pop_front_n(__n); p_range.pop_front_n(n);
} }
octa::RangeSize<_T> pop_back_n(octa::RangeSize<_T> __n) { octa::RangeSize<_T> pop_back_n(octa::RangeSize<_T> n) {
__range.pop_back_n(__n); p_range.pop_back_n(n);
} }
octa::RangeSize<_T> push_front_n(octa::RangeSize<_T> __n) { octa::RangeSize<_T> push_front_n(octa::RangeSize<_T> n) {
return __range.push_front_n(__n); return p_range.push_front_n(n);
} }
octa::RangeSize<_T> push_back_n(octa::RangeSize<_T> __n) { octa::RangeSize<_T> push_back_n(octa::RangeSize<_T> n) {
return __range.push_back_n(__n); return p_range.push_back_n(n);
} }
_R front() const { return __func(__range.front()); } _R front() const { return p_func(p_range.front()); }
_R back() const { return __func(__range.back()); } _R back() const { return p_func(p_range.back()); }
_R operator[](octa::RangeSize<_T> __idx) const { _R operator[](octa::RangeSize<_T> idx) const {
return __func(__range[__idx]); return p_func(p_range[idx]);
} }
MapRange<_T, _R> slice(octa::RangeSize<_T> __start, MapRange<_T, _R> slice(octa::RangeSize<_T> start,
octa::RangeSize<_T> __end) { octa::RangeSize<_T> end) {
return MapRange<_T, _R>(__range.slice(__start, __end), __func); return MapRange<_T, _R>(p_range.slice(start, end), p_func);
} }
}; };
@ -497,10 +497,10 @@ namespace octa {
} }
template<typename _R, typename _F> template<typename _R, typename _F>
MapRange<_R, octa::detail::MapReturnType<_R, _F>> map(_R __range, MapRange<_R, octa::detail::MapReturnType<_R, _F>> map(_R range,
_F __func) { _F func) {
return octa::MapRange<_R, octa::detail::MapReturnType<_R, _F>>(__range, return octa::MapRange<_R, octa::detail::MapReturnType<_R, _F>>(range,
__func); func);
} }
template<typename _T> template<typename _T>
@ -510,71 +510,72 @@ namespace octa {
octa::RangeValue<_T>, octa::RangeReference<_T>, octa::RangeSize<_T> octa::RangeValue<_T>, octa::RangeReference<_T>, octa::RangeSize<_T>
> { > {
private: private:
_T __range; _T p_range;
octa::Function<bool(octa::RangeReference<_T>)> __pred; octa::Function<bool(octa::RangeReference<_T>)> p_pred;
void advance_valid() { void advance_valid() {
while (!__range.empty() && !__pred(front())) __range.pop_front(); while (!p_range.empty() && !p_pred(front())) p_range.pop_front();
} }
public: public:
FilterRange(): __range(), __pred() {} FilterRange(): p_range(), p_pred() {}
template<typename _P> template<typename _P>
FilterRange(const _T &__range, const _P &__pred): __range(__range), FilterRange(const _T &range, const _P &pred): p_range(range),
__pred(__pred) { p_pred(pred) {
advance_valid(); advance_valid();
} }
FilterRange(const FilterRange &__it): __range(__it.__range), FilterRange(const FilterRange &it): p_range(it.p_range),
__pred(__it.__pred) { p_pred(it.p_pred) {
advance_valid(); advance_valid();
} }
FilterRange(FilterRange &&__it): __range(move(__it.__range)), FilterRange(FilterRange &&it): p_range(move(it.p_range)),
__pred(move(__it.__pred)) { p_pred(move(it.p_pred)) {
advance_valid(); advance_valid();
} }
FilterRange &operator=(const FilterRange &__v) { FilterRange &operator=(const FilterRange &v) {
__range = __v.__range; p_range = v.p_range;
__pred = __v.__pred; p_pred = v.p_pred;
advance_valid(); advance_valid();
return *this; return *this;
} }
FilterRange &operator=(FilterRange &&__v) { FilterRange &operator=(FilterRange &&v) {
__range = move(__v.__range); p_range = move(v.p_range);
__pred = move(__v.__pred); p_pred = move(v.p_pred);
advance_valid(); advance_valid();
return *this; return *this;
} }
bool empty() const { return __range.empty(); } bool empty() const { return p_range.empty(); }
bool equals_front(const FilterRange &__r) const { bool equals_front(const FilterRange &r) const {
return __range.equals_front(__r.__range); return p_range.equals_front(r.p_range);
} }
bool pop_front() { bool pop_front() {
bool __ret = __range.pop_front(); bool ret = p_range.pop_front();
advance_valid(); advance_valid();
return __ret; return ret;
} }
bool push_front() { bool push_front() {
_T __tmp = __range; _T tmp = p_range;
if (!__tmp.push_front()) return false; if (!tmp.push_front()) return false;
while (!pred(__tmp.front())) while (!p_pred(tmp.front()))
if (!__tmp.push_front()) if (!tmp.push_front())
return false; return false;
__range = __tmp; p_range = tmp;
return true; return true;
} }
octa::RangeReference<_T> front() const { return __range.front(); } octa::RangeReference<_T> front() const { return p_range.front(); }
}; };
template<typename _R, typename _P> template<typename _R, typename _P>
FilterRange<_R> filter(_R __range, _P __pred) { FilterRange<_R> filter(_R range, _P pred) {
return octa::FilterRange<_R>(__range, __pred); return octa::FilterRange<_R>(range, pred);
}
} }
} /* namespace octa */
#endif #endif