34 constexpr AOptional()
noexcept =
default;
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));
50 constexpr AOptional(
const AOptional& rhs) {
54 constexpr AOptional(AOptional&& rhs)
noexcept {
55 operator=(std::move(rhs));
59 constexpr AOptional(
const AOptional<U>& rhs) {
64 constexpr AOptional(AOptional<U>&& rhs)
noexcept {
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>
83 constexpr AOptional<T>& emplace(Args&&... 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>
96 constexpr AOptional<T>& operator=(U&& rhs)
noexcept {
98 new (ptrUnsafe()) T(std::forward<U>(rhs));
103 constexpr AOptional<T>& operator=(
const AOptional& rhs)
noexcept {
105 operator=(rhs.value());
112 constexpr AOptional<T>& operator=(AOptional&& rhs)
noexcept {
114 operator=(std::move(rhs.value()));
123 constexpr AOptional<T>& operator=(
const AOptional<U>& rhs)
noexcept {
125 operator=(rhs.value());
135 constexpr AOptional<T>& operator=(AOptional<U>&& rhs)
noexcept {
137 operator=(std::move(rhs.value()));
147 template<
typename U = T>
148 constexpr AOptional<T>& operator=(T&& rhs)
noexcept {
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>
279 auto map(Mapper&& mapper) -> AOptional<decltype(std::invoke(std::forward<Mapper>(mapper), value()))>
const {
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);
T valueOr(F &&alternative) const
value or alternative (either value or callback)
Definition AOptional.h:233
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
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition Assert.h:74