File indexing completed on 2025-08-28 08:27:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <cstring>
0021 #include <type_traits>
0022 #include <utility>
0023
0024 #include "arrow/util/launder.h"
0025 #include "arrow/util/macros.h"
0026
0027 namespace arrow {
0028 namespace internal {
0029
0030 template <typename T>
0031 class AlignedStorage {
0032 public:
0033 static constexpr bool can_memcpy = std::is_trivial<T>::value;
0034
0035 constexpr T* get() noexcept {
0036 return arrow::internal::launder(reinterpret_cast<T*>(&data_));
0037 }
0038
0039 constexpr const T* get() const noexcept {
0040
0041 return arrow::internal::launder(reinterpret_cast<const T*>(&data_));
0042 }
0043
0044 void destroy() noexcept {
0045 if (!std::is_trivially_destructible<T>::value) {
0046 get()->~T();
0047 }
0048 }
0049
0050 template <typename... A>
0051 void construct(A&&... args) noexcept {
0052 new (&data_) T(std::forward<A>(args)...);
0053 }
0054
0055 template <typename V>
0056 void assign(V&& v) noexcept {
0057 *get() = std::forward<V>(v);
0058 }
0059
0060 void move_construct(AlignedStorage* other) noexcept {
0061 new (&data_) T(std::move(*other->get()));
0062 }
0063
0064 void move_assign(AlignedStorage* other) noexcept { *get() = std::move(*other->get()); }
0065
0066 template <bool CanMemcpy = can_memcpy>
0067 static typename std::enable_if<CanMemcpy>::type move_construct_several(
0068 AlignedStorage* ARROW_RESTRICT src, AlignedStorage* ARROW_RESTRICT dest, size_t n,
0069 size_t memcpy_length) noexcept {
0070 memcpy(dest->get(), src->get(), memcpy_length * sizeof(T));
0071 }
0072
0073 template <bool CanMemcpy = can_memcpy>
0074 static typename std::enable_if<CanMemcpy>::type
0075 move_construct_several_and_destroy_source(AlignedStorage* ARROW_RESTRICT src,
0076 AlignedStorage* ARROW_RESTRICT dest, size_t n,
0077 size_t memcpy_length) noexcept {
0078 memcpy(dest->get(), src->get(), memcpy_length * sizeof(T));
0079 }
0080
0081 template <bool CanMemcpy = can_memcpy>
0082 static typename std::enable_if<!CanMemcpy>::type move_construct_several(
0083 AlignedStorage* ARROW_RESTRICT src, AlignedStorage* ARROW_RESTRICT dest, size_t n,
0084 size_t memcpy_length) noexcept {
0085 for (size_t i = 0; i < n; ++i) {
0086 new (dest[i].get()) T(std::move(*src[i].get()));
0087 }
0088 }
0089
0090 template <bool CanMemcpy = can_memcpy>
0091 static typename std::enable_if<!CanMemcpy>::type
0092 move_construct_several_and_destroy_source(AlignedStorage* ARROW_RESTRICT src,
0093 AlignedStorage* ARROW_RESTRICT dest, size_t n,
0094 size_t memcpy_length) noexcept {
0095 for (size_t i = 0; i < n; ++i) {
0096 new (dest[i].get()) T(std::move(*src[i].get()));
0097 src[i].destroy();
0098 }
0099 }
0100
0101 static void move_construct_several(AlignedStorage* ARROW_RESTRICT src,
0102 AlignedStorage* ARROW_RESTRICT dest,
0103 size_t n) noexcept {
0104 move_construct_several(src, dest, n, n);
0105 }
0106
0107 static void move_construct_several_and_destroy_source(
0108 AlignedStorage* ARROW_RESTRICT src, AlignedStorage* ARROW_RESTRICT dest,
0109 size_t n) noexcept {
0110 move_construct_several_and_destroy_source(src, dest, n, n);
0111 }
0112
0113 static void destroy_several(AlignedStorage* p, size_t n) noexcept {
0114 if (!std::is_trivially_destructible<T>::value) {
0115 for (size_t i = 0; i < n; ++i) {
0116 p[i].destroy();
0117 }
0118 }
0119 }
0120
0121 private:
0122 alignas(T) std::byte data_[sizeof(T)];
0123 };
0124
0125 }
0126 }