-
Notifications
You must be signed in to change notification settings - Fork 58
Ranges: Stories sketch
This is what I see for stories we'd need to do. The list is incomplete and we will see how are we with updating it.
@jfalcou says there is already a good way to do it in which case this is a noop.
Has just one pointer (ptr) to T or const T inside.
Supports eve::load[ignore](eve::iterator<T, N>)
-> eve::load[ignore](ptr, N{});
eve::store[ignore]
operators: + - <=>
has a static constexpr N cardinality;
Has one aligned_ptr<T, N>
member.
Can be converted to iterator
at the same position via
eve::remove_alignment
that should be customisable outside of eve
namespace.
Is comparable against iterator
.
You can do pointer arithmetic between iterator
and aligned_iterator
.
Should allow customisation.
cardinality_cast<N>(eve::iterator<T, M>) -> eve::iterator<T, N>
cardinality_cast<M>(eve::aligned_iterator<T, N>) requires(M::value <= N::value) -> eve::aligned_iterator<T, M>
Not sure if we need M::value > N::value
or what should it do. We should probably skip it at the moment.
Basically a typedef for return type of load, or a parameter of store. Maybe needs to be exposed for iterators via some machinery, since you can't reflect it for store easily.
bring kumi tuple into the project https://github.com/jfalcou/ofw
We need a decent tuple implementation
This is kind of putting some of the things together. No aligning, no zips. No constraints on templates. Put whatever instead of traits.
We need:
-
Some version of for_each iteration pattern. I should write down how I see design for those. Sketch: https://github.com/DenisYaroshevskiy/unsq_eve/blob/977794c06f504ee03c027e9415f4a451b2ceb5d9/src/unsq_eve/iterations/for_each.h#L84 Actual one that is tested, but this one aligns things and doesn't follow the design I want: https://github.com/DenisYaroshevskiy/unsq_eve/blob/977794c06f504ee03c027e9415f4a451b2ceb5d9/src/unsq_eve/iteration_guarded.h#L92
-
A
eve::ranges::make_range
function. Just pointers toeve::iterator
, nothing fancy. -
Putting them together.
This is the version I had for my talk: https://github.com/DenisYaroshevskiy/unsq_eve/blob/977794c06f504ee03c027e9415f4a451b2ceb5d9/src/unsq_eve/all_any_none.h#L94
This would be my sketch:
namespace eve::ranges {
namespace detail {
// steps return true if the iteration should break
template <typename Traits, typename P>
struct any_of_impl {
Traits traits;
P p;
template <typename I, eve::relative_conditional_expression C>
bool small_step(I it, C c)
{
auto loaded = eve::load[c](it);
return eve::any[ignore](p(loaded));
}
template <typename I>
bool big_step(I it) {
eve::logical<decltype(eve::load(it)> res = false;
// This is not an ideal way to aggregate any across the array.
// However @jfalcou thinks it's important to allow for arbitrary unrolls
// (and not just powers of 2)
// So we cannot just reuse the `any(wide<aggregated>)` logic.
for (int i = 0; i != Traits::unrolling(); ++i) {
res = res || p(eve::load(it));
it += I::cardinality();
}
return eve::any(res);
}
};
} // namespace detail
template <typename I, typename S, typename P>
bool any_of(I _f, S _l, P p) {
// We'd need this empty check in the future
// because otherwise doing &*std::vector<int>::iterator is not legal.
if (_f == _l) return false;
auto [f, l] = make_range(_f, _l);
detail::any_impl impl{any_traits, p};
return iteration::for_each(f, l, impl).action == Action::Break;
}
} // namespace eve::ranges