24 #ifndef PSTORE_SUPPORT_MAYBE_HPP 25 #define PSTORE_SUPPORT_MAYBE_HPP 41 using type =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
44 using remove_cvref_t =
typename remove_cvref<T>::type;
48 template <typename T, typename = typename std::enable_if<!std::is_reference<T>::value>::type>
53 static_assert (std::is_object<value_type>::value,
54 "Instantiation of maybe<> with a non-object type is undefined behavior.");
55 static_assert (std::is_nothrow_destructible<value_type>::value,
56 "Instantiation of maybe<> with an object type that is not noexcept " 57 "destructible is undefined behavior.");
60 constexpr
maybe () noexcept =
default;
65 typename =
typename std::enable_if<
66 std::is_constructible<T, U &&>::value &&
67 !std::is_same<typename details::remove_cvref_t<U>,
maybe<T>>::value>::type>
68 explicit maybe (U && value) noexcept (std::is_nothrow_move_constructible<T>::value &&
69 std::is_nothrow_copy_constructible<T>::value &&
70 !std::is_convertible<U &&, T>::value)
73 new (&storage_) T (std::forward<U> (value));
76 template <
typename... Args>
80 new (&storage_) T (std::forward<Args> (args)...);
86 maybe (maybe
const & other) noexcept (std::is_nothrow_copy_constructible<T>::value) {
88 new (&storage_) T (*other);
97 maybe (maybe && other) noexcept (std::is_nothrow_move_constructible<T>::value) {
99 new (&storage_) T (std::move (*other));
104 ~maybe () noexcept { this->reset (); }
111 reinterpret_cast<T
const *
> (&storage_)->~T ();
115 maybe & operator= (maybe
const & other) noexcept (
116 std::is_nothrow_copy_assignable<T>::value &&
117 std::is_nothrow_copy_constructible<T>::value) {
118 if (&other !=
this) {
122 this->operator= (other.value ());
129 operator= (maybe && other) noexcept (std::is_nothrow_move_assignable<T>::value &&
130 std::is_nothrow_move_constructible<T>::value) {
132 if (&other !=
this) {
136 this->operator= (std::forward<T> (other.value ()));
143 template <
typename U,
144 typename =
typename std::enable_if<
145 std::is_constructible<T, U &&>::value &&
146 !std::is_same<typename details::remove_cvref_t<U>,
maybe<T>>::value>::type>
147 maybe & operator= (U && other) noexcept (
148 std::is_nothrow_copy_assignable<T>::value && std::is_nothrow_copy_constructible<
149 T>::value && std::is_nothrow_move_assignable<T>::value &&
150 std::is_nothrow_move_constructible<T>::value) {
153 T temp = std::forward<U> (other);
154 std::swap (this->value (), temp);
156 new (&storage_) T (std::forward<U> (other));
167 template <
typename... Args>
170 T temp (std::forward<Args> (args)...);
171 std::swap (this->value (), temp);
173 new (&storage_) T (std::forward<Args> (args)...);
176 return this->value ();
179 bool operator== (maybe
const & other)
const {
180 return this->has_value () == other.
has_value () &&
181 (!this->has_value () || this->value () == other.value ());
183 bool operator!= (maybe
const & other)
const {
return !operator== (other); }
186 T
const & operator* () const noexcept {
return *(operator-> ()); }
188 T & operator* () noexcept {
return *(operator-> ()); }
190 T
const * operator-> () const noexcept {
191 PSTORE_ASSERT (valid_);
192 return reinterpret_cast<T
const *
> (&storage_);
195 T * operator-> () noexcept {
196 PSTORE_ASSERT (valid_);
197 return reinterpret_cast<T *
> (&storage_);
201 constexpr
explicit operator bool () const noexcept {
return valid_; }
203 constexpr
bool has_value () const noexcept {
return valid_; }
205 T
const & value ()
const noexcept {
return value_impl (*
this); }
206 T & value () noexcept {
return value_impl (*
this); }
208 template <
typename U>
209 constexpr T value_or (U && default_value)
const {
210 return this->has_value () ? this->value () : default_value;
214 template <typename Maybe, typename ResultType = typename inherit_const<Maybe, T>::type>
215 static ResultType & value_impl (Maybe && m) noexcept {
216 PSTORE_ASSERT (m.has_value ());
221 typename std::aligned_storage<sizeof (T), alignof (T)>::type storage_;
227 template <
typename T>
228 constexpr decltype (
auto) just (T && value) {
232 template <
typename T,
typename... Args>
233 constexpr decltype (
auto) just (
in_place_t const inp, Args &&... args) {
240 template <
typename T>
241 constexpr decltype (
auto) nothing () noexcept {
251 template <
typename T,
typename Function>
252 auto operator>>= (
maybe<T> && t, Function f) -> decltype (f (*t)) {
261 #endif // PSTORE_SUPPORT_MAYBE_HPP
Provides definitions needed by the code that are available in C++17 <utility>.
maybe(maybe &&other) noexcept(std::is_nothrow_move_constructible< T >::value)
Move constructor: If other contains a value, initializes the contained value with the expression std:...
Definition: maybe.hpp:97
maybe(U &&value) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_copy_constructible< T >::value &&!std::is_convertible< U &&, T >::value)
Constructs an optional object that contains a value, initialized with the expression std::forward<U>(...
Definition: maybe.hpp:68
constexpr bool has_value() const noexcept
checks whether the object contains a value
Definition: maybe.hpp:203
A utility template intended to simplify the writing of the const- and non-const variants of member fu...
maybe(maybe const &other) noexcept(std::is_nothrow_copy_constructible< T >::value)
Copy constructor: If other contains a value, initializes the contained value with the expression *oth...
Definition: maybe.hpp:86
Definition: utility.hpp:24
Definition: nonpod2.cpp:40
void reset() noexcept
If *this contains a value, destroy it. *this does not contain a value after this call.
Definition: maybe.hpp:107
An implementation of the standard assert() macro with the exception that it will, on failure...
T & emplace(Args &&... args)
Constructs the contained value in-place.
Definition: maybe.hpp:168