29 using reference = std::invoke_result_t<
30 F,
typename std::iterator_traits<std::remove_const_t<Iter>>::value_type>;
31 using difference_type =
32 typename std::iterator_traits<std::remove_const_t<Iter>>::difference_type;
33 using value_type = reference;
34 using iterator_category =
typename std::iterator_traits<
35 std::remove_const_t<Iter>>::iterator_category;
40 if (
this == &other)
return *
this;
46 constexpr reference operator*()
const {
return f(*iter); }
48 constexpr reference operator[](
size_t i)
const {
return f(iter[i]); }
95 return iter == other.iter;
99 return !(iter == other.iter);
103 return iter < other.iter;
107 return iter - other.iter;
205 struct StridedRangeIter {
212 typename std::iterator_traits<std::remove_const_t<Iter>>::pointer;
214 typename std::iterator_traits<std::remove_const_t<Iter>>::reference;
215 using difference_type =
typename std::iterator_traits<
216 std::remove_const_t<Iter>>::difference_type;
218 typename std::iterator_traits<std::remove_const_t<Iter>>::value_type;
219 using iterator_category =
typename std::iterator_traits<
220 std::remove_const_t<Iter>>::iterator_category;
222 constexpr StridedRangeIter(Iter iter,
int stride)
223 : iter(iter), stride(stride) {}
225 constexpr reference operator*() {
return *iter; }
227 constexpr std::add_const_t<reference> operator*()
const {
return *iter; }
229 constexpr reference operator[](
size_t i) {
return iter[i * stride]; }
231 constexpr std::add_const_t<reference> operator[](
size_t i)
const {
232 return iter[i * stride];
236 StridedRangeIter& operator++() {
242 StridedRangeIter operator++(
int) {
249 StridedRangeIter& operator--() {
255 StridedRangeIter operator--(
int) {
261 constexpr StridedRangeIter operator+(
size_t n)
const {
262 return StridedRangeIter(iter + n * stride, stride);
265 StridedRangeIter& operator+=(
size_t n) {
270 constexpr StridedRangeIter operator-(
size_t n)
const {
271 return StridedRangeIter(iter - n * stride, stride);
274 StridedRangeIter& operator-=(
size_t n) {
279 constexpr friend bool operator==(StridedRangeIter a, StridedRangeIter b) {
280 return a.iter == b.iter;
283 constexpr friend bool operator!=(StridedRangeIter a, StridedRangeIter b) {
284 return !(a.iter == b.iter);
287 constexpr friend bool operator<(StridedRangeIter a, StridedRangeIter b) {
288 return a.iter < b.iter;
291 constexpr friend difference_type operator-(StridedRangeIter a,
292 StridedRangeIter b) {
294 return (a.iter - b.iter) / a.stride;
301 constexpr StridedRange(Iter start, Iter end,
size_t stride)
302 : _start(start), _end(end), stride(stride) {}
304 constexpr StridedRangeIter begin()
const {
305 return StridedRangeIter(_start, stride);
308 constexpr StridedRangeIter end()
const {
309 return StridedRangeIter(_start, stride) +
310 ((std::distance(_start, _end) + (stride - 1)) / stride);