15 #ifndef A_UTIL_UTIL_MEMORY_DETAIL_STACK_PTR_IMPL_HEADER_INCLUDED
16 #define A_UTIL_UTIL_MEMORY_DETAIL_STACK_PTR_IMPL_HEADER_INCLUDED
24 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
31 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
36 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
42 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
45 reset(std::move(data));
48 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
51 static_assert(StackSize >=
sizeof(T),
"Array size must be larger");
52 static_assert(
alignof(T) <=
Alignment,
"Alignment must match alignment requirement of T");
56 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
64 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
72 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
76 this->
reset(std::move(*other));
80 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
83 return static_cast<T*
>(address());
86 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
89 return static_cast<const T*
>(address());
92 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
95 return *(operator->());
98 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
101 return *(operator->());
104 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
107 return isConstructed();
110 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
113 if (isConstructed()) {
114 static_cast<T*
>(address())->~T();
115 setFlag(InitializeStatus, StackPtrFlags::IsDestroyed);
119 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
120 template <
typename... Args>
124 new (address()) T(std::forward<Args>(args)...);
125 setFlag(InitializeStatus, StackPtrFlags::IsConstructed);
128 template <
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()) {
138 reset_after_swap =
this;
140 swap(*(*
this), *other);
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();
163 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
169 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
175 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
179 _storage[position] =
static_cast<typename std::underlying_type<StackPtrFlags>::type
>(flag);
182 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
185 return _storage[InitializeStatus] ==
186 static_cast<typename std::underlying_type<StackPtrFlags>::type
>(
187 StackPtrFlags::IsConstructed);
190 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
196 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
197 inline bool operator==(
const StackPtr<T, StackSize, Alignment>& lhs,
198 const StackPtr<T, StackSize, Alignment>& rhs)
201 if (!lhs.isConstructed() && !rhs.isConstructed()) {
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 =
217 is_equal = lhs._storage[storage_index] == rhs._storage[storage_index];
222 template <
typename T, std::
size_t StackSize, std::
size_t Alignment>
226 return !(lhs == rhs);
229 template <
typename T, std::size_t StackSize, std::size_t
Alignment,
typename... Args>
tBool operator==(const tErrorCode &lhs, const tErrorCode &rhs)
Compare two POD error code types for equality.
A smart pointer allocating its memory only on the stack.
std::array< char, StorageSize > _storage
Aligned storage large enough to contain one object of type T and some overhead for flags.
StackPtr()
Initializes the storage and constructs object ot type T by calling its default ctor.
StackPtrFlags
Flags for StackPtrFlagPositions.
@ IsConstructed
for InitializeStatus --> contained object constructed
void setFlag(StackPtrFlagPositions position, StackPtrFlags flag)
Sets a flag to the appropriate position in the overhead section of the storage.
bool isConstructed() const noexcept
Check whether the object hidden by the storage got constructed.
T & operator*()
Operator overload to use this class like a raw pointer.
T * operator->()
Operator overload to use this class like a raw pointer.
void swap(StackPtr &other)
Swap storage of *this with storage of other stack pointer.
StackPtr & operator=(StackPtr other)
Assignment operator.
@ StorageSize
Entire size of the _storage, including aligned overhead for necessary flags.
@ OverheadSize
Size of the overhead containing the flags (complying to alignment)
void reset()
Unitializes the storage and, if constructed, destructs the storaged object.
StackPtrFlagPositions
Absolute bit positions of the flags inside the overhead area of the storage.
@ InitializeStatus
Flag position for the initialize status.
void * address()
Get pointer to beginning of the storage.
void swap(StackPtr< T, StackSize, Alignment > &lhs, StackPtr< T, StackSize, Alignment > &rhs)
Swap storages of two objects of type StackPtr.
constexpr auto makeStackPtr(Args &&... args) -> StackPtr< T, StackSize, Alignment >
Create a new StackPtr.
bool operator!=(const StackPtr< T, StackSize, Alignment > &lhs, const StackPtr< T, StackSize, Alignment > &rhs)
Compare for inequality.
Serves as the root component, with common functionality documented in core functionality.
tResult is_equal(const ant::IProperties &oLeftProperties, const ant::IProperties &oRightProperties)
Check if two property sets are equal.
tResult reset(T &oCodec, const A_UTILS_NS::cString &strElementName)
Set the value of the requested element to zero.
Alignment
Alignment defintion.
Public API for StackPtr type and functions.