9#include <boost/optional/optional_fwd.hpp>
11#include <userver/utils/assert.hpp>
13USERVER_NAMESPACE_BEGIN
31 static_assert(!std::is_reference<T>::value,
"Do not use a reference for T");
33 constexpr OptionalRef()
noexcept =
default;
34 constexpr OptionalRef(std::nullopt_t)
noexcept {}
35 constexpr OptionalRef(
const OptionalRef&)
noexcept =
default;
38 constexpr OptionalRef(T& other)
noexcept : data_(&other) {}
41 explicit constexpr OptionalRef(
const T&&) =
delete;
44 explicit constexpr OptionalRef(
const std::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
47 explicit constexpr OptionalRef(std::optional<U>& other)
noexcept : 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 : data_(GetPointer(other)) {}
58 explicit constexpr OptionalRef(boost::optional<U>& other)
noexcept : data_(GetPointer(other)) {}
61 explicit constexpr OptionalRef(
const boost::optional<U>&&)
noexcept {
62 static_assert(!
sizeof(U),
"Forming a reference to a temporary");
65 constexpr bool has_value()
const noexcept {
return !!data_; }
66 constexpr explicit operator
bool()
const noexcept {
return has_value(); }
68 constexpr T* operator->()
const {
73 constexpr T& operator*()
const {
78 constexpr T& value()
const {
80 throw std::bad_optional_access();
87 constexpr T value_or(U&& default_value)
const {
89 return std::forward<U>(default_value);
96 template <
class Optional>
97 static T* GetPointer(Optional& other)
noexcept {
98 using ValueType =
decltype(*other);
100 std::is_const<T>::value || !std::is_const<ValueType>::value,
101 "Attempt to initialize non-const T from a const optional value"
108 auto& value = *other;
112 T*
const data_ =
nullptr;
115template <
class T,
class U>
123template <
class T,
class U>
125 return !(lhs == rhs);