diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-17 00:21:48 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-17 22:29:50 +0100 |
commit | a141c401f78467bc15f62882fca5d55a007cacbb (patch) | |
tree | 908ac71a8640f78f45d22c6808c5fa6e373000fa /asl/span.hpp | |
parent | cb77cbe9ce4cddad6a460aa190ff70f0c13e4703 (diff) |
Reorganize everything
Diffstat (limited to 'asl/span.hpp')
-rw-r--r-- | asl/span.hpp | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/asl/span.hpp b/asl/span.hpp deleted file mode 100644 index 9ebe022..0000000 --- a/asl/span.hpp +++ /dev/null @@ -1,235 +0,0 @@ -#pragma once - -#include "asl/meta.hpp" -#include "asl/annotations.hpp" -#include "asl/layout.hpp" -#include "asl/assert.hpp" - -namespace asl -{ - -static constexpr isize_t dynamic_size = -1; - -template<typename T> -class contiguous_iterator -{ - T* m_ptr; - -public: - constexpr explicit contiguous_iterator(T* ptr) : m_ptr{ptr} {} - - constexpr bool operator==(const contiguous_iterator& other) const - { - return other.m_ptr == m_ptr; - } - - constexpr contiguous_iterator& operator++() - { - m_ptr += 1; - return *this; - } - - constexpr contiguous_iterator operator++(int) - { - return contiguous_iterator{ exchange(m_ptr, m_ptr + 1) }; - } - - constexpr T& operator*() const { return *m_ptr; } - - constexpr T* operator->() const { return m_ptr; } -}; - -template<typename T> -contiguous_iterator(T) -> contiguous_iterator<T>; - -template<is_object T, isize_t kSize = dynamic_size> -class span -{ - static constexpr bool is_dynamic(isize_t size) - { - return size < 0; - } - - static constexpr bool kIsDynamic = is_dynamic(kSize); - - using SizeType = select_t<kIsDynamic, isize_t, empty>; - - T* m_data{}; - ASL_NO_UNIQUE_ADDRESS SizeType m_size{}; - -public: - constexpr span() requires (kIsDynamic || kSize == 0) = default; - - constexpr span(T* data, isize_t size) - requires kIsDynamic - : m_data{data} - , m_size{size} - {} - - constexpr explicit span(T* data, isize_t size) - requires (!kIsDynamic) - : m_data{data} - { - ASL_ASSERT(size == kSize); - } - - template<isize_t N> - constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions) - requires (kIsDynamic) - : m_data{array} - , m_size{N} - {} - - template<isize_t N> - constexpr span(T (&array)[N]) // NOLINT(*-explicit-conversions) - requires (!kIsDynamic) && (N == kSize) - : m_data{array} - {} - - template<is_object U, isize_t kOtherSize> - constexpr explicit(!kIsDynamic) - span(const span<U, kOtherSize>& other) // NOLINT(*-explicit-conversions) - requires ( - ( - kIsDynamic || - is_dynamic(kOtherSize) || - kOtherSize == kSize - ) && convertible_from<T(&)[], U(&)[]> - ) - : span{static_cast<U*>(other.data()), other.size()} - { - } - - constexpr span(const span&) = default; - constexpr span(span&&) = default; - - constexpr span& operator=(const span&) = default; - constexpr span& operator=(span&&) = default; - - ~span() = default; - - constexpr isize_t size() const - { - if constexpr (kIsDynamic) { return m_size; } - else { return kSize; } - } - - constexpr isize_t size_bytes() const { return size() * size_of<T>; } - - constexpr bool is_empty() const { return size() == 0; } - - constexpr T* data() const { return m_data; } - - constexpr contiguous_iterator<T> begin() const - { - return contiguous_iterator{m_data}; - } - - constexpr contiguous_iterator<T> end() const - { - return contiguous_iterator{m_data + size()}; - } - - constexpr T& operator[](isize_t i) const - { - ASL_ASSERT(i >= 0 && i < size()); - return m_data[i]; // NOLINT(*-pointer-arithmetic) - } - - template<isize_t kOffset, isize_t kSubSize = dynamic_size> - constexpr auto subspan() const - requires ( - kOffset >= 0 && - (kIsDynamic || kOffset <= kSize) && - (kIsDynamic || is_dynamic(kSubSize) || kSubSize <= kSize - kOffset) - ) - { - ASL_ASSERT(kOffset <= size()); - - if constexpr (is_dynamic(kSubSize)) - { - if constexpr (kIsDynamic) - { - return span<T>(data() + kOffset, size() - kOffset); - } - else - { - return span<T, kSize - kOffset>(data() + kOffset, size() - kOffset); - } - } - else - { - ASL_ASSERT(kSubSize <= size() - kOffset); - return span<T, kSubSize>(data() + kOffset, kSubSize); - } - } - - constexpr span<T> subspan(isize_t offset) const - { - ASL_ASSERT(offset <= size()); - return span<T>{ data() + offset, size() - offset }; - } - - constexpr span<T> subspan(isize_t offset, isize_t sub_size) const - { - ASL_ASSERT(offset <= size() && !is_dynamic(sub_size)); - ASL_ASSERT(sub_size <= size() - offset); - return span<T>{ data() + offset, sub_size }; - } - - template<isize_t kSubSize> - constexpr auto first() const - requires ( - kSubSize >= 0 && - (kIsDynamic || kSubSize <= kSize) - ) - { - ASL_ASSERT(kSubSize <= size()); - return span<T, kSubSize>{ data(), kSubSize }; - } - - constexpr span<T> first(isize_t sub_size) const - { - ASL_ASSERT(sub_size >= 0 && sub_size <= size()); - return span<T>{ data(), sub_size }; - } - - template<isize_t kSubSize> - constexpr auto last() const - requires ( - kSubSize >= 0 && - (kIsDynamic || kSubSize <= kSize) - ) - { - ASL_ASSERT(kSubSize <= size()); - return span<T, kSubSize>{ data() + size() - kSubSize, kSubSize }; - } - - constexpr span<T> last(isize_t sub_size) const - { - ASL_ASSERT(sub_size >= 0 && sub_size <= size()); - return span<T>{ data() + size() - sub_size, sub_size }; - } -}; - -template<is_object T, isize_t kSize> -inline span<const byte> as_bytes(span<T, kSize> s) -{ - return span<const byte>( - reinterpret_cast<const byte*>(s.data()), - s.size_bytes()); -} - -template<is_object T, isize_t kSize> -inline span<byte> as_mutable_bytes(span<T, kSize> s) - requires (!is_const<T>) -{ - return span<byte>( - reinterpret_cast<byte*>(s.data()), - s.size_bytes()); -} - -template<is_object T, isize_t kSize> -span(T (&)[kSize]) -> span<T, kSize>; - -} // namespace asl |