Add subrange template

feature/simd
Andrew Cassidy 2 years ago
parent db24af730e
commit 9b3c1d0ca3

@ -35,10 +35,10 @@ namespace quicktex {
// std::ranges::range is not usable by default in libc++ 13
template <class T>
concept range = std::is_constructible_v<T> && requires(T &t) {
t.begin();
t.end();
};
concept range = requires(T &t) {
t.begin();
t.end();
};
template <class T>
concept sized = requires(T &t) { std::size(t); };
@ -83,22 +83,6 @@ size_t distance(T range) {
return std::distance(range.begin(), range.end());
}
template <class II>
requires std::input_or_output_iterator<II>
class view {
public:
view() : _begin(), _end() {}
view(II begin, II end) : _begin(begin), _end(end) {}
inline size_t size() { return distance(_begin, _end); }
inline II begin() { return _begin; }
inline II end() { return _end; }
private:
II _begin;
II _end;
};
template <typename D> class index_iterator_base {
public:
typedef long long difference_type;
@ -113,12 +97,12 @@ template <typename D> class index_iterator_base {
return old;
}
D &operator--() {
_index++;
_index--;
return static_cast<D &>(*this);
}
D operator--(int) {
D old = static_cast<D &>(*this);
_index++;
_index--;
return old;
}

@ -0,0 +1,97 @@
/* Quicktex Texture Compression Library
Copyright (C) 2021 Andrew Cassidy <drewcassidy@me.com>
Partially derived from rgbcx.h written by Richard Geldreich <richgel99@gmail.com>
and licenced under the public domain
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <concepts>
#include <iterator>
#include "util/ranges.h"
namespace quicktex {
template <std::input_or_output_iterator I, std::sentinel_for<I> S = I> struct subrange {
public:
using iterator_type = I;
using sentinel_type = S;
using value_type = std::iter_value_t<I>;
using reference_type = std::iter_reference_t<I>;
using difference_type = std::iter_difference_t<I>;
constexpr subrange(const I& b, const S& e) : _begin(b), _end(e) {}
constexpr I begin() const { return _begin; }
constexpr S end() const { return _end; }
constexpr bool empty() const { return _begin == _end; }
constexpr difference_type size() const { return std::distance(_end, _begin); }
explicit constexpr operator bool() const { return !empty(); }
constexpr subrange& advance(difference_type n) {
assert(n >= 0 || std::bidirectional_iterator<I>); // forward iterators cannot be decremented
if (n > 0) {
for (int i = 0; i < n && _begin != _end; i++) { _begin++; }
} else {
for (int i = 0; i > n && _begin != _end; i--) { _begin--; }
}
return *this;
}
constexpr subrange next(difference_type n = 1) const {
auto tmp = *this;
return tmp.advance(n);
}
template <typename _ = I>
requires std::bidirectional_iterator<I>
constexpr subrange prev(difference_type n = 1) const {
return next(-n);
}
template <typename _ = I>
requires std::random_access_iterator<I>
constexpr reference_type operator[](difference_type i) {
assert(i >= 0 && i < size());
return _begin[i];
}
template <typename _ = I>
requires std::random_access_iterator<I>
constexpr const reference_type operator[](difference_type i) const {
assert(i >= 0 && i < size());
return _begin[i];
}
template <typename _ = I>
requires std::contiguous_iterator<I>
constexpr value_type* data() {
return std::to_address(_begin);
}
template <typename _ = I>
requires std::contiguous_iterator<I>
constexpr value_type const* data() const {
return std::to_address(_begin);
}
private:
I _begin;
S _end;
};
} // namespace quicktex
Loading…
Cancel
Save