35 constexpr AOptional()
noexcept =
default;
36 constexpr AOptional(std::nullopt_t)
noexcept {}
39 template<
typename U = T,
40 std::enable_if_t<std::is_constructible_v<T, U> && std::is_convertible_v<U&&, T>,
bool> =
true>
41 constexpr AOptional(U&& rhs)
noexcept: mInitialized(
true) {
42 new (ptrUnsafe()) T(std::forward<U>(rhs));
45 template<
typename U = T,
46 std::enable_if_t<std::is_constructible_v<T, U> && !std::is_convertible_v<U&&, T>,
bool> =
true>
47 explicit constexpr AOptional(U&& rhs)
noexcept: mInitialized(
true) {
48 new (ptrUnsafe()) T(std::forward<U>(rhs));
51 constexpr AOptional(
const AOptional& rhs) {
55 constexpr AOptional(AOptional&& rhs)
noexcept {
56 operator=(std::move(rhs));
60 constexpr AOptional(
const AOptional<U>& rhs) {
65 constexpr AOptional(AOptional<U>&& rhs)
noexcept {
66 operator=(std::move(rhs));
70 if (mInitialized) ptrUnsafe()->~T();
75 bool hasValue()
const noexcept {
79 constexpr explicit operator bool()
const noexcept {
83 template<
typename... Args>
84 constexpr AOptional<T>& emplace(Args&&... args) {
86 new (ptrUnsafe()) T(std::forward<Args>(args)...);
91 constexpr AOptional<T>& operator=(std::nullopt_t)
noexcept {
96 template<
typename U = T,
typename std::enable_if_t<std::is_convertible_v<U&&, T>,
bool> = true>
97 constexpr AOptional<T>& operator=(U&& rhs)
noexcept {
99 new (ptrUnsafe()) T(std::forward<U>(rhs));
104 constexpr AOptional<T>& operator=(
const AOptional& rhs)
noexcept {
106 operator=(rhs.value());
113 constexpr AOptional<T>& operator=(AOptional&& rhs)
noexcept {
115 operator=(std::move(rhs.value()));
124 constexpr AOptional<T>& operator=(
const AOptional<U>& rhs)
noexcept {
126 operator=(rhs.value());
136 constexpr AOptional<T>& operator=(AOptional<U>&& rhs)
noexcept {
138 operator=(std::move(rhs.value()));
148 template<
typename U = T>
149 constexpr AOptional<T>& operator=(T&& rhs)
noexcept {
151 new (ptrUnsafe()) T(std::move(rhs));
157 T& value()
noexcept {
159 return reinterpret_cast<T&
>(mStorage);
163 const T& value()
const noexcept {
165 return reinterpret_cast<const T&
>(mStorage);
174 const T* ptr()
const noexcept {
179 T* operator->()
noexcept {
184 const T* operator->()
const noexcept {
189 T& operator*()
noexcept {
194 const T& operator*()
const noexcept {
198 void reset()
noexcept {
201 mInitialized =
false;
212 aui::impl::optional::throwException(message);
213 throw std::logic_error(
"should not have reached here");
223 aui::impl::optional::throwException(message);
224 throw std::logic_error(
"should not have reached here");
238 constexpr bool isSame = std::is_constructible_v<T, F>;
239 constexpr bool isInvocable = std::is_invocable_v<F>;
241 static_assert(isSame || isInvocable,
"F is neither same as T nor invokable returning T nor invokable throwing a exception");
243 if constexpr (isSame) {
244 return std::forward<F>(alternative);
245 }
else if constexpr(isInvocable) {
246 if constexpr (std::is_same_v<std::invoke_result_t<F>,
void>) {
249 throw std::runtime_error(
"should not have reached here");
251 return alternative();
258 bool operator==(
const AOptional<U>& rhs)
const noexcept {
259 return (mInitialized == rhs.mInitialized) && (!mInitialized || value() == rhs.value());
264 bool operator==(
const U& rhs)
const noexcept {
265 return mInitialized && value() == rhs;
269 bool operator==(
const std::nullopt_t& rhs)
const noexcept {
270 return !mInitialized;
278 template<aui::invocable<const T&> Mapper>
280 auto map(Mapper&& mapper) -> AOptional<decltype(std::invoke(std::forward<Mapper>(mapper), value()))>
const {
282 return std::invoke(std::forward<Mapper>(mapper), value());
288 std::aligned_storage_t<
sizeof(T),
alignof(T)> mStorage{};
289 bool mInitialized =
false;
292 T* ptrUnsafe() noexcept {
293 return &valueUnsafe();
297 T& valueUnsafe() noexcept {
298 return reinterpret_cast<T&
>(mStorage);
T valueOr(F &&alternative) const
value or alternative (either value or callback)
Definition AOptional.h:234
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:280
#define AUI_ASSERTX(condition, what)
Asserts that the passed condition evaluates to true. Adds extra message string.
Definition Assert.h:74