libhatchet
Loading...
Searching...
No Matches
hxexpected.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
8
9#include "libhatchet.h"
10
11static_assert(HX_CPLUSPLUS >= 202302L, "hxexpected.hpp requires C++23");
12
13// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
14#if HX_USE_MACROS_WITH_MODULE
15#error Header does not provide macros alone.
16#endif
17
18#include "hxallocator.hpp"
19#include "hxkey.hpp"
20
21HX_NS_BEGIN_
22
24template<typename T_>
25concept hxexpected_concept_ = requires(T_& x_, const T_& y_) {
26 sizeof(T_);
27 T_();
28 T_(y_);
29 T_(hxmove(x_));
30 x_ = y_;
31 x_ = hxmove(x_);
32 x_.~T_();
33 { x_ == y_ } -> hxsame_as<bool>;
34};
35
36template<typename E_>
37concept hxunexpected_concept_ = requires(E_& x_, const E_& y_) {
38 sizeof(E_);
39 E_(true);
40 E_(false);
41 E_(y_);
42 E_(hxmove(x_));
43 x_ = y_;
44 x_ = hxmove(x_);
45 x_.~E_();
46 { static_cast<bool>(y_) };
47 { x_ == y_ } -> hxsame_as<bool>;
48};
49
50template<hxexpected_concept_ T_, hxunexpected_concept_ E_=bool> class hxexpected;
51
52// Used to prevent forwarding constructors from hijacking converting-copy
53// construction paths.
54template<typename> class hxis_hxexpected_ : public hxfalse_t { };
55template<typename T_, typename E_>
56class hxis_hxexpected_<hxexpected<T_, E_>> : public hxtrue_t { };
58
66template<hxexpected_concept_ T_, hxunexpected_concept_ E_>
67class hxexpected : private hxallocator<T_, 1> {
68public:
69 // These are for safety. Use hxref for pointer and reference types.
70 static_assert(!hxis_reference<T_>(), "hxexpected does not support reference types");
71 static_assert(!hxis_pointer<T_>(), "hxexpected does not support pointer types");
72
74 using error_t = E_;
75
77 using value_t = T_;
78
80 hxexpected(void) : m_error_(true) { }
81
84 hxexpected(hxnil_t) : m_error_(true) { }
85
88 hxexpected(const hxexpected& x_) noexcept;
89
92 hxexpected(hxexpected&& x_) noexcept;
93
99 template<typename error_t_=E_, typename... args_t_, hxenable_if_t<
100 !hxis_hxexpected_<hxremove_cvref_t<error_t_>>::value, bool> = true>
101 explicit hxexpected(error_t_&& error_, args_t_&&... args_) noexcept;
102
105
108 hxattr_nodiscard const T_& operator*(void) const;
109
111
114 hxattr_nodiscard const T_* operator->(void) const;
115
117
119 hxattr_nodiscard explicit operator bool(void) const { return !static_cast<bool>(m_error_); }
120
123 hxexpected& operator=(const hxexpected& x_) noexcept;
124
128
131 hxexpected& operator=(hxnil_t) { this->reset(); return *this; }
132
135 template<typename U_=T_, hxenable_if_t<
136 !hxis_hxexpected_<hxremove_cvref_t<U_>>::value &&
137 !hxis_same<hxremove_cvref_t<U_>, E_>(), bool> = true>
138 hxexpected& operator=(U_&& value_) noexcept;
139
143 hxattr_nodiscard bool operator==(const hxexpected& x_) const { return this->equal(x_); }
144
147 hxattr_nodiscard bool operator==(hxnil_t) const { return static_cast<bool>(m_error_); }
148
151 hxattr_nodiscard bool operator==(const T_& value_) const;
152
157 template<typename self_t_, typename callable_t_>
158 hxattr_nodiscard auto and_then(this self_t_&& self_, callable_t_&& callable_)
161
164 template<typename... args_t_>
165 T_& emplace(args_t_&&... args_) noexcept;
166
170 hxattr_nodiscard bool equal(const hxexpected& x_) const;
171
174 template<typename self_t_>
175 hxattr_nodiscard auto error(this self_t_&& self_)
177
179 hxattr_nodiscard bool has_value(void) const { return !static_cast<bool>(m_error_); }
180
183
187 template<typename self_t_, typename callable_t_>
188 hxattr_nodiscard hxexpected or_else(this self_t_&& self_, callable_t_&& callable_);
189
191 void reset(void) noexcept;
192
196 void reset(const E_& error_) noexcept;
197
200 void swap(hxexpected& x_) noexcept;
201
204 template<typename self_t_>
205 hxattr_nodiscard auto value(this self_t_&& self_)
207
212 template<typename self_t_, typename... args_t_>
213 hxattr_nodiscard T_ value_or(this self_t_&& self_, args_t_&&... args_);
214
215private:
216 E_ m_error_;
217};
218
222template<typename T_>
224 return hxexpected<T_>(false, value_);
225}
226
230template<typename T_, typename E_, typename... args_t_>
232 hxexpected<T_, E_> result_;
233 result_.emplace(hxforward<args_t_>(args_)...);
234 return result_;
235}
236
238template<typename T_, typename E_>
239class hxkey_equal_t<hxexpected<T_, E_> > {
240public:
243 const hxexpected<T_, E_>& x_, const hxexpected<T_, E_>& y_) const {
244 return x_.equal(y_);
245 }
246};
247
250template<typename T_, typename E_>
251class hxkey_hash_t<hxexpected<T_, E_> > {
252public:
254 hxhash_t operator()(const hxexpected<T_, E_>& expected_) const {
255 return expected_.hash();
256 }
257};
258
259#include "detail/hxexpected.inl"
260HX_NS_END_
hxallocator(void)
Definition hxallocator.hpp:35
hxexpected<T, E=bool> - Holds either a value of type T or an error of type E.
Definition hxexpected.hpp:67
const T * operator->(void) const
Returns a const pointer to the contained value.
void reset(void) noexcept
Destroys the contained value and assigns a true error.
T & emplace(args_t_ &&... args_) noexcept
Constructs the contained value in place from args, clearing the error.
E_ error_t
error_t - Publishes the error type.
Definition hxexpected.hpp:74
auto error(this self_t_ &&self_) -> decltype(hxforward_like< self_t_ >(hxdeclval< E_ & >()))
Returns a reference to the error with the constness and value category of self.
hxexpected & operator=(const hxexpected &x_) noexcept
Copy assignment.
bool operator==(const T &value_) const
Returns true if this expected value contains a value equal to value.
void reset(const E_ &error_) noexcept
Changes the error.
T * operator->(void)
~hxexpected(void)
Destroys the contained value if non-null.
void swap(hxexpected &x_) noexcept
Exchanges the values and errors with x.
hxhash_t hash(void) const
Returns the hash of the contained value if non-null, otherwise 31u.
hxexpected(error_t_ &&error_, args_t_ &&... args_) noexcept
Constructs an hxexpected with error.
T & operator*(void)
hxexpected(void)
Default constructs an error using E(true).
Definition hxexpected.hpp:80
hxexpected(hxexpected &&x_) noexcept
Move constructor.
bool equal(const hxexpected &x_) const
Returns true if both expected values contain equal values or equal errors.
T value_or(this self_t_ &&self_, args_t_ &&... args_)
Returns the contained value if non-null, otherwise returns a T constructed from args.
T value_t
value_t - Publishes the contained value type.
Definition hxexpected.hpp:77
hxexpected(hxnil_t)
Constructs an error from hxnil using E(true).
Definition hxexpected.hpp:84
hxexpected(const hxexpected &x_) noexcept
Copy constructor.
bool operator==(hxnil_t) const
Returns true if this expected value contains an error.
Definition hxexpected.hpp:147
hxexpected & operator=(hxnil_t)
Assigns a default error using T(true).
Definition hxexpected.hpp:131
auto and_then(this self_t_ &&self_, callable_t_ &&callable_) -> hxremove_cvref_t< decltype(hxforward< callable_t_ >(callable_)(hxforward_like< self_t_ >(hxdeclval< T & >())))>
Returns the result of calling callable with the contained value when there is no error,...
hxexpected or_else(this self_t_ &&self_, callable_t_ &&callable_)
Returns this expected value if non-null, otherwise returns the result of calling callable.
auto value(this self_t_ &&self_) -> decltype(hxforward_like< self_t_ >(hxdeclval< T & >()))
Returns a reference to the contained value with the constness and value category of self.
const T & operator*(void) const
Returns a const reference to the contained value.
bool operator==(const hxexpected &x_) const
Returns true if both expected values contain equal values or equal errors.
Definition hxexpected.hpp:143
hxexpected & operator=(hxexpected &&x_) noexcept
Move assignment.
bool has_value(void) const
Returns true if the expected value contains a value.
Definition hxexpected.hpp:179
bool operator()(const hxexpected< T, E_ > &x_, const hxexpected< T, E_ > &y_) const
Definition hxexpected.hpp:242
hxkey_equal_t<T> - A constexpr callable that returns true if two objects are equivalent.
Definition hxkey.hpp:57
hxhash_t operator()(const hxexpected< T, E_ > &expected_) const
Definition hxexpected.hpp:254
hxkey_hash_t<T> - A callable that returns the xxhash32 of a numeric value cast to 32 bits.
Definition hxkey.hpp:146
hxnil_t - A class that will only convert to a null T pointer or a null hxhandle_t.
Definition hxutility.h:57
hxsame_as - A concept that requires two types to be the same.
Definition hxutility.h:265
Similar to std::allocator.
hxexpected< T > hxmake_expected(const T &value_)
hxmake_expected<T> - Returns an non-null hxexpected<T> constructed by copying value.
Definition hxexpected.hpp:223
User-specializable key-equal, key-less, and key-hash callables.
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:125
#define HX_CPLUSPLUS
HX_CPLUSPLUS - A version of __cplusplus that is defined to 0 when __cplusplus is undefined.
Definition hxsettings.h:31
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
#define hxattr_flatten
hxattr_flatten - Inline every call inside a function's body into it, recursively, regardless of the c...
Definition hxsettings.h:90
constexpr bool hxis_same(void)
hxis_same<A, B> - Implements std::is_same.
Definition hxutility.h:246
constexpr T && hxforward(hxremove_reference_t< T > &&x_)
hxforward - Implements std::forward.
Definition hxutility.h:353
hxremove_cv_t< hxremove_reference_t< T > > hxremove_cvref_t
hxremove_cvref_t<T> - Returns T with const, volatile, and references removed.
Definition hxutility.h:103
T && hxdeclval(void) noexcept
hxdeclval - Implements std::declval.
constexpr bool hxis_reference(void)
hxis_reference<T> - Implements std::is_reference.
Definition hxutility.h:228
constexpr hxremove_reference_t< T > && hxmove(T &&t_)
hxmove - Implements std::move.
Definition hxutility.h:407
constexpr bool hxis_pointer(void)
hxis_pointer<T> - Implements std::is_pointer.
Definition hxutility.h:216
constexpr hxforward_like_t_< like_t_, value_t_ > hxforward_like(value_t_ &value_)
hxforward_like<T> - Returns value with the constness and value category of T.
Definition hxutility.h:387
Provides core macros, memory management and feature detection.
uint32_t hxhash_t
hxhash_t - Unsigned 32-bit hash value. Expect collisions.
Definition libhatchet.h:210
hxfalse_t - Implements std::false_type.
Definition hxutility.h:112
hxtrue_t - Implements std::true_type.
Definition hxutility.h:110