#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); Span(Span&); template requires(is_same_v) Span(const Span&); 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)); Span as_const() const { return Span(m_data, m_size); } 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 Span::Span(Span& other) : m_data(other.data()) , m_size(other.size()) { } template template requires(is_same_v) Span::Span(const Span& other) : m_data(other.data()) , m_size(other.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(m_size - start >= length); return Span(m_data + start, length); } }