diff options
author | Chris Robinson <[email protected]> | 2023-12-10 12:58:18 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-12-10 12:58:18 -0800 |
commit | cf37d92442ccf3c7f4b979bd97282dcbe28ca64a (patch) | |
tree | 3b96251062c9c6ea97aea3190e22ea68e1377e18 /common/almalloc.h | |
parent | 073d79c2047143e70bb199077fe3c8dbafe0a606 (diff) |
Refactor FlexArray
This avoids using an array of 1 as a flexible array member, and instead uses a
span to reference the memory after itself.
Diffstat (limited to 'common/almalloc.h')
-rw-r--r-- | common/almalloc.h | 116 |
1 files changed, 0 insertions, 116 deletions
diff --git a/common/almalloc.h b/common/almalloc.h index 288b5075..8a976aae 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -127,122 +127,6 @@ constexpr T* construct_at(T *ptr, Args&& ...args) noexcept(std::is_nothrow_constructible<T, Args...>::value) { return ::new(static_cast<void*>(ptr)) T{std::forward<Args>(args)...}; } - -/* Storage for flexible array data. This is trivially destructible if type T is - * trivially destructible. - */ -template<typename T, size_t alignment, bool = std::is_trivially_destructible<T>::value> -struct FlexArrayStorage { - const size_t mSize; - union { - char mDummy; - alignas(alignment) T mArray[1]; - }; - - static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept - { - const size_t len{sizeof(T)*count}; - return std::max(offsetof(FlexArrayStorage,mArray)+len, sizeof(FlexArrayStorage)) + base; - } - - FlexArrayStorage(size_t size) : mSize{size} - { std::uninitialized_default_construct_n(mArray, mSize); } - ~FlexArrayStorage() = default; - - FlexArrayStorage(const FlexArrayStorage&) = delete; - FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; -}; - -template<typename T, size_t alignment> -struct FlexArrayStorage<T,alignment,false> { - const size_t mSize; - union { - char mDummy; - alignas(alignment) T mArray[1]; - }; - - static constexpr size_t Sizeof(size_t count, size_t base) noexcept - { - const size_t len{sizeof(T)*count}; - return std::max(offsetof(FlexArrayStorage,mArray)+len, sizeof(FlexArrayStorage)) + base; - } - - FlexArrayStorage(size_t size) : mSize{size} - { std::uninitialized_default_construct_n(mArray, mSize); } - ~FlexArrayStorage() { std::destroy_n(mArray, mSize); } - - FlexArrayStorage(const FlexArrayStorage&) = delete; - FlexArrayStorage& operator=(const FlexArrayStorage&) = delete; -}; - -/* A flexible array type. Used either standalone or at the end of a parent - * struct, with placement new, to have a run-time-sized array that's embedded - * with its size. - */ -template<typename T, size_t alignment=alignof(T)> -struct FlexArray { - using element_type = T; - using value_type = std::remove_cv_t<T>; - using index_type = size_t; - using difference_type = ptrdiff_t; - - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; - - using iterator = pointer; - using const_iterator = const_pointer; - using reverse_iterator = std::reverse_iterator<iterator>; - using const_reverse_iterator = std::reverse_iterator<const_iterator>; - - using Storage_t_ = FlexArrayStorage<element_type,alignment>; - - Storage_t_ mStore; - - static constexpr index_type Sizeof(index_type count, index_type base=0u) noexcept - { return Storage_t_::Sizeof(count, base); } - static std::unique_ptr<FlexArray> Create(index_type count) - { - void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))}; - return std::unique_ptr<FlexArray>{al::construct_at(static_cast<FlexArray*>(ptr), count)}; - } - - FlexArray(index_type size) : mStore{size} { } - ~FlexArray() = default; - - [[nodiscard]] auto size() const noexcept -> index_type { return mStore.mSize; } - [[nodiscard]] auto empty() const noexcept -> bool { return mStore.mSize == 0; } - - [[nodiscard]] auto data() noexcept -> pointer { return mStore.mArray; } - [[nodiscard]] auto data() const noexcept -> const_pointer { return mStore.mArray; } - - [[nodiscard]] auto operator[](index_type i) noexcept -> reference { return mStore.mArray[i]; } - [[nodiscard]] auto operator[](index_type i) const noexcept -> const_reference { return mStore.mArray[i]; } - - [[nodiscard]] auto front() noexcept -> reference { return mStore.mArray[0]; } - [[nodiscard]] auto front() const noexcept -> const_reference { return mStore.mArray[0]; } - - [[nodiscard]] auto back() noexcept -> reference { return mStore.mArray[mStore.mSize-1]; } - [[nodiscard]] auto back() const noexcept -> const_reference { return mStore.mArray[mStore.mSize-1]; } - - [[nodiscard]] auto begin() noexcept -> iterator { return mStore.mArray; } - [[nodiscard]] auto begin() const noexcept -> const_iterator { return mStore.mArray; } - [[nodiscard]] auto cbegin() const noexcept -> const_iterator { return mStore.mArray; } - [[nodiscard]] auto end() noexcept -> iterator { return mStore.mArray + mStore.mSize; } - [[nodiscard]] auto end() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; } - [[nodiscard]] auto cend() const noexcept -> const_iterator { return mStore.mArray + mStore.mSize; } - - [[nodiscard]] auto rbegin() noexcept -> reverse_iterator { return end(); } - [[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator { return end(); } - [[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator { return cend(); } - [[nodiscard]] auto rend() noexcept -> reverse_iterator { return begin(); } - [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return begin(); } - [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return cbegin(); } - - DEF_PLACE_NEWDEL() -}; - } // namespace al #endif /* AL_MALLOC_H */ |