diff --git a/octa/algorithm.h b/octa/algorithm.h index 9088190..7f9fe2b 100644 --- a/octa/algorithm.h +++ b/octa/algorithm.h @@ -554,15 +554,6 @@ public: advance_valid(); return ret; } - bool push_front() { - T tmp = p_range; - if (!tmp.push_front()) return false; - while (!p_pred(tmp.front())) - if (!tmp.push_front()) - return false; - p_range = tmp; - return true; - } octa::RangeReference front() const { return p_range.front(); } }; diff --git a/octa/range.h b/octa/range.h index c070521..0a8813a 100644 --- a/octa/range.h +++ b/octa/range.h @@ -143,6 +143,39 @@ namespace detail { template struct HalfRange; +namespace detail { + template::value> + struct RangeAdd; + + template + struct RangeAdd { + using Diff = RangeDifference; + + static Diff add_n(R &half, Diff n) { + if (n < 0) return -half.prev_n(n); + return half.next_n(n); + } + static Diff sub_n(R &half, Diff n) { + if (n < 0) return -half.next_n(n); + return half.prev_n(n); + } + }; + + template + struct RangeAdd { + using Diff = RangeDifference; + + static Diff add_n(R &half, Diff n) { + if (n < 0) return 0; + return half.next_n(n); + } + static Diff sub_n(R &half, Diff n) { + if (n < 0) return 0; + return half.prev_n(n); + } + }; +} + template struct RangeHalf { private: @@ -177,6 +210,13 @@ public: return p_range.push_front_n(n); } + RangeDifference add_n(RangeDifference n) { + return octa::detail::RangeAdd>::add_n(*this, n); + } + RangeDifference sub_n(RangeDifference n) { + return octa::detail::RangeAdd>::sub_n(*this, n); + } + RangeReference get() const { return p_range.front(); } @@ -228,25 +268,21 @@ public: RangeHalf operator+(RangeDifference n) { RangeHalf tmp(*this); - if (n < 0) tmp.prev_n(-n); - else tmp.next_n(n); + tmp.add_n(n); return octa::move(tmp); } RangeHalf operator-(RangeDifference n) { RangeHalf tmp(*this); - if (n < 0) tmp.next_n(-n); - else tmp.prev_n(n); + tmp.sub_n(n); return octa::move(tmp); } RangeHalf &operator+=(RangeDifference n) { - if (n < 0) prev_n(-n); - else next_n(n); + add_n(n); return *this; } RangeHalf &operator-=(RangeDifference n) { - if (n < 0) next_n(-n); - else prev_n(n); + sub_n(n); return *this; } @@ -623,7 +659,6 @@ struct NumberRange: InputRange, ForwardRangeTag, T, T> { } bool pop_front() { p_a += p_step; return true; } - bool push_front() { p_a -= p_step; return true; } T front() const { return p_a; } private: @@ -873,13 +908,6 @@ public: } return false; } - bool push_front() { - if (p_range.push_front()) { - ++p_remaining; - return true; - } - return false; - } RangeSize pop_front_n(RangeSize n) { RangeSize ret = p_range.pop_front_n(n); @@ -941,27 +969,9 @@ public: } bool pop_front() { return p_range.pop_front_n(p_chunksize) > 0; } - bool push_front() { - T tmp = p_range; - RangeSize an = tmp.push_front_n(p_chunksize); - if (an != p_chunksize) return false; - p_range = tmp; - return true; - } RangeSize pop_front_n(RangeSize n) { return p_range.pop_front_n(p_chunksize * n) / p_chunksize; } - RangeSize push_front_n(RangeSize n) { - T tmp = p_range; - RangeSize an = tmp.push_front_n(p_chunksize * n); - RangeSize pn = an / p_chunksize; - if (!pn) return 0; - if (pn == n) { - p_range = tmp; - return pn; - } - return p_range.push_front_n(p_chunksize * an) / p_chunksize; - } TakeRange front() const { return take(p_range, p_chunksize); } };