diff --git a/src/common/align.h b/src/common/align.h index 4414b4247..9585f07d9 100644 --- a/src/common/align.h +++ b/src/common/align.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) #pragma once @@ -6,6 +6,8 @@ #include "types.h" #include +#include +#include #ifdef _MSC_VER #include @@ -109,4 +111,46 @@ ALWAYS_INLINE static void AlignedFree(void* ptr) #endif } +namespace detail { +template +struct unique_aligned_ptr_deleter +{ + ALWAYS_INLINE void operator()(T* ptr) { Common::AlignedFree(ptr); } +}; + +template +constexpr bool is_unbounded_array_v = false; +template +constexpr bool is_unbounded_array_v = true; + +template +constexpr bool is_bounded_array_v = false; +template +constexpr bool is_bounded_array_v = true; +} // namespace detail + +template +using unique_aligned_ptr = std::unique_ptr>>; + +template + requires(std::is_unbounded_array_v, std::is_trivially_default_constructible_v>, + std::is_trivially_destructible_v>) +unique_aligned_ptr make_unique_aligned(size_t alignment, size_t n) +{ + unique_aligned_ptr ptr( + static_cast*>(AlignedMalloc(sizeof(std::remove_extent_t) * n, alignment))); + if (ptr) + new (ptr.get()) std::remove_extent_t[ n ](); + return ptr; +} + +template + requires(std::is_unbounded_array_v, std::is_trivially_default_constructible_v>, + std::is_trivially_destructible_v>) +unique_aligned_ptr make_unique_aligned_for_overwrite(size_t alignment, size_t n) +{ + return unique_aligned_ptr( + static_cast*>(AlignedMalloc(sizeof(std::remove_extent_t) * n, alignment))); +} + } // namespace Common