userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
required.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/utils/required.hpp
4
/// @brief @copybrief utils::Required
5
6
#
include
<
concepts
>
7
#
include
<
memory
>
8
#
include
<
string_view
>
9
#
include
<
type_traits
>
10
#
include
<
utility
>
11
12
#
include
<
userver
/
compiler
/
impl
/
lifetime
.
hpp
>
13
14
USERVER_NAMESPACE_BEGIN
15
16
namespace
utils
{
17
18
/// @brief A wrapper that holds a value of type `T` and has no default
19
/// constructor, forcing explicit initialization.
20
///
21
/// Unlike `std::optional`, `Required` is always engaged after construction.
22
/// It is useful for struct fields that must be explicitly set.
23
///
24
/// ## Example usage
25
///
26
/// @snippet utils/required_test.cpp sample
27
///
28
/// @snippet utils/required_test.cpp sample usage
29
template
<
typename
T>
30
class
Required final {
31
public
:
32
Required() =
delete
;
33
34
/// @brief Construct `T` from a value (conditionally explicit).
35
template
<
typename
U>
36
requires
(!std::same_as<std::decay_t<U>, Required> && std::constructible_from<T, U &&>)
37
constexpr
explicit
(!
std
::
convertible_to
<
U
&&,
T
>)
Required
(U&& value)
38
: value_(std::forward<U>(value))
39
{}
40
41
/// @brief Emplace-construct `T` from `args`.
42
template
<
typename
... Args>
43
requires
(
sizeof
...(Args) >= 2 && std::constructible_from<T, Args && ...>)
44
constexpr
explicit
Required
(Args&&... args)
45
: value_(std::forward<Args>(args)...)
46
{}
47
48
Required(
const
Required&) =
default
;
49
Required& operator=(
const
Required&) =
default
;
50
Required(Required&&) =
default
;
51
Required& operator=(Required&&) =
default
;
52
53
/// @brief Access the contained value.
54
constexpr
T&
operator
*() &
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
value_; }
55
56
/// @overload
57
constexpr
const
T&
operator
*()
const
&
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
value_; }
58
59
/// @overload
60
constexpr
T&&
operator
*() &&
noexcept
{
return
std::move(value_); }
61
62
/// @brief Access members of the contained value.
63
constexpr
T*
operator
->()
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
std::addressof(value_); }
64
65
/// @overload
66
constexpr
const
T*
operator
->()
const
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
std::addressof(value_); }
67
68
/// @brief Implicit conversion to `T&`.
69
constexpr
/*implicit*/
operator
T&() &
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
value_; }
70
71
/// @brief Implicit conversion to `const T&`.
72
constexpr
/*implicit*/
operator
const
T&()
const
&
noexcept
USERVER_IMPL_LIFETIME_BOUND {
return
value_; }
73
74
/// @brief Implicit conversion to any type that `T` is implicitly convertible to (by value).
75
template
<
typename
U>
76
requires
(!std::same_as<U, T> && !std::is_reference_v<U> && std::convertible_to<
const
T&, U>)
77
constexpr
/*implicit*/
operator
U()
const
{
78
return
value_;
79
}
80
81
private
:
82
T value_;
83
};
84
85
/// @brief Convert `Required<T>` to `std::string_view` via ADL-found `ToStringView` on the inner value.
86
///
87
/// Participates in overload resolution only when `ToStringView(*req)` is valid.
88
template
<
typename
T>
89
requires
requires
(
const
T& v) {
90
{
91
ToStringView(v)
92
} -> std::same_as<std::string_view>;
93
}
94
std::string_view
ToStringView
(
const
Required<T>& req) {
95
return
ToStringView(*req);
96
}
97
98
}
// namespace utils
99
100
USERVER_NAMESPACE_END
userver
utils
required.hpp
Generated on
for userver by
Doxygen
1.17.0