9#include <boost/optional/optional_fwd.hpp>
11#include <userver/utils/assert.hpp>
13USERVER_NAMESPACE_BEGIN
29 static_assert(!std::is_reference<T>::value,
"Do not use a reference for T");
31 constexpr OptionalRef()
noexcept =
default;
32 constexpr OptionalRef(std::nullopt_t)
noexcept {}
33 constexpr OptionalRef(
const OptionalRef&)
noexcept =
default;
36 constexpr OptionalRef(T& other)
noexcept : data_(&other) {}
39 explicit constexpr OptionalRef(
const T&&) =
delete;
42 explicit constexpr OptionalRef(
const std::optional<U>& other)
noexcept
43 : data_(GetPointer(other)) {}
46 explicit constexpr OptionalRef(std::optional<U>& other)
noexcept
47 : data_(GetPointer(other)) {}
50 explicit constexpr OptionalRef(
const std::optional<U>&&)
noexcept {
51 static_assert(!
sizeof(U),
"Forming a reference to a temporary");
55 explicit constexpr OptionalRef(
const boost::optional<U>& other)
noexcept
56 : data_(GetPointer(other)) {}
59 explicit constexpr OptionalRef(boost::optional<U>& other)
noexcept
60 : data_(GetPointer(other)) {}
63 explicit constexpr OptionalRef(
const boost::optional<U>&&)
noexcept {
64 static_assert(!
sizeof(U),
"Forming a reference to a temporary");
67 constexpr bool has_value()
const noexcept {
return !!data_; }
68 constexpr explicit operator
bool()
const noexcept {
return has_value(); }
70 constexpr T* operator->()
const {
75 constexpr T& operator*()
const {
80 constexpr T& value()
const {
82 throw std::bad_optional_access();
89 template <
class Optional>
90 static T* GetPointer(Optional& other)
noexcept {
91 using ValueType =
decltype(*other);
93 std::is_const<T>::value || !std::is_const<ValueType>::value,
94 "Attempt to initialize non-const T from a const optional value");
100 auto& value = *other;
104 T*
const data_ =
nullptr;
107template <
class T,
class U>
109 if (!lhs || !rhs)
return !lhs && !rhs;
113template <
class T,
class U>
115 return !(lhs == rhs);