Go to the documentation of this file.
9 #ifndef EAGINE_VALID_IF_BASE_HPP
10 #define EAGINE_VALID_IF_BASE_HPP
12 #include "../assert.hpp"
13 #include "../branch_predict.hpp"
16 #include <type_traits>
30 noexcept(T(std::declval<T&&>())))
31 : _value{std::move(value)} {}
35 std::is_nothrow_default_constructible_v<T>) = default;
39 std::is_nothrow_move_constructible_v<T>) = default;
43 std::is_nothrow_copy_constructible_v<T>) = default;
57 auto operator=(const T& v) -> auto& {
64 _value = std::move(v);
69 auto _ref_value() noexcept -> auto& {
73 constexpr
auto _get_value() const noexcept -> auto& {
85 template <
typename T,
typename Policy,
typename DoLog,
typename... P>
91 auto _do_log()
const noexcept ->
const DoLog& {
101 [[nodiscard]]
auto policy() const noexcept -> const Policy& {
117 , Policy(std::move(plcy))
124 , Policy(static_cast<const Policy&>(that))
129 std::is_nothrow_move_constructible_v<T>)
131 , Policy(static_cast<Policy&&>(that))
137 if(
this != std::addressof(that)) {
140 static_cast<Policy&
>(*this) =
static_cast<const Policy&
>(that);
141 static_cast<DoLog&
>(*this) = {
policy()};
148 std::is_nothrow_move_assignable_v<T>) ->
auto& {
149 if(
this != std::addressof(that)) {
152 static_cast<Policy&
>(*this) =
static_cast<Policy&&
>(that);
153 static_cast<DoLog&
>(*this) = DoLog(
policy());
176 constexpr auto
is_valid(const T& val, P... p) const noexcept ->
bool {
177 return policy()(val, p...);
183 return is_valid(this->_get_value(), p...);
193 constexpr
friend auto
196 return (a._get_value() == b._get_value()) && a.is_valid() &&
200 template <
typename Log>
201 void log_invalid(Log& log,
const T& v, P... p)
const {
203 _do_log()(log, v, p...);
206 template <
typename Log>
207 void log_invalid(Log& log, P... p)
const {
208 log_invalid(log, this->_get_value(), p...);
214 template <
typename Func>
217 func(_do_log(), this->_get_value(), p...);
227 std::stringstream ss;
228 log_invalid(ss, p...);
229 throw std::runtime_error(ss.str());
238 return this->_ref_value();
244 auto value(P... p)
const ->
const T& {
246 return this->_get_value();
251 auto value_or(T& fallback, P... p) noexcept ->
auto& {
252 return EAGINE_LIKELY(
is_valid(p...)) ? this->_ref_value() : fallback;
257 constexpr
auto value_or(
const T& fallback, P... p)
const noexcept ->
auto& {
258 return EAGINE_LIKELY(
is_valid(p...)) ? this->_get_value() : fallback;
263 return this->_get_value();
268 return this->_ref_value();
274 template <
typename Func>
275 auto then(
const Func& func, P... p)
const
276 -> std::enable_if_t<std::is_same_v<std::result_of_t<Func(T)>,
void>> {
285 template <
typename Func>
287 return func(this->_get_value(),
is_valid(p...));
293 #endif // EAGINE_VALID_IF_BASE_HPP
constexpr auto has_value(P... p) const noexcept
Checks if the stored value is valid according to policy.
Definition: base.hpp:188
auto operator=(T &&v) -> auto &
Moves v to the stored value.
Definition: base.hpp:63
constexpr auto value_anyway(P...) const noexcept -> auto &
Returns the stored value regardless of its validity.
Definition: base.hpp:262
constexpr basic_valid_if(T val) noexcept
Constructor initializing the stored value by val.
Definition: base.hpp:110
constexpr friend auto operator==(const basic_valid_if &a, const basic_valid_if &b) noexcept -> bool
Equality comparison.
Definition: base.hpp:194
Common code is placed in this namespace.
Definition: eagine.hpp:21
constexpr basic_valid_if_value(T value) noexcept(noexcept(T(std::declval< T && >())))
Initializing constructor.
Definition: base.hpp:29
auto call_if_invalid(Func func, P... p) -> auto &
Calls the specified function if the stored value is invalid.
Definition: base.hpp:215
constexpr basic_valid_if(const basic_valid_if &that)
Copy constructor.
Definition: base.hpp:121
auto operator=(const basic_valid_if &that) -> auto &
Copy assignment operator.
Definition: base.hpp:136
auto policy() const noexcept -> const Policy &
Returns a reference to this object's policy.
Definition: base.hpp:101
constexpr basic_valid_if(T val, Policy plcy) noexcept
Constructor initializing the stored value and policy.
Definition: base.hpp:115
auto operator=(const T &value) -> auto &
Copies value into this instance.
Definition: base.hpp:159
constexpr auto is_valid(const T &val, P... p) const noexcept -> bool
Checks if val is valid according to this object's policy.
Definition: base.hpp:176
constexpr auto transformed(Func func, P... p) const noexcept
Calls a binary transforming function on {value, is_valid()} pair.
Definition: base.hpp:286
~basic_valid_if() noexcept=default
The destructor.
Base class for basic_valid_if, storing the conditionally valid value.
Definition: base.hpp:26
auto then(const Func &func, P... p) const -> std::enable_if_t< std::is_same_v< std::result_of_t< Func(T)>, void >>
Calls the specified function if the stored value is valid.
Definition: base.hpp:275
void throw_if_invalid(P... p) const
Throws an exception if the stored value is invalid.
Definition: base.hpp:225
auto value_or(T &fallback, P... p) noexcept -> auto &
Returns the stored value if valid, otherwise returns fallback.
Definition: base.hpp:251
constexpr auto value_anyway(P...) noexcept -> auto &
Returns the stored value regardless of its validity.
Definition: base.hpp:267
basic_valid_if(basic_valid_if &&that) noexcept(std::is_nothrow_move_constructible_v< T >)
Move constructor.
Definition: base.hpp:128
constexpr basic_valid_if_value() noexcept(std::is_nothrow_default_constructible_v< T >)=default
Default constructor.
constexpr basic_valid_if() noexcept
Default constructor.
Definition: base.hpp:106
auto value(P... p) -> T &
Returns the stored value if it is valid otherwise throws.
Definition: base.hpp:236
auto operator=(basic_valid_if &&that) noexcept(std::is_nothrow_move_assignable_v< T >) -> auto &
Move assignment operator.
Definition: base.hpp:147
Basic template for conditionally-valid values.
Definition: base.hpp:86