mirror of
https://github.com/drewcassidy/quicktex.git
synced 2024-09-13 06:37:34 +00:00
Add subrange template
This commit is contained in:
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;
|
||||
}
|
||||
|
||||
|
97
quicktex/util/subrange.h
Normal file
97
quicktex/util/subrange.h
Normal file
@ -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…
Reference in New Issue
Block a user