/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */ #ifndef MPT_BASE_ALIGNED_ARRAY_HPP #define MPT_BASE_ALIGNED_ARRAY_HPP #include "mpt/base/bit.hpp" #include "mpt/base/namespace.hpp" #include #include #include #include #include namespace mpt { inline namespace MPT_INLINE_NS { template struct alignas(static_cast(alignment)) aligned_array : std::array { static_assert(static_cast(alignment) >= alignof(T)); static_assert(((count * sizeof(T)) % static_cast(alignment)) == 0); static_assert(sizeof(std::array) == (sizeof(T) * count)); }; static_assert(sizeof(mpt::aligned_array) == sizeof(std::array)); template T * align_elements(std::array & a) { static_assert(mpt::has_single_bit(alignof(T))); static_assert(mpt::has_single_bit(sizeof(T))); static_assert(mpt::has_single_bit(alignment_elements)); static_assert((expected_elements + alignment_elements - 1) <= N); void * buf = a.data(); std::size_t size = N * sizeof(T); void * result = std::align(alignment_elements * sizeof(T), expected_elements * sizeof(T), buf, size); assert(result); return reinterpret_cast(result); } template T * align_elements(T (&a)[N]) { static_assert(mpt::has_single_bit(alignof(T))); static_assert(mpt::has_single_bit(sizeof(T))); static_assert(mpt::has_single_bit(alignment_elements)); static_assert((expected_elements + alignment_elements - 1) <= N); void * buf = a; std::size_t size = N * sizeof(T); void * result = std::align(alignment_elements * sizeof(T), expected_elements * sizeof(T), buf, size); assert(result); return reinterpret_cast(result); } template T * align_bytes(std::array & a) { static_assert(mpt::has_single_bit(alignof(T))); static_assert(mpt::has_single_bit(sizeof(T))); static_assert(mpt::has_single_bit(alignment_bytes)); static_assert((alignment_bytes % alignof(T)) == 0); static_assert(((expected_elements * sizeof(T)) + alignment_bytes - 1) <= (N * sizeof(T))); void * buf = a.data(); std::size_t size = N * sizeof(T); void * result = std::align(alignment_bytes, expected_elements * sizeof(T), buf, size); assert(result); return reinterpret_cast(result); } template T * align_bytes(T (&a)[N]) { static_assert(mpt::has_single_bit(alignof(T))); static_assert(mpt::has_single_bit(sizeof(T))); static_assert(mpt::has_single_bit(alignment_bytes)); static_assert((alignment_bytes % alignof(T)) == 0); static_assert(((expected_elements * sizeof(T)) + alignment_bytes - 1) <= (N * sizeof(T))); void * buf = a; std::size_t size = N * sizeof(T); void * result = std::align(alignment_bytes, expected_elements * sizeof(T), buf, size); assert(result); return reinterpret_cast(result); } } // namespace MPT_INLINE_NS } // namespace mpt #endif // MPT_BASE_ALIGNED_ARRAY_HPP