From cf7db48c261ee9c896c813a38ff8c59da5b8fe07 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sun, 26 Jan 2025 00:40:51 +0100 Subject: Fix line endings --- asl/option.hpp | 1016 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 508 insertions(+), 508 deletions(-) (limited to 'asl/option.hpp') diff --git a/asl/option.hpp b/asl/option.hpp index f7a3eab..d12d4ce 100644 --- a/asl/option.hpp +++ b/asl/option.hpp @@ -1,509 +1,509 @@ -#pragma once - -#include "asl/assert.hpp" -#include "asl/meta.hpp" -#include "asl/maybe_uninit.hpp" -#include "asl/functional.hpp" -#include "asl/annotations.hpp" -#include "asl/hash.hpp" - -namespace asl -{ - -struct nullopt_t {}; -static constexpr nullopt_t nullopt{}; - -// @Todo(option) Reference -// @Todo(option) Function -// @Todo(option) Arrays - -template class option; - -namespace option_internal -{ - -template -concept not_constructible_from_option = - !constructible_from&> && - !constructible_from&> && - !constructible_from&&> && - !constructible_from&&>; - -template -concept not_assignable_from_option = - !assignable_from&> && - !assignable_from&> && - !assignable_from&&> && - !assignable_from&&>; - -template -concept not_constructible_assignable_from_option = - not_constructible_from_option && - not_assignable_from_option; - -} // namespace option_internal - -template -concept is_option = requires -{ - typename T::type; - requires same_as, option>; -}; - -template -class option -{ - static constexpr bool kHasNiche = has_niche; - - using HasValueMarker = select_t; - - maybe_uninit m_payload{}; - ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value{}; - - template - friend class option; - - template - constexpr void construct(Args&&... args) - { - ASL_ASSERT(!has_value()); - - if constexpr (!kHasNiche) - { - m_payload.construct_unsafe(ASL_FWD(args)...); - m_has_value = true; - } - else - { - if constexpr (move_assignable) - { - m_payload.assign_unsafe(ASL_MOVE(T{ASL_FWD(args)...})); - } - else - { - m_payload.destroy_unsafe(); - m_payload.construct_unsafe(ASL_FWD(args)...); - } - } - } - - template - constexpr void assign(U&& arg) - { - ASL_ASSERT(has_value()); - m_payload.assign_unsafe(ASL_FWD(arg)); - } - -public: - using type = T; - - constexpr option() : option{nullopt} {} - - // NOLINTNEXTLINE(*-explicit-conversions) - constexpr option(nullopt_t) requires (!kHasNiche) {} - - // NOLINTNEXTLINE(*-explicit-conversions) - constexpr option(nullopt_t) requires kHasNiche : m_payload{in_place, niche_t{}} {} - - template - constexpr explicit (!convertible_from) - option(U&& value) - requires ( - kHasNiche && - constructible_from && - !same_as, option> - ) - : m_payload{in_place, ASL_FWD(value)} - {} - - template - constexpr explicit (!convertible_from) - option(U&& value) - requires ( - !kHasNiche && - constructible_from && - !is_option - ) - : m_payload{in_place, ASL_FWD(value)} - , m_has_value{true} - {} - - constexpr option(const option& other) requires trivially_copy_constructible = default; - constexpr option(const option& other) requires (!copy_constructible) = delete; - - constexpr option(const option& other) - requires copy_constructible && (!trivially_copy_constructible) - : option{nullopt} - { - if (other.has_value()) - { - construct(other.m_payload.as_init_unsafe()); - } - } - - constexpr option(option&& other) requires trivially_move_constructible = default; - constexpr option(option&& other) requires (!move_constructible) = delete; - - constexpr option(option&& other) - requires move_constructible && (!trivially_move_constructible) - : option{nullopt} - { - if (other.has_value()) - { - construct(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - } - - template - constexpr explicit (!convertible_from) - option(const option& other) - requires ( - constructible_from && - option_internal::not_constructible_from_option - ) - : option{nullopt} - { - if (other.has_value()) - { - construct(other.m_payload.as_init_unsafe()); - } - } - - template - constexpr explicit (!convertible_from) - option(option&& other) - requires ( - constructible_from && - option_internal::not_constructible_from_option - ) - : option{nullopt} - { - if (other.has_value()) - { - construct(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - } - - constexpr option& operator=(nullopt_t) & - { - reset(); - return *this; - } - - template - constexpr option& operator=(U&& value) & - requires ( - assignable_from && - constructible_from && - !is_option - ) - { - if (has_value()) - { - assign(ASL_FWD(value)); - } - else - { - construct(ASL_FWD(value)); - } - - return *this; - } - - constexpr option& operator=(const option& other) & - requires (!copy_assignable) = delete; - - constexpr option& operator=(const option& other) & - requires trivially_copy_assignable = default; - - constexpr option& operator=(const option& other) & - requires copy_assignable && (!trivially_copy_constructible) - { - if (&other == this) { return *this; } - - if (other.has_value()) - { - if (has_value()) - { - assign(other.m_payload.as_init_unsafe()); - } - else - { - construct(other.m_payload.as_init_unsafe()); - } - } - else if (has_value()) - { - reset(); - } - - return *this; - } - - constexpr option& operator=(option&& other) & - requires (!move_assignable) = delete; - - constexpr option& operator=(option&& other) & - requires trivially_move_assignable = default; - - constexpr option& operator=(option&& other) & - requires move_assignable && (!trivially_move_constructible) - { - if (&other == this) { return *this; } - - if (other.has_value()) - { - if (has_value()) - { - assign(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - else - { - construct(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - } - else if (has_value()) - { - reset(); - } - - return *this; - } - - template - constexpr option& operator=(const option& other) & - requires ( - constructible_from && - assignable_from && +#pragma once + +#include "asl/assert.hpp" +#include "asl/meta.hpp" +#include "asl/maybe_uninit.hpp" +#include "asl/functional.hpp" +#include "asl/annotations.hpp" +#include "asl/hash.hpp" + +namespace asl +{ + +struct nullopt_t {}; +static constexpr nullopt_t nullopt{}; + +// @Todo(option) Reference +// @Todo(option) Function +// @Todo(option) Arrays + +template class option; + +namespace option_internal +{ + +template +concept not_constructible_from_option = + !constructible_from&> && + !constructible_from&> && + !constructible_from&&> && + !constructible_from&&>; + +template +concept not_assignable_from_option = + !assignable_from&> && + !assignable_from&> && + !assignable_from&&> && + !assignable_from&&>; + +template +concept not_constructible_assignable_from_option = + not_constructible_from_option && + not_assignable_from_option; + +} // namespace option_internal + +template +concept is_option = requires +{ + typename T::type; + requires same_as, option>; +}; + +template +class option +{ + static constexpr bool kHasNiche = has_niche; + + using HasValueMarker = select_t; + + maybe_uninit m_payload{}; + ASL_NO_UNIQUE_ADDRESS HasValueMarker m_has_value{}; + + template + friend class option; + + template + constexpr void construct(Args&&... args) + { + ASL_ASSERT(!has_value()); + + if constexpr (!kHasNiche) + { + m_payload.construct_unsafe(ASL_FWD(args)...); + m_has_value = true; + } + else + { + if constexpr (move_assignable) + { + m_payload.assign_unsafe(ASL_MOVE(T{ASL_FWD(args)...})); + } + else + { + m_payload.destroy_unsafe(); + m_payload.construct_unsafe(ASL_FWD(args)...); + } + } + } + + template + constexpr void assign(U&& arg) + { + ASL_ASSERT(has_value()); + m_payload.assign_unsafe(ASL_FWD(arg)); + } + +public: + using type = T; + + constexpr option() : option{nullopt} {} + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr option(nullopt_t) requires (!kHasNiche) {} + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr option(nullopt_t) requires kHasNiche : m_payload{in_place, niche_t{}} {} + + template + constexpr explicit (!convertible_from) + option(U&& value) + requires ( + kHasNiche && + constructible_from && + !same_as, option> + ) + : m_payload{in_place, ASL_FWD(value)} + {} + + template + constexpr explicit (!convertible_from) + option(U&& value) + requires ( + !kHasNiche && + constructible_from && + !is_option + ) + : m_payload{in_place, ASL_FWD(value)} + , m_has_value{true} + {} + + constexpr option(const option& other) requires trivially_copy_constructible = default; + constexpr option(const option& other) requires (!copy_constructible) = delete; + + constexpr option(const option& other) + requires copy_constructible && (!trivially_copy_constructible) + : option{nullopt} + { + if (other.has_value()) + { + construct(other.m_payload.as_init_unsafe()); + } + } + + constexpr option(option&& other) requires trivially_move_constructible = default; + constexpr option(option&& other) requires (!move_constructible) = delete; + + constexpr option(option&& other) + requires move_constructible && (!trivially_move_constructible) + : option{nullopt} + { + if (other.has_value()) + { + construct(ASL_MOVE(other.m_payload.as_init_unsafe())); + } + } + + template + constexpr explicit (!convertible_from) + option(const option& other) + requires ( + constructible_from && + option_internal::not_constructible_from_option + ) + : option{nullopt} + { + if (other.has_value()) + { + construct(other.m_payload.as_init_unsafe()); + } + } + + template + constexpr explicit (!convertible_from) + option(option&& other) + requires ( + constructible_from && + option_internal::not_constructible_from_option + ) + : option{nullopt} + { + if (other.has_value()) + { + construct(ASL_MOVE(other.m_payload.as_init_unsafe())); + } + } + + constexpr option& operator=(nullopt_t) & + { + reset(); + return *this; + } + + template + constexpr option& operator=(U&& value) & + requires ( + assignable_from && + constructible_from && + !is_option + ) + { + if (has_value()) + { + assign(ASL_FWD(value)); + } + else + { + construct(ASL_FWD(value)); + } + + return *this; + } + + constexpr option& operator=(const option& other) & + requires (!copy_assignable) = delete; + + constexpr option& operator=(const option& other) & + requires trivially_copy_assignable = default; + + constexpr option& operator=(const option& other) & + requires copy_assignable && (!trivially_copy_constructible) + { + if (&other == this) { return *this; } + + if (other.has_value()) + { + if (has_value()) + { + assign(other.m_payload.as_init_unsafe()); + } + else + { + construct(other.m_payload.as_init_unsafe()); + } + } + else if (has_value()) + { + reset(); + } + + return *this; + } + + constexpr option& operator=(option&& other) & + requires (!move_assignable) = delete; + + constexpr option& operator=(option&& other) & + requires trivially_move_assignable = default; + + constexpr option& operator=(option&& other) & + requires move_assignable && (!trivially_move_constructible) + { + if (&other == this) { return *this; } + + if (other.has_value()) + { + if (has_value()) + { + assign(ASL_MOVE(other.m_payload.as_init_unsafe())); + } + else + { + construct(ASL_MOVE(other.m_payload.as_init_unsafe())); + } + } + else if (has_value()) + { + reset(); + } + + return *this; + } + + template + constexpr option& operator=(const option& other) & + requires ( + constructible_from && + assignable_from && option_internal::not_constructible_assignable_from_option - ) - { - if (other.has_value()) - { - if (has_value()) - { - assign(other.m_payload.as_init_unsafe()); - } - else - { - construct(other.m_payload.as_init_unsafe()); - } - } - else if (has_value()) - { - reset(); - } - - return *this; - } - - template - constexpr option& operator=(option&& other) & - requires ( - constructible_from && - assignable_from && - option_internal::not_constructible_assignable_from_option - ) - { - if (other.has_value()) - { - if (has_value()) - { - assign(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - else - { - construct(ASL_MOVE(other.m_payload.as_init_unsafe())); - } - } - else if (has_value()) - { - reset(); - } - - return *this; - } - - constexpr ~option() requires trivially_destructible = default; - constexpr ~option() requires (!trivially_destructible) - { - reset(); - } - - constexpr void reset() - { - if (!has_value()) { return; } - - if constexpr (kHasNiche) - { - if constexpr (move_assignable) - { - m_payload.assign_unsafe(ASL_MOVE(T{niche_t{}})); - } - else - { - m_payload.destroy_unsafe(); - m_payload.construct_unsafe(niche_t{}); - } - } - else - { - m_has_value = false; - m_payload.destroy_unsafe(); - } - } - - constexpr bool has_value() const - { - if constexpr (kHasNiche) - { - return m_payload.as_init_unsafe() != niche_t{}; - } - else - { - return m_has_value; - } - } - - // @Todo(C++23) Deducing this - constexpr T&& value() && - { - ASL_ASSERT_RELEASE(has_value()); - return ASL_MOVE(m_payload).as_init_unsafe(); - } - - constexpr T& value() & - { - ASL_ASSERT_RELEASE(has_value()); - return m_payload.as_init_unsafe(); - } - - constexpr const T& value() const& - { - ASL_ASSERT_RELEASE(has_value()); - return m_payload.as_init_unsafe(); - } - - template - constexpr T value_or(U&& other_value) const& - requires copy_constructible && convertible_from - { - return has_value() ? value() : static_cast(ASL_FWD(other_value)); - } - - template - constexpr T value_or(U&& other_value) && - requires move_constructible && convertible_from - { - return has_value() ? ASL_MOVE(value()) : static_cast(ASL_FWD(other_value)); - } - - template - constexpr T& emplace(Args&&... args) & - requires constructible_from - { - if (has_value()) { reset(); } - construct(ASL_FWD(args)...); - return value(); - } - - template - constexpr auto and_then(F&& f) & - requires is_option> - { - if (has_value()) - { - return invoke(ASL_FWD(f), value()); - } - return un_cvref_t>{}; - } - - template - constexpr auto and_then(F&& f) const& - requires is_option> - { - if (has_value()) - { - return invoke(ASL_FWD(f), value()); - } - return un_cvref_t>{}; - } - - template - constexpr auto and_then(F&& f) && - requires is_option> - { - if (has_value()) - { - return invoke(ASL_FWD(f), ASL_MOVE(value())); - } - return un_cvref_t>{}; - } - - template - constexpr auto transform(F&& f) & - { - using U = un_cvref_t>; - if (has_value()) - { - return option{ invoke(ASL_FWD(f), value()) }; - } - return option{}; - } - - template - constexpr auto transform(F&& f) const& - { - using U = un_cvref_t>; - if (has_value()) - { - return option{ invoke(ASL_FWD(f), value()) }; - } - return option{}; - } - - template - constexpr auto transform(F&& f) && - { - using U = un_cvref_t>; - if (has_value()) - { - return option{ invoke(ASL_FWD(f), ASL_MOVE(value())) }; - } - return option{}; - } - - template - constexpr option or_else(F&& f) const& - requires same_as>, option> - { - return has_value() ? *this : invoke(ASL_FWD(f)); - } - - template - constexpr option or_else(F&& f) && - requires same_as>, option> - { - return has_value() ? ASL_MOVE(*this) : invoke(ASL_FWD(f)); - } - - template - requires (!uniquely_represented