10#include <userver/formats/parse/to.hpp>
11#include <userver/formats/serialize/to.hpp>
12#include <userver/logging/log_helper_fwd.hpp>
13#include <userver/utils/assert.hpp>
15USERVER_NAMESPACE_BEGIN
21template <
typename Self,
typename... Args>
22inline constexpr bool kArgsAreNotSelf = ((
sizeof...(Args) > 1) || ... || !std::is_same_v<std::decay_t<Args>, Self>);
24template <
bool Condition,
template <
typename...>
typename Trait,
typename... Args>
25constexpr bool ConjunctionWithTrait()
noexcept {
26 if constexpr (Condition) {
27 return Trait<Args...>::value;
65 impl::ConjunctionWithTrait<
68 impl::kArgsAreNotSelf<Box, U>,
82 impl::ConjunctionWithTrait<
85 impl::kArgsAreNotSelf<Box, Args...>,
87 std::is_constructible,
95 template <
typename Factory>
97 return Box(EmplaceFactory{}, std::forward<Factory>(factory));
100 Box(
Box&& other)
noexcept =
default;
101 Box& operator=(
Box&& other)
noexcept =
default;
103 Box(
const Box& other) : data_(std::make_unique<T>(*other)) {}
105 Box& operator=(
const Box& other) {
114 impl::ConjunctionWithTrait<
115 impl::ConjunctionWithTrait<
118 impl::kArgsAreNotSelf<Box, U>,
120 std::is_constructible,
129 *data_ = std::forward<U>(other);
131 data_ = std::make_unique<T>(std::forward<U>(other));
137 operator
bool()
const =
delete;
139 T* operator->()
noexcept {
return Get(); }
140 const T* operator->()
const noexcept {
return Get(); }
142 T& operator*()
noexcept {
return *Get(); }
143 const T& operator*()
const noexcept {
return *Get(); }
145 bool operator==(
const Box& other)
const {
return **
this == *other; }
147 bool operator!=(
const Box& other)
const {
return **
this != *other; }
149 bool operator<(
const Box& other)
const {
return **
this < *other; }
151 bool operator>(
const Box& other)
const {
return **
this > *other; }
153 bool operator<=(
const Box& other)
const {
return **
this <= *other; }
155 bool operator>=(
const Box& other)
const {
return **
this >= *other; }
158 struct EmplaceFactory
final {};
160 template <
typename Factory>
161 explicit Box(EmplaceFactory, Factory&& factory) : data_(
new T(std::forward<Factory>(factory)())) {}
168 const T* Get()
const noexcept {
173 std::unique_ptr<T> data_;
176template <
typename Value,
typename T>
178 return Box<T>::MakeWithFactory([&value] {
return value.
template As<T>(); });
181template <
typename Value,
typename T>
186template <
typename StringBuilder,
typename T>
187void WriteToStream(
const Box<T>& value, StringBuilder& sw) {
188 WriteToStream(*value, sw);