guaranteed single-argument slice

master
Daniel Kolesa 2017-04-01 16:49:38 +02:00
parent 9fda006d40
commit f2a78ad589
5 changed files with 33 additions and 9 deletions

View File

@ -332,6 +332,7 @@ not the only thing, you can additionally slice them, with this method:
~~~{.cc}
my_range slice(size_type start, size_type end) const;
my_range slice(size_type start) const;
~~~
Making a slice of a range means creating a new range that contains a subset
@ -353,6 +354,16 @@ will return a range that contains everything but the first or the last items,
provided that the range contains at very least 2 items, otherwise the behavior
is undefined.
The second method takes only the `start` argument. In this case, the second
argument is implied to be the `size()` of the range. Therefore, the typical
implementation will be simply
~~~{.cc}
my_range slice(size_type start) const {
return slice(start, size());
}
~~~
The slicing indexes follow a regular half-open interval approach, so there
shouldn't be anything unclear about it.

View File

@ -16,7 +16,7 @@ int main() {
c.put(foldl(half, 0));
};
spawn(f, c, iter(arr).slice(0, arr.size() / 2));
spawn(f, c, iter(arr).slice(arr.size() / 2, arr.size()));
spawn(f, c, iter(arr).slice(arr.size() / 2));
int a = c.get();
int b = c.get();

View File

@ -69,9 +69,9 @@ namespace detail {
range_size_t<R> rlen = range.size();
for (range_size_t<R> i = 1; i < rlen; ++i) {
range_size_t<R> j = i;
range_value_t<R> v(std::move(range[i]));
range_value_t<R> v{std::move(range[i])};
while (j > 0 && !compare(range[j - 1], v)) {
range[j] = range[j - 1];
range[j] = std::move(range[j - 1]);
--j;
}
range[j] = std::move(v);
@ -143,9 +143,7 @@ namespace detail {
}
swap(range[pi], range.back());
detail::introloop(range.slice(0, pi), compare, depth - 1);
detail::introloop(
range.slice(pi + 1, range.size()), compare, depth - 1
);
detail::introloop(range.slice(pi + 1), compare, depth - 1);
}
template<typename R, typename C>
@ -746,7 +744,7 @@ public:
}
bool empty() const { return p_range.empty(); }
range_size_t<T> size() const { return p_range.size(); }
size_type size() const { return p_range.size(); }
void pop_front() { p_range.pop_front(); }
void pop_back() { p_range.pop_back(); }
@ -754,13 +752,16 @@ public:
R front() const { return p_func(p_range.front()); }
R back() const { return p_func(p_range.back()); }
R operator[](range_size_t<T> idx) const {
R operator[](size_type idx) const {
return p_func(p_range[idx]);
}
map_range slice(range_size_t<T> start, range_size_t<T> end) {
map_range slice(size_type start, size_type end) const {
return map_range(p_range.slice(start, end), p_func);
}
map_range slice(size_type start) const {
return slice(start, size());
}
};
namespace detail {

View File

@ -628,6 +628,9 @@ public:
size_type len = p_range.size();
return reverse_range{p_range.slice(len - end, len - start)};
}
reverse_range slice(size_type start) const {
return slice(start, size());
}
};
template<typename T>
@ -680,6 +683,9 @@ public:
move_range slice(size_type start, size_type end) const {
return move_range{p_range.slice(start, end)};
}
move_range slice(size_type start) const {
return slice(start, size());
}
void put(value_type const &v) { p_range.put(v); }
void put(value_type &&v) { p_range.put(std::move(v)); }
@ -1180,6 +1186,9 @@ struct iterator_range: input_range<iterator_range<T>> {
iterator_range slice(size_type start, size_type end) const {
return iterator_range(p_beg + start, p_beg + end);
}
iterator_range slice(size_type start) const {
return slice(start, size());
}
reference operator[](size_type i) const { return p_beg[i]; }

View File

@ -100,6 +100,9 @@ public:
basic_char_range slice(size_t start, size_t end) const {
return basic_char_range(p_beg + start, p_beg + end);
}
basic_char_range slice(size_t start) const {
return slice(start, size());
}
T &operator[](size_t i) const { return p_beg[i]; }