remove the range half stuff for now

master
Daniel Kolesa 2017-03-31 03:04:32 +02:00
parent 9d08f4361d
commit 6ddb0f1b17
2 changed files with 1 additions and 318 deletions

View File

@ -132,7 +132,7 @@ From forward ranges onwards, independence of state is guaranteed though.
This method checks whether the range has any elements left in it. If this
returns true, it means `front()` is safe to use. Safe code should always
check; the behavior is an item is retrieved on an empty range.
check; the behavior is undefined if an item is retrieved on an empty range.
~~~{.cc}
bool equals_front() const;

View File

@ -250,227 +250,6 @@ namespace detail {
};
}
// range half
template<typename T>
struct half_range;
namespace detail {
template<typename R, bool = is_bidirectional_range<typename R::range>>
struct range_add;
template<typename R>
struct range_add<R, true> {
using diff_t = range_difference_t<typename R::range>;
static diff_t add_n(R &half, diff_t n) {
if (n < 0) {
return -half.prev_n(n);
}
return half.next_n(n);
}
static diff_t sub_n(R &half, diff_t n) {
if (n < 0) {
return -half.next_n(n);
}
return half.prev_n(n);
}
};
template<typename R>
struct range_add<R, false> {
using diff_t = range_difference_t<typename R::range>;
static diff_t add_n(R &half, diff_t n) {
if (n < 0) {
return 0;
}
return half.next_n(n);
}
static diff_t sub_n(R &half, diff_t n) {
if (n < 0) {
return 0;
}
return half.prev_n(n);
}
};
}
namespace detail {
template<typename>
struct range_iterator_tag {
/* better range types all become random access iterators */
using type = std::random_access_iterator_tag;
};
template<>
struct range_iterator_tag<input_range_tag> {
using type = std::input_iterator_tag;
};
template<>
struct range_iterator_tag<output_range_tag> {
using type = std::output_iterator_tag;
};
template<>
struct range_iterator_tag<forward_range_tag> {
using type = std::forward_iterator_tag;
};
template<>
struct range_iterator_tag<bidirectional_range_tag> {
using type = std::bidirectional_iterator_tag;
};
}
template<typename T>
struct range_half {
private:
T p_range;
public:
using range = T;
using iterator_category = typename detail::range_iterator_tag<T>::type;
using value_type = range_value_t<T>;
using difference_type = range_difference_t<T>;
using pointer = range_value_t<T> *;
using reference = range_reference_t<T>;
range_half() = delete;
range_half(T const &range): p_range(range) {}
template<typename U, typename = std::enable_if_t<std::is_convertible_v<U, T>>>
range_half(range_half<U> const &half): p_range(half.p_range) {}
range_half(range_half const &half): p_range(half.p_range) {}
range_half(range_half &&half): p_range(std::move(half.p_range)) {}
range_half &operator=(range_half const &half) {
p_range = half.p_range;
return *this;
}
range_half &operator=(range_half &&half) {
p_range = std::move(half.p_range);
return *this;
}
void next() { p_range.pop_front(); }
void prev() { p_range.push_front(); }
void next_n(range_size_t<T> n) {
p_range.pop_front_n(n);
}
void prev_n(range_size_t<T> n) {
p_range.push_front_n(n);
}
range_difference_t<T> add_n(range_difference_t<T> n) {
return detail::range_add<range_half<T>>::add_n(*this, n);
}
range_difference_t<T> sub_n(range_difference_t<T> n) {
return detail::range_add<range_half<T>>::sub_n(*this, n);
}
range_reference_t<T> get() const {
return p_range.front();
}
range_difference_t<T> distance(range_half const &half) const {
return p_range.distance_front(half.p_range);
}
bool equals(range_half const &half) const {
return p_range.equals_front(half.p_range);
}
bool operator==(range_half const &half) const {
return equals(half);
}
bool operator!=(range_half const &half) const {
return !equals(half);
}
bool operator<(range_half const &half) const {
return distance(half) > 0;
}
bool operator>(range_half const &half) const {
return distance(half) < 0;
}
bool operator<=(range_half const &half) const {
return distance(half) >= 0;
}
bool operator>=(range_half const &half) const {
return distance(half) <= 0;
}
/* iterator like interface */
range_reference_t<T> operator*() const {
return p_range.front();
}
range_reference_t<T> operator[](range_size_t<T> idx) const {
return p_range[idx];
}
range_half &operator++() {
next();
return *this;
}
range_half operator++(int) {
range_half tmp(*this);
next();
return tmp;
}
range_half &operator--() {
prev();
return *this;
}
range_half operator--(int) {
range_half tmp(*this);
prev();
return tmp;
}
range_half operator+(range_difference_t<T> n) const {
range_half tmp(*this);
tmp.add_n(n);
return tmp;
}
range_half operator-(range_difference_t<T> n) const {
range_half tmp(*this);
tmp.sub_n(n);
return tmp;
}
range_half &operator+=(range_difference_t<T> n) {
add_n(n);
return *this;
}
range_half &operator-=(range_difference_t<T> n) {
sub_n(n);
return *this;
}
T iter() const { return p_range; }
half_range<range_half> iter(range_half const &other) const {
return half_range<range_half>(*this, other);
}
range_value_t<T> *data() { return p_range.data(); }
range_value_t<T> const *data() const { return p_range.data(); }
};
template<typename R>
inline range_difference_t<R> operator-(
range_half<R> const &lhs, range_half<R> const &rhs
) {
return rhs.distance(lhs);
}
namespace detail {
template<typename R>
void pop_front_n(R &range, range_size_t<R> n) {
@ -581,10 +360,6 @@ struct input_range {
return zip_range<B, R1, RR...>(iter(), std::move(r1), std::move(rr)...);
}
range_half<B> half() const {
return range_half<B>(iter());
}
/* iterator like interface operating on the front part of the range
* this is sometimes convenient as it can be used within expressions */
@ -851,98 +626,6 @@ namespace detail {
constexpr bool iterable_test = decltype(test_iterable<T>(0))::value;
}
template<typename T>
struct half_range: input_range<half_range<T>> {
using range_category = range_category_t <typename T::range>;
using value_type = range_value_t <typename T::range>;
using reference = range_reference_t <typename T::range>;
using size_type = range_size_t <typename T::range>;
using difference_type = range_difference_t<typename T::range>;
private:
T p_beg;
T p_end;
public:
half_range() = delete;
half_range(half_range const &range):
p_beg(range.p_beg), p_end(range.p_end)
{}
half_range(half_range &&range):
p_beg(std::move(range.p_beg)), p_end(std::move(range.p_end))
{}
half_range(T const &beg, T const &end):
p_beg(beg),p_end(end)
{}
half_range(T &&beg, T &&end):
p_beg(std::move(beg)), p_end(std::move(end))
{}
half_range &operator=(half_range const &range) {
p_beg = range.p_beg;
p_end = range.p_end;
return *this;
}
half_range &operator=(half_range &&range) {
p_beg = std::move(range.p_beg);
p_end = std::move(range.p_end);
return *this;
}
bool empty() const { return p_beg == p_end; }
void pop_front() {
p_beg.next();
}
void push_front() {
p_beg.prev();
}
void pop_back() {
p_end.prev();
}
void push_back() {
p_end.next();
}
reference front() const { return *p_beg; }
reference back() const { return *(p_end - 1); }
bool equals_front(half_range const &range) const {
return p_beg == range.p_beg;
}
bool equals_back(half_range const &range) const {
return p_end == range.p_end;
}
difference_type distance_front(half_range const &range) const {
return range.p_beg - p_beg;
}
difference_type distance_back(half_range const &range) const {
return range.p_end - p_end;
}
size_type size() const { return p_end - p_beg; }
half_range slice(size_type start, size_type end) const {
return half_range{p_beg + start, p_beg + end};
}
reference operator[](size_type idx) const {
return p_beg[idx];
}
void put(value_type const &v) {
p_beg.range().put(v);
}
void put(value_type &&v) {
p_beg.range().put(std::move(v));
}
value_type *data() { return p_beg.data(); }
value_type const *data() const { return p_beg.data(); }
};
template<typename T>
struct reverse_range: input_range<reverse_range<T>> {
using range_category = std::common_type_t<