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>
23 : std::bool_constant<((
sizeof...(Args) > 1) || ... ||
24 !std::is_same_v<std::decay_t<Args>, Self>)> {};
55 template <
typename U = T,
56 std::enable_if_t<std::conjunction_v<
59 impl::ArgsAreNotSelf<Box, U>,
63 std::is_convertible<U&&, T>>,
69 template <
typename... Args,
70 std::enable_if_t<std::conjunction_v<
73 impl::ArgsAreNotSelf<Box, Args...>,
75 std::is_constructible<T, Args&&...>>,
77 explicit Box(Args&&... args)
82 template <
typename Factory>
84 return Box(EmplaceFactory{}, std::forward<Factory>(factory));
87 Box(
Box&& other)
noexcept =
default;
88 Box& operator=(
Box&& other)
noexcept =
default;
90 Box(
const Box& other) : data_(std::make_unique<T>(*other)) {}
92 Box& operator=(
const Box& other) {
98 template <
typename U = T, std::enable_if_t<std::conjunction_v<
101 impl::ArgsAreNotSelf<Box, U>,
103 std::is_constructible<T, U>,
104 std::is_assignable<T&, U>>,
108 *data_ = std::forward<U>(other);
110 data_ = std::make_unique<T>(std::forward<U>(other));
116 operator
bool()
const =
delete;
118 T* operator->()
noexcept {
return Get(); }
119 const T* operator->()
const noexcept {
return Get(); }
121 T& operator*()
noexcept {
return *Get(); }
122 const T& operator*()
const noexcept {
return *Get(); }
124 bool operator==(
const Box& other)
const {
return **
this == *other; }
126 bool operator!=(
const Box& other)
const {
return **
this != *other; }
128 bool operator<(
const Box& other)
const {
return **
this < *other; }
130 bool operator>(
const Box& other)
const {
return **
this > *other; }
132 bool operator<=(
const Box& other)
const {
return **
this <= *other; }
134 bool operator>=(
const Box& other)
const {
return **
this >= *other; }
137 struct EmplaceFactory
final {};
139 template <
typename Factory>
140 explicit Box(EmplaceFactory, Factory&& factory)
141 : data_(
new T(std::forward<Factory>(factory)())) {}
148 const T* Get()
const noexcept {
153 std::unique_ptr<T> data_;
156template <
typename Value,
typename T>
157Box<T> Parse(
const Value& value, formats::
parse::
To<
Box<T>>) {
158 return Box<T>::MakeWithFactory([&value] {
return value.
template As<T>(); });
161template <
typename Value,
typename T>
162Value Serialize(
const Box<T>& value, formats::
serialize::
To<Value>) {
163 return Serialize(*value, formats::
serialize::
To<Value>{});
166template <
typename StringBuilder,
typename T>
167void WriteToStream(
const Box<T>& value, StringBuilder& sw) {
168 WriteToStream(*value, sw);