51 static_assert(StackSize >=
sizeof(T),
"Array size must be larger");
52 static_assert(
alignof(T) <= Alignment,
"Alignment must match alignment requirement of T");
56template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
59 if (other.isConstructed()) {
64template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
72template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
75 if (other.isConstructed()) {
76 this->reset(std::move(*other));
80template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
83 return static_cast<T*
>(address());
86template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
89 return static_cast<const T*
>(address());
92template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
98template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
104template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
107 return isConstructed();
110template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
113 if (isConstructed()) {
114 static_cast<T*
>(address())->~T();
115 setFlag(InitializeStatus, StackPtrFlags::IsDestroyed);
119template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
120template <
typename... Args>
124 new (address()) T(std::forward<Args>(args)...);
125 setFlag(InitializeStatus, StackPtrFlags::IsConstructed);
128template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
132 StackPtr* reset_after_swap =
nullptr;
133 std::size_t remaining_bytes_to_swap = OverheadSize;
135 if (this->isConstructed()) {
136 if (!other.isConstructed()) {
138 reset_after_swap =
this;
140 swap(*(*
this), *other);
142 else if (other.isConstructed()) {
144 reset_after_swap = &other;
145 swap(*(*
this), *other);
148 remaining_bytes_to_swap = StorageSize;
152 while (remaining_bytes_to_swap) {
154 const std::size_t storage_index = StorageSize - remaining_bytes_to_swap--;
155 swap(this->_storage[storage_index], other._storage[storage_index]);
158 if (reset_after_swap) {
159 reset_after_swap->reset();
163template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
164inline void* StackPtr<T, StackSize, Alignment>::address()
169template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
170inline const void* StackPtr<T, StackSize, Alignment>::address()
const
175template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
176inline void StackPtr<T, StackSize, Alignment>::setFlag(StackPtrFlagPositions position,
179 _storage[position] =
static_cast<typename std::underlying_type<StackPtrFlags>::type
>(flag);
182template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
183inline bool StackPtr<T, StackSize, Alignment>::isConstructed() const noexcept
185 return _storage[InitializeStatus] ==
186 static_cast<typename std::underlying_type<StackPtrFlags>::type
>(
187 StackPtrFlags::IsConstructed);
190template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
196template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
197inline bool operator==(
const StackPtr<T, StackSize, Alignment>& lhs,
198 const StackPtr<T, StackSize, Alignment>& rhs)
200 std::size_t remaining_bytes_to_compare = StackPtr<T, StackSize, Alignment>::OverheadSize;
201 if (!lhs.isConstructed() && !rhs.isConstructed()) {
202 remaining_bytes_to_compare = StackPtr<T, StackSize, Alignment>::StorageSize;
204 else if (lhs.isConstructed() ^ rhs.isConstructed()) {
207 else if (!(*lhs == *rhs)) {
214 while (remaining_bytes_to_compare && is_equal) {
215 const std::size_t storage_index =
216 StackPtr<T, StackSize, Alignment>::StorageSize - remaining_bytes_to_compare--;
217 is_equal = lhs._storage[storage_index] == rhs._storage[storage_index];
222template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
226 return !(lhs == rhs);
229template <
typename T, std::size_t StackSize, std::size_t Alignment,
typename... Args>