35 static_assert(!std::is_reference<T>::value,
"Do not use a reference for T");
37 constexpr OptionalRef()
noexcept =
default;
38 constexpr OptionalRef(std::nullopt_t)
noexcept {}
39 constexpr OptionalRef(
const OptionalRef&)
noexcept =
default;
42 constexpr OptionalRef(T& other)
noexcept : data_(std::addressof(other)) {}
45 constexpr explicit OptionalRef(
const T&&) =
delete;
48 constexpr explicit OptionalRef(
const std::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
51 constexpr explicit OptionalRef(std::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
54 constexpr explicit OptionalRef(
const std::optional<U>&&)
noexcept {
55 static_assert(!
sizeof(U),
"Forming a reference to a temporary");
59 constexpr explicit OptionalRef(
const boost::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
62 constexpr explicit OptionalRef(boost::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
65 constexpr explicit OptionalRef(
const boost::optional<U>&&)
noexcept {
66 static_assert(!
sizeof(U),
"Forming a reference to a temporary");
69 constexpr bool has_value()
const noexcept {
return !!data_; }
70 constexpr explicit operator
bool()
const noexcept {
return has_value(); }
72 constexpr T* operator->()
const {
77 constexpr T& operator*()
const {
82 constexpr T& value()
const {
84 throw std::bad_optional_access();
91 constexpr T value_or(U&& default_value)
const {
93 return std::forward<U>(default_value);
100 constexpr auto and_then(F&& function)
const -> std::remove_cvref_t<std::invoke_result_t<F, T&>> {
101 using Result = std::remove_cvref_t<std::invoke_result_t<F, T&>>;
103 meta::IsInstantiationOf<Result, std::optional> ||
meta::IsInstantiationOf<Result,
OptionalRef>,
104 "The function passed to and_then must return std::optional or utils::OptionalRef"
108 return std::invoke(std::forward<F>(function), *data_);
113 template <
typename F>
114 constexpr auto transform(F&& function)
const {
115 using Result = std::remove_cv_t<std::invoke_result_t<F, T&>>;
118 return std::optional<Result>{std::invoke(std::forward<F>(function), *data_)};
120 return std::optional<Result>{};
123 template <
typename F>
124 constexpr OptionalRef or_else(F&& function)
const {
125 using Result = std::remove_cvref_t<std::invoke_result_t<F>>;
128 "The function passed to or_else must return utils::OptionalRef<T>"
134 return std::invoke(std::forward<F>(function));
138 template <
class Optional>
139 static T* GetPointer(Optional& other)
noexcept {
140 using ValueType =
decltype(*other);
142 std::is_const<T>::value || !std::is_const<ValueType>::value,
143 "Attempt to initialize non-const T from a const optional value"
146 return other.has_value() ? std::addressof(*other) :
nullptr;
149 T*
const data_ =
nullptr;