19#include "AUI/Traits/concepts.h"
23namespace aui::impl::optional {
24 API_AUI_CORE
void throwException(
const char* message);
35 constexpr AOptional(std::nullopt_t)
noexcept {}
38 template<
typename U = T,
39 std::enable_if_t<std::is_constructible_v<T, U> && std::is_convertible_v<U&&, T>,
bool> =
true>
40 constexpr AOptional(U&& rhs)
noexcept: mInitialized(
true) {
41 new (ptrUnsafe()) T(std::forward<U>(rhs));
44 template<
typename U = T,
45 std::enable_if_t<std::is_constructible_v<T, U> && !std::is_convertible_v<U&&, T>,
bool> =
true>
46 explicit constexpr AOptional(U&& rhs)
noexcept: mInitialized(
true) {
47 new (ptrUnsafe()) T(std::forward<U>(rhs));
55 operator=(std::move(rhs));
65 operator=(std::move(rhs));
69 if (mInitialized) ptrUnsafe()->~T();
74 bool hasValue()
const noexcept {
78 constexpr explicit operator bool()
const noexcept {
82 template<
typename... Args>
85 new (ptrUnsafe()) T(std::forward<Args>(
args)...);
90 constexpr AOptional<T>& operator=(std::nullopt_t)
noexcept {
95 template<
typename U = T,
typename std::enable_if_t<std::is_convertible_v<U&&, T>,
bool> = true>
98 new (ptrUnsafe()) T(std::forward<U>(rhs));
105 operator=(rhs.value());
114 operator=(std::move(rhs.value()));
125 operator=(rhs.value());
137 operator=(std::move(rhs.value()));
147 template<
typename U = T>
150 new (ptrUnsafe()) T(std::move(rhs));
156 T& value()
noexcept {
158 return reinterpret_cast<T&
>(mStorage);
162 const T& value()
const noexcept {
164 return reinterpret_cast<const T&
>(mStorage);
173 const T* ptr()
const noexcept {
178 T* operator->()
noexcept {
183 const T* operator->()
const noexcept {
188 T& operator*()
noexcept {
193 const T& operator*()
const noexcept {
197 void reset()
noexcept {
200 mInitialized =
false;
211 aui::impl::optional::throwException(message);
212 throw std::logic_error(
"should not have reached here");
222 aui::impl::optional::throwException(message);
223 throw std::logic_error(
"should not have reached here");
237 constexpr bool isSame = std::is_constructible_v<T, F>;
238 constexpr bool isInvocable = std::is_invocable_v<F>;
240 static_assert(isSame || isInvocable,
"F is neither same as T nor invokable returning T nor invokable throwing a exception");
242 if constexpr (isSame) {
243 return std::forward<F>(alternative);
244 }
else if constexpr(isInvocable) {
245 if constexpr (std::is_same_v<std::invoke_result_t<F>,
void>) {
248 throw std::runtime_error(
"should not have reached here");
250 return alternative();
257 bool operator==(
const AOptional<U>& rhs)
const noexcept {
258 return (mInitialized == rhs.mInitialized) && (!mInitialized || value() == rhs.value());
263 bool operator==(
const U& rhs)
const noexcept {
264 return mInitialized && value() == rhs;
268 bool operator==(
const std::nullopt_t& rhs)
const noexcept {
269 return !mInitialized;
277 template<aui::invocable<const T&> Mapper>
281 return std::invoke(std::forward<Mapper>(mapper), value());
287 std::aligned_storage_t<
sizeof(T),
alignof(T)> mStorage;
288 bool mInitialized =
false;
291 T* ptrUnsafe() noexcept {
292 return &valueUnsafe();
296 T& valueUnsafe() noexcept {
297 return reinterpret_cast<T&
>(mStorage);
Utility wrapper implementing the stack-allocated (fast) optional idiom.
Definition: AOptional.h:32
const T & valueOrException(const char *message="empty optional") const
value or exception
Definition: AOptional.h:218
T valueOr(F &&alternative) const
value or alternative (either value or callback)
Definition: AOptional.h:233
T & valueOrException(const char *message="empty optional")
value or exception
Definition: AOptional.h:207
auto map(Mapper &&mapper) -> AOptional< decltype(std::invoke(std::forward< Mapper >(mapper), value()))> const
If a value is present, apply the provided mapper function to it.
Definition: AOptional.h:279
API_AUI_CORE const ACommandLineArgs & args() noexcept
Definition: OSAndroid.cpp:29
#define AUI_ASSERT_NO_CONDITION(what)
Always triggers assertion fail.
Definition: Assert.h:94
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition: Assert.h:74