turn make_move_range into .movable() on any range, and make_half_range(h1, h2) into h1.each(h2)

This commit is contained in:
q66 2015-06-10 00:12:52 +01:00
parent 6b2a7fb43c
commit f9adf08ef9

View file

@ -141,6 +141,8 @@ namespace detail {
// range half
template<typename T> struct HalfRange;
template<typename T>
struct RangeHalf {
private:
@ -247,6 +249,10 @@ public:
else prev_n(n);
return *this;
}
HalfRange<RangeHalf> each(const RangeHalf &other) const {
return HalfRange<RangeHalf>(*this, other);
}
};
template<typename R>
@ -285,6 +291,7 @@ namespace detail {
}
template<typename> struct ReverseRange;
template<typename> struct MoveRange;
template<typename B, typename C, typename V, typename R = V &,
typename S = octa::Size, typename D = octa::Ptrdiff
@ -327,7 +334,11 @@ template<typename B, typename C, typename V, typename R = V &,
}
RangeHalf<B> half() const {
return RangeHalf<B>(*((B *)this));
return RangeHalf<B>(each());
}
MoveRange<B> movable() const {
return MoveRange<B>(each());
}
};
@ -371,6 +382,89 @@ template<typename V, typename R = V &, typename S = octa::Size,
using Reference = R;
};
template<typename T>
struct HalfRange: InputRange<HalfRange<T>,
RangeCategory<T>, RangeValue<T>, RangeReference<T>, RangeSize<T>,
RangeDifference<T>
> {
private:
T p_beg;
T p_end;
public:
HalfRange(): p_beg(), p_end() {}
HalfRange(const HalfRange &range): p_beg(range.p_beg),
p_end(range.p_end) {}
HalfRange(HalfRange &&range): p_beg(octa::move(range.p_beg)),
p_end(octa::move(range.p_end)) {}
HalfRange(const T &beg, const T &end): p_beg(beg),
p_end(end) {}
HalfRange(T &&beg, T &&end): p_beg(octa::move(beg)),
p_end(octa::move(end)) {}
HalfRange &operator=(const HalfRange &range) {
p_beg = range.p_beg;
p_end = range.p_end;
return *this;
}
HalfRange &operator=(HalfRange &&range) {
p_beg = octa::move(range.p_beg);
p_end = octa::move(range.p_end);
return *this;
}
bool empty() const { return p_beg == p_end; }
bool pop_front() {
if (empty()) return false;
return p_beg.next();
}
bool push_front() {
return p_beg.prev();
}
bool pop_back() {
if (empty()) return false;
return p_end.prev();
}
bool push_back() {
return p_end.next();
}
RangeReference<T> front() const { return *p_beg; }
RangeReference<T> back() const { return *(p_end - 1); }
bool equals_front(const HalfRange &range) const {
return p_beg == range.p_beg;
}
bool equals_back(const HalfRange &range) const {
return p_end == range.p_end;
}
RangeDifference<T> distance_front(const HalfRange &range) const {
return range.p_beg - p_beg;
}
RangeDifference<T> distance_back(const HalfRange &range) const {
return range.p_end - p_end;
}
RangeSize<T> size() const { return p_end - p_beg; }
HalfRange<T> slice(RangeSize<T> start, RangeSize<T> p_end) const {
return HalfRange<T>(p_beg + start, p_beg + p_end);
}
RangeReference<T> operator[](RangeSize<T> idx) const {
return p_beg[idx];
}
void put(const RangeValue<T> &v) {
p_beg.range().put(v);
}
void put(RangeValue<T> &&v) {
p_beg.range().put(octa::move(v));
}
};
template<typename T>
struct ReverseRange: InputRange<ReverseRange<T>,
RangeCategory<T>, RangeValue<T>, RangeReference<T>, RangeSize<T>,
@ -528,11 +622,6 @@ public:
void put(Rval &&v) { p_range.put(octa::move(v)); }
};
template<typename T>
MoveRange<T> make_move_range(const T &it) {
return MoveRange<T>(it);
}
template<typename T>
struct NumberRange: InputRange<NumberRange<T>, ForwardRangeTag, T, T> {
NumberRange(): p_a(0), p_b(0), p_step(0) {}
@ -902,95 +991,6 @@ ChunksRange<T> chunks(const T &it, RangeSize<T> chs) {
// range of
template<typename T> using RangeOf = decltype(octa::each(octa::declval<T>()));
template<typename T>
struct HalfRange: InputRange<HalfRange<T>,
RangeCategory<T>, RangeValue<T>, RangeReference<T>, RangeSize<T>,
RangeDifference<T>
> {
private:
T p_beg;
T p_end;
public:
HalfRange(): p_beg(), p_end() {}
HalfRange(const HalfRange &range): p_beg(range.p_beg),
p_end(range.p_end) {}
HalfRange(HalfRange &&range): p_beg(octa::move(range.p_beg)),
p_end(octa::move(range.p_end)) {}
HalfRange(const T &beg, const T &end): p_beg(beg),
p_end(end) {}
HalfRange(T &&beg, T &&end): p_beg(octa::move(beg)),
p_end(octa::move(end)) {}
HalfRange &operator=(const HalfRange &range) {
p_beg = range.p_beg;
p_end = range.p_end;
return *this;
}
HalfRange &operator=(HalfRange &&range) {
p_beg = octa::move(range.p_beg);
p_end = octa::move(range.p_end);
return *this;
}
bool empty() const { return p_beg == p_end; }
bool pop_front() {
if (empty()) return false;
return p_beg.next();
}
bool push_front() {
return p_beg.prev();
}
bool pop_back() {
if (empty()) return false;
return p_end.prev();
}
bool push_back() {
return p_end.next();
}
RangeReference<T> front() const { return *p_beg; }
RangeReference<T> back() const { return *(p_end - 1); }
bool equals_front(const HalfRange &range) const {
return p_beg == range.p_beg;
}
bool equals_back(const HalfRange &range) const {
return p_end == range.p_end;
}
RangeDifference<T> distance_front(const HalfRange &range) const {
return range.p_beg - p_beg;
}
RangeDifference<T> distance_back(const HalfRange &range) const {
return range.p_end - p_end;
}
RangeSize<T> size() const { return p_end - p_beg; }
HalfRange<T> slice(RangeSize<T> start, RangeSize<T> p_end) const {
return HalfRange<T>(p_beg + start, p_beg + p_end);
}
RangeReference<T> operator[](RangeSize<T> idx) const {
return p_beg[idx];
}
void put(const RangeValue<T> &v) {
p_beg.range().put(v);
}
void put(RangeValue<T> &&v) {
p_beg.range().put(octa::move(v));
}
};
template<typename T>
HalfRange<RangeHalf<T>>
make_half_range(const RangeHalf<T> &a, const RangeHalf<T> &b) {
return HalfRange<RangeHalf<T>>(a, b);
}
} /* namespace octa */
#endif