diff options
author | Chris Robinson <[email protected]> | 2023-12-31 08:00:02 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-12-31 08:00:02 -0800 |
commit | cc8dd1c8ce560ef2f7d163f0c98fd95cb352be69 (patch) | |
tree | 5cf2ff35844f9618ce4578c14da77dbfc65090eb | |
parent | 77a571e42ada313ed11d37a3738214df57d378ef (diff) |
Avoid placement new for FlexArray
-rw-r--r-- | common/flexarray.h | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/common/flexarray.h b/common/flexarray.h index 7975a52a..b2884639 100644 --- a/common/flexarray.h +++ b/common/flexarray.h @@ -1,6 +1,7 @@ #ifndef AL_FLEXARRAY_H #define AL_FLEXARRAY_H +#include <algorithm> #include <cstddef> #include <stdexcept> #include <type_traits> @@ -15,7 +16,7 @@ namespace al { */ template<typename T, size_t alignment, bool = std::is_trivially_destructible<T>::value> struct FlexArrayStorage { - alignas(alignment) const ::al::span<T> mData; + alignas(std::max(alignment, alignof(::al::span<T>))) const ::al::span<T> mData; static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept { return sizeof(FlexArrayStorage) + sizeof(T)*count + base; } @@ -31,7 +32,7 @@ struct FlexArrayStorage { template<typename T, size_t alignment> struct FlexArrayStorage<T,alignment,false> { - alignas(alignment) const ::al::span<T> mData; + alignas(std::max(alignment, alignof(::al::span<T>))) const ::al::span<T> mData; static constexpr size_t Sizeof(size_t count, size_t base=0u) noexcept { return sizeof(FlexArrayStorage) + sizeof(T)*count + base; } @@ -49,7 +50,7 @@ struct FlexArrayStorage<T,alignment,false> { * 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)> +template<typename T, size_t Align=alignof(T)> struct FlexArray { using element_type = T; using value_type = std::remove_cv_t<T>; @@ -66,6 +67,7 @@ struct FlexArray { using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; + static constexpr size_t alignment{std::max(alignof(T), Align)}; using Storage_t_ = FlexArrayStorage<element_type,alignment>; Storage_t_ mStore; @@ -73,19 +75,7 @@ struct FlexArray { 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) - { - if(gsl::owner<void*> ptr{al_calloc(alignof(FlexArray), Sizeof(count))}) - { - try { - return std::unique_ptr<FlexArray>{::new(ptr) FlexArray{count}}; - } - catch(...) { - al_free(ptr); - throw; - } - } - throw std::bad_alloc(); - } + { return std::unique_ptr<FlexArray>{new(FamCount{count}) FlexArray{count}}; } FlexArray(index_type size) noexcept(std::is_nothrow_constructible_v<Storage_t_,index_type>) : mStore{size} @@ -121,7 +111,16 @@ struct FlexArray { [[nodiscard]] auto rend() const noexcept -> const_reverse_iterator { return begin(); } [[nodiscard]] auto crend() const noexcept -> const_reverse_iterator { return cbegin(); } - DEF_PLACE_NEWDEL + gsl::owner<void*> operator new(size_t, FamCount count) + { return ::operator new[](Sizeof(count), std::align_val_t{alignof(FlexArray)}); } + void operator delete(gsl::owner<void*> block, FamCount) noexcept + { ::operator delete[](block, std::align_val_t{alignof(FlexArray)}); } + void operator delete(gsl::owner<void*> block) noexcept + { ::operator delete[](block, std::align_val_t{alignof(FlexArray)}); } + + void *operator new(size_t size) = delete; + void *operator new[](size_t size) = delete; + void operator delete[](void *block) = delete; }; } // namespace al |