From ce3f268075bbf7d92e20a04dbb9336b8fb4b60f1 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Mon, 20 Mar 2023 13:28:01 +0200 Subject: [PATCH] BAN: Implement basic Span This is wrapper over contiguous block of memory e.g. Vector --- BAN/include/BAN/Array.h | 4 ++ BAN/include/BAN/Span.h | 112 +++++++++++++++++++++++++++++++++++++++ BAN/include/BAN/Vector.h | 4 ++ 3 files changed, 120 insertions(+) create mode 100644 BAN/include/BAN/Span.h diff --git a/BAN/include/BAN/Array.h b/BAN/include/BAN/Array.h index f19c680f23..95da02343d 100644 --- a/BAN/include/BAN/Array.h +++ b/BAN/include/BAN/Array.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -34,6 +35,9 @@ namespace BAN const T& front() const; T& front(); + Span span() { return Span(m_data, size()); } + const Span span() const { return Span(m_data, size()); } + constexpr size_type size() const; private: diff --git a/BAN/include/BAN/Span.h b/BAN/include/BAN/Span.h new file mode 100644 index 0000000000..d2e7a8632e --- /dev/null +++ b/BAN/include/BAN/Span.h @@ -0,0 +1,112 @@ +#pragma once + +#include +#include + +#include + +namespace BAN +{ + + template + class Span + { + public: + using value_type = T; + using size_type = size_t; + using iterator = IteratorSimple; + using const_iterator = ConstIteratorSimple; + + public: + Span() = default; + Span(T*, size_type); + + iterator begin() { return iterator(m_data); } + iterator end() { return iterator(m_data + m_size); } + const_iterator begin() const { return const_iterator(m_data); } + const_iterator end() const { return const_iterator(m_data + m_size); } + + T& operator[](size_type); + const T& operator[](size_type) const; + + T* data(); + const T* data() const; + + bool empty() const; + size_type size() const; + + void clear(); + + Span slice(size_type, size_type = ~size_type(0)); + + private: + T* m_data = nullptr; + size_type m_size = 0; + }; + + template + Span::Span(T* data, size_type size) + : m_data(data) + , m_size(size) + { + } + + template + T& Span::operator[](size_type index) + { + ASSERT(m_data); + ASSERT(index < m_size); + return m_data[index]; + } + + template + const T& Span::operator[](size_type index) const + { + ASSERT(m_data); + ASSERT(index < m_size); + return m_data[index]; + } + + template + T* Span::data() + { + return m_data; + } + + template + const T* Span::data() const + { + return m_data; + } + + template + bool Span::empty() const + { + return m_size == 0; + } + + template + typename Span::size_type Span::size() const + { + return m_size; + } + + template + void Span::clear() + { + m_data = nullptr; + m_size = 0; + } + + template + Span Span::slice(size_type start, size_type length) + { + ASSERT(m_data); + ASSERT(start <= m_size); + if (length == ~size_type(0)) + length = m_size - start; + ASSERT(start + length <= m_size); + return Span(m_data + start, m_size - start - length); + } + +} \ No newline at end of file diff --git a/BAN/include/BAN/Vector.h b/BAN/include/BAN/Vector.h index 3cf9868530..2e2e6db006 100644 --- a/BAN/include/BAN/Vector.h +++ b/BAN/include/BAN/Vector.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace BAN { @@ -52,6 +53,9 @@ namespace BAN bool contains(const T&) const; + Span span() { return Span(m_data, m_size); } + const Span span() const { return Span(m_data, m_size); } + const T& operator[](size_type) const; T& operator[](size_type);