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);