userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
value.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/formats/yaml/value.hpp
4
/// @brief @copybrief formats::yaml::Value
5
6
#
include
<
type_traits
>
7
8
#
include
<
userver
/
formats
/
common
/
items
.
hpp
>
9
#
include
<
userver
/
formats
/
common
/
meta
.
hpp
>
10
#
include
<
userver
/
formats
/
parse
/
common
.
hpp
>
11
#
include
<
userver
/
formats
/
yaml
/
exception
.
hpp
>
12
#
include
<
userver
/
formats
/
yaml
/
iterator
.
hpp
>
13
#
include
<
userver
/
formats
/
yaml
/
types
.
hpp
>
14
#
include
<
userver
/
utils
/
fast_pimpl
.
hpp
>
15
16
USERVER_NAMESPACE_BEGIN
17
18
namespace
formats::
yaml
{
19
20
class
ValueBuilder;
21
22
namespace
impl {
23
formats::
yaml
::Value FromStringAllowRepeatedKeys(
const
std::string& doc);
24
}
// namespace impl
25
26
/// @ingroup userver_universal userver_containers userver_formats
27
///
28
/// @brief Non-mutable YAML value representation.
29
///
30
/// Class provides non mutable access YAML value. For modification and
31
/// construction of new YAML values use formats::yaml::ValueBuilder.
32
///
33
/// ## Example usage:
34
///
35
/// @snippet formats/yaml/value_test.cpp Sample formats::yaml::Value usage
36
///
37
/// @see @ref scripts/docs/en/userver/formats.md
38
///
39
/// To iterate over `Value` as object use formats::common::Items.
40
class
Value
final
{
41
public
:
42
struct
IterTraits
{
43
using
native_iter = YAML::const_iterator;
44
using
value_type = formats::
yaml
::Value;
45
using
reference =
const
formats::
yaml
::Value&;
46
using
pointer =
const
formats::
yaml
::Value*;
47
};
48
struct
DefaultConstructed
{};
49
50
using
const_iterator = Iterator<
IterTraits
>;
51
using
Exception = formats::
yaml
::
Exception
;
52
using
ParseException = formats::
yaml
::
ParseException
;
53
using
ExceptionWithPath = formats::
yaml
::
ExceptionWithPath
;
54
using
Builder = ValueBuilder;
55
56
/// @brief Constructs a Value that holds a Null.
57
Value
()
noexcept
;
58
59
// NOLINTNEXTLINE(performance-noexcept-move-constructor)
60
Value(Value&&);
61
Value(
const
Value&);
62
// NOLINTNEXTLINE(performance-noexcept-move-constructor)
63
Value& operator=(Value&&);
64
Value& operator=(
const
Value&);
65
66
template
<
class
T>
67
Value& operator=(T&&) && {
68
static_assert
(
69
!
sizeof
(T),
70
"You're assigning to a temporary formats::yaml::Value! Use "
71
"formats::yaml::ValueBuilder for data modifications."
72
);
73
return
*
this
;
74
}
75
76
~Value();
77
78
/// @brief Copies `other`, appending `path_prefix` to the stored `path`
79
/// @warning `other` must have an empty (root) path
80
/// @throw `std::logic_error` if `other` has path other than the root path
81
/// @see GetPath
82
Value
(Value&& other, std::string path_prefix);
83
84
/// @brief Access member by key for read.
85
/// @throw TypeMismatchException if not a missing value, an object, or Null.
86
Value
operator
[](std::string_view key)
const
;
87
88
/// @brief Access array member by index for read.
89
/// @throw TypeMismatchException if not an array value.
90
/// @throw `OutOfBoundsException` if index is greater or equal
91
/// than size.
92
Value
operator
[](std::size_t index)
const
;
93
94
/// @brief Returns an iterator to the beginning of the held array or map.
95
/// @throw TypeMismatchException if not an array or an object.
96
const_iterator
begin
()
const
;
97
98
/// @brief Returns an iterator to the end of the held array or map.
99
/// @throw TypeMismatchException if not an array or an object.
100
const_iterator
end
()
const
;
101
102
/// @brief Returns whether the array or object is empty.
103
/// @throw TypeMismatchException if not an array or an object.
104
bool
IsEmpty
()
const
;
105
106
/// @brief Returns array size or object members count.
107
/// @throw TypeMismatchException if not an array or an object.
108
std::size_t
GetSize
()
const
;
109
110
/// @brief Compares values.
111
/// @throw MemberMissingException if `*this` or `other` is missing.
112
bool
operator
==(
const
Value& other)
const
;
113
114
/// @brief Returns true if *this holds nothing. When `IsMissing()` returns
115
/// `true` any attempt to get the actual value or iterate over *this will
116
/// throw MemberMissingException.
117
bool
IsMissing
()
const
;
118
119
/// @brief Returns true if *this holds a Null (Type::kNull).
120
bool
IsNull
()
const
noexcept
;
121
122
/// @brief Returns true if *this is convertible to bool.
123
bool
IsBool
()
const
noexcept
;
124
125
/// @brief Returns true if *this is convertible to int.
126
bool
IsInt
()
const
noexcept
;
127
128
/// @brief Returns true if *this is convertible to int64_t.
129
bool
IsInt64
()
const
noexcept
;
130
131
/// @brief Returns true if *this is convertible to uint64_t.
132
bool
IsUInt64
()
const
noexcept
;
133
134
/// @brief Returns true if *this is convertible to double.
135
bool
IsDouble
()
const
noexcept
;
136
137
/// @brief Returns true if *this is convertible to std::string.
138
bool
IsString
()
const
noexcept
;
139
140
/// @brief Returns true if *this is an array (Type::kArray).
141
bool
IsArray
()
const
noexcept
;
142
143
/// @brief Returns true if *this is a map (Type::kObject).
144
bool
IsObject
()
const
noexcept
;
145
146
/// @brief Returns value of *this converted to the result type of
147
/// Parse(const Value&, parse::To<T>). Almost always it is T.
148
/// @throw Anything derived from std::exception.
149
///
150
/// ## Example usage:
151
///
152
/// @snippet formats/yaml/value_test.cpp Sample formats::yaml::Value::As<T>() usage
153
///
154
/// @see @ref scripts/docs/en/userver/formats.md
155
template
<
typename
T>
156
auto
As
()
const
;
157
158
/// @brief Returns value of *this converted to T or T(args) if
159
/// this->IsMissing().
160
/// @throw Anything derived from std::exception.
161
template
<
typename
T,
typename
First,
typename
... Rest>
162
auto
As
(First&& default_arg, Rest&&... more_default_args)
const
;
163
164
/// @brief Returns value of *this converted to T or T() if this->IsMissing().
165
/// @throw Anything derived from std::exception.
166
/// @note Use as `value.As<T>({})`
167
template
<
typename
T>
168
auto
As
(
DefaultConstructed
)
const
;
169
170
/// @brief Returns true if *this holds a `key`.
171
bool
HasMember
(std::string_view key)
const
;
172
173
/// @brief Returns full path to this value.
174
std::string
GetPath
()
const
;
175
176
/// @brief Returns 0-based column number of this `Value` in the original
177
/// document. Returns `-1` if `this->IsMissing()`. If `Value` was created
178
/// using formats::yaml::ValueBuilder, returns `0`.
179
/// @note This method available **only** for formats::yaml::Value.
180
int
GetColumn
()
const
;
181
182
/// @brief Returns 0-based line number of this `Value` in the original
183
/// document. Returns `-1` if `this->IsMissing()`. If `Value` was created
184
/// using formats::yaml::ValueBuilder, returns `0`.
185
/// @note This method available **only** for formats::yaml::Value.
186
int
GetLine
()
const
;
187
188
/// @brief Returns YAML tag of this node.
189
/// If tag is not explicitly specified, its value depends on node value. For
190
/// explicitly specified tags, its value depends on used `TAG` directives and
191
/// node value. There is an implicit `TAG` derictive for `!!` with prefix
192
/// `tag:yaml.org,2002:`.
193
///
194
/// For example:
195
/// - `""` if field is null, even when tag is specified
196
/// - `"!"` for quoted and block strings if tag is not specified
197
/// - `"?"` for other fields if tag is not specified
198
/// - `"tag:yaml.org,2002:str"` for `!!str` tag
199
/// - `"!!str"` for `!<!!str>` tag
200
/// - `"!custom_tag"` for `!custom_tag` tag, if no additional `TAG` directives
201
/// are specified
202
///
203
/// For details see YAML specification.
204
/// @throws MemberMissingException if `this->IsMissing()`.
205
/// @note This method available **only** for formats::yaml::Value.
206
std::string_view
GetTag
()
const
;
207
208
/// @brief Returns new value that is an exact copy if the existing one
209
/// but references different memory (a deep copy of a *this). The returned
210
/// value is a root value with path '/'.
211
/// @throws MemberMissingException if `this->IsMissing()`.
212
Value
Clone
()
const
;
213
214
/// @throw MemberMissingException if `this->IsMissing()`.
215
void
CheckNotMissing
()
const
;
216
217
/// @throw MemberMissingException if `*this` is not an array.
218
void
CheckArray
()
const
;
219
220
/// @throw MemberMissingException if `*this` is not an array or Null.
221
void
CheckArrayOrNull
()
const
;
222
223
/// @throw TypeMismatchException if `*this` is not a map or Null.
224
void
CheckObjectOrNull
()
const
;
225
226
/// @throw TypeMismatchException if `*this` is not a map.
227
void
CheckObject
()
const
;
228
229
/// @throw TypeMismatchException if `*this` is not convertible to std::string.
230
void
CheckString
()
const
;
231
232
/// @throw TypeMismatchException if `*this` is not a map, array or Null.
233
void
CheckObjectOrArrayOrNull
()
const
;
234
235
/// @throw TypeMismatchException if `*this` is not a map, array or Null;
236
/// `OutOfBoundsException` if `index >= this->GetSize()`.
237
void
CheckInBounds
(std::size_t index)
const
;
238
239
/// @brief Returns true if *this is a first (root) value.
240
bool
IsRoot
()
const
noexcept
;
241
242
/// @brief Returns true if `*this` and `other` reference the value by the same
243
/// pointer.
244
bool
DebugIsReferencingSameMemory
(
const
Value& other)
const
;
245
246
private
:
247
class
EmplaceEnabler {};
248
249
public
:
250
/// @cond
251
Value(EmplaceEnabler,
const
YAML::Node& value,
const
formats::
yaml
::Path& path, std::string_view key);
252
253
Value(EmplaceEnabler,
const
YAML::Node& value,
const
formats::
yaml
::Path& path, size_t index);
254
255
Value CloneWithReplacedPath(std::string&& new_path)
const
;
256
/// @endcond
257
258
private
:
259
Value(
const
YAML::Node& root)
noexcept
;
260
261
static
Value MakeNonRoot(
const
YAML::Node& value,
const
formats::
yaml
::Path& path, std::string_view key);
262
static
Value MakeNonRoot(
const
YAML::Node& val,
const
formats::
yaml
::Path& path, size_t index);
263
264
const
YAML::Node& GetNative()
const
;
265
YAML::Node& GetNative();
266
int
GetExtendedType()
const
;
267
268
template
<
class
T>
269
bool
IsConvertibleToArithmetic()
const
;
270
271
template
<
class
T>
272
T ValueAsArithmetic()
const
;
273
274
static
constexpr
std::size_t kNativeNodeSize = 64;
275
static
constexpr
std::size_t kNativeAlignment =
alignof
(
void
*);
276
277
utils
::FastPimpl<YAML::Node, kNativeNodeSize, kNativeAlignment> value_pimpl_;
278
formats::
yaml
::Path path_;
279
280
friend
class
Iterator<
IterTraits
>;
281
friend
class
ValueBuilder;
282
283
friend
bool
Parse(
const
Value& value,
parse
::
To
<
bool
>);
284
friend
int64_t Parse(
const
Value& value,
parse
::
To
<int64_t>);
285
friend
uint64_t Parse(
const
Value& value,
parse
::
To
<uint64_t>);
286
friend
double
Parse(
const
Value& value,
parse
::
To
<
double
>);
287
friend
std::string Parse(
const
Value& value,
parse
::
To
<std::string>);
288
289
friend
formats::
yaml
::Value
FromString
(
const
std::string&);
290
friend
formats::
yaml
::Value
FromStream
(std::istream&);
291
friend
void
Serialize
(
const
formats::
yaml
::Value&, std::ostream&);
292
friend
formats::
yaml
::Value impl::FromStringAllowRepeatedKeys(
const
std::string& doc);
293
};
294
295
template
<
typename
T>
296
auto
Value::
As
()
const
{
297
static_assert
(
298
formats::common::impl::HasParse<Value, T>,
299
"There is no `Parse(const Value&, formats::parse::To<T>)` in namespace of `T` or `formats::parse`. "
300
"Probably you forgot to include the <userver/formats/parse/common_containers.hpp> or you "
301
"have not provided a `Parse` function overload."
302
);
303
304
return
Parse(*
this
, formats::
parse
::
To
<T>{});
305
}
306
307
bool
Parse(
const
Value& value,
parse
::
To
<
bool
>);
308
309
int64_t Parse(
const
Value& value,
parse
::
To
<int64_t>);
310
311
uint64_t Parse(
const
Value& value,
parse
::
To
<uint64_t>);
312
313
double
Parse(
const
Value& value,
parse
::
To
<
double
>);
314
315
std::string Parse(
const
Value& value,
parse
::
To
<std::string>);
316
317
template
<
typename
T,
typename
First,
typename
... Rest>
318
auto
Value::
As
(First&& default_arg, Rest&&... more_default_args)
const
{
319
if
(
IsMissing
(
)
||
IsNull
(
)
) {
320
// intended raw ctor call, sometimes casts
321
// NOLINTNEXTLINE(google-readability-casting)
322
return
decltype
(As<T>())(std::forward<First>(default_arg), std::forward<Rest>(more_default_args)...);
323
}
324
return
As<T>();
325
}
326
327
template
<
typename
T>
328
auto
Value::
As
(Value::
DefaultConstructed
)
const
{
329
return
(
IsMissing
(
)
||
IsNull
(
)
) ?
decltype
(As<T>())() : As<T>();
330
}
331
332
/// @brief Wrapper for handy python-like iteration over a map
333
///
334
/// @snippet universal/src/formats/common/items_test.cpp Items const iteration
335
using
formats::common::Items;
336
337
}
// namespace formats::yaml
338
339
/// Although we provide user defined literals, please beware that
340
/// 'using namespace ABC' may contradict code style of your company.
341
namespace
formats::
literals
{
342
343
yaml
::Value operator
""_yaml
(
const
char
* str, std::size_t len);
344
345
}
// namespace formats::literals
346
347
USERVER_NAMESPACE_END
userver
formats
yaml
value.hpp
Generated on
for userver by
Doxygen
1.17.0