Span does runtime checks of bounds (if exist) now
This commit is contained in:
@ -6,59 +6,73 @@
|
|||||||
|
|
||||||
namespace Container {
|
namespace Container {
|
||||||
|
|
||||||
// 0 is unchecked
|
/**
|
||||||
template<typename T, std::size_t N = 0>
|
* This class implements a readonly view on a memory region of uniform type.
|
||||||
class Span {
|
* The Span can be initialized wihout size checking by supplying 0 as size
|
||||||
public:
|
* and using the one-argument constructor. Then iterators become invalid.
|
||||||
using iterator = ContinuousIterator<T>;
|
*
|
||||||
|
* @tparam T The type of the objects located in the memory region
|
||||||
|
* @tparam N The size of the memory region
|
||||||
|
*/
|
||||||
|
template<typename T, std::size_t N = 0>
|
||||||
|
class Span {
|
||||||
|
public:
|
||||||
|
using iterator = ContinuousIterator<T>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* const ptr;
|
T *const ptr;
|
||||||
const std::size_t sz = N;
|
const std::size_t sz = N;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Span() = default;
|
Span() = delete;
|
||||||
|
|
||||||
Span(T* first) : ptr(first) {}
|
explicit Span(T *first) : ptr(first) {}
|
||||||
|
|
||||||
Span(T* first, T* last) : ptr(first), sz(last - first) {}
|
Span(T *first, T *last) : ptr(first), sz(last - first) {}
|
||||||
|
|
||||||
iterator begin() { return iterator(ptr); }
|
// TODO: Rest of constructors
|
||||||
iterator begin() const { return iterator(ptr); }
|
|
||||||
// If size is unchecked end() is equal to begin()
|
|
||||||
iterator end() { return iterator(&ptr[N]); }
|
|
||||||
iterator end() const { return iterator(&ptr[N]); }
|
|
||||||
|
|
||||||
T* operator[](std::size_t i) {
|
iterator begin() { return iterator(ptr); }
|
||||||
if constexpr (N != 0) {
|
|
||||||
if (i < 0 || i >= N) { return nullptr; }
|
iterator begin() const { return iterator(ptr); }
|
||||||
}
|
|
||||||
return &ptr[i];
|
// If size is unchecked end() is equal to begin()
|
||||||
|
iterator end() { return iterator(&ptr[sz]); }
|
||||||
|
|
||||||
|
// If size is unchecked end() is equal to begin()
|
||||||
|
iterator end() const { return iterator(&ptr[sz]); }
|
||||||
|
|
||||||
|
T *operator[](std::size_t i) {
|
||||||
|
if (sz != 0) {
|
||||||
|
if (i >= sz) { return nullptr; }
|
||||||
}
|
}
|
||||||
|
return &ptr[i];
|
||||||
|
}
|
||||||
|
|
||||||
T* operator[](std::size_t i) const {
|
T *operator[](std::size_t i) const {
|
||||||
if constexpr (N != 0) {
|
if (sz != 0) {
|
||||||
if (i < 0 || i >= N) { return nullptr; }
|
if (i >= sz) { return nullptr; }
|
||||||
}
|
|
||||||
return &ptr[i];
|
|
||||||
}
|
}
|
||||||
|
return &ptr[i];
|
||||||
|
}
|
||||||
|
|
||||||
T* data() { return ptr; }
|
T *data() { return ptr; }
|
||||||
const T* data() const { return ptr; }
|
|
||||||
|
|
||||||
explicit operator T*() {
|
const T *data() const { return ptr; }
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// First is inclusive, last exclusive [first, last)
|
explicit operator T *() {
|
||||||
Span& subspan(std::size_t first, std::size_t last = N) {
|
return ptr;
|
||||||
return Span(ptr + first, ptr + last - 1);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const {
|
// First is inclusive, last exclusive [first, last)
|
||||||
return sz;
|
Span &subspan(std::size_t first, std::size_t last) {
|
||||||
}
|
return Span(ptr + first, ptr + last - 1);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::size_t size() const {
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace bse
|
} // namespace bse
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user