rapidyaml 0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches

These functions are used by the parser and emitter to convert scalars to and from chars. More...

Functions

bool c4::yml::scalar_is_null (csubstr s) noexcept
 YAML-sense query of nullity.
bool c4::yml::scalar_is_plain_number_json (csubstr s) noexcept
 JSON-sense query of plain number.
bool c4::yml::scalar_is_inf3 (const char *s) noexcept
 Query if a scalar is inf (inf, Inf, INF).
bool c4::yml::scalar_is_nan3 (const char *s) noexcept
 Query if a scalar is nan (nan, NaN, Nan, NAN).
bool c4::yml::scalar_is_inf_or_nan3 (const char *s) noexcept
 Same as scalar_is_inf3() || scalar_is_nan3().
bool c4::yml::scalar_is_special_json (csubstr s) noexcept
 Query if a scalar is plain, eg, true, false, null, +-.inf or .nan.
template<class T>
bool c4::yml::from_chars_float (csubstr scalar, T *val) RYML_NOEXCEPT
 Deserialize a floating point from string.
template<class T>
size_t c4::yml::to_chars_float (substr buf, T val) RYML_NOEXCEPT
 Serialize a floating point value to a string.
template<class T>
bool c4::yml::from_chars_integral (csubstr scalar, T *val) RYML_NOEXCEPT
 Deserialize an integral scalar.
template<class T>
bool c4::yml::scalar_deserialize (csubstr str, T *val)
 Deserialize a scalar from its string representation, dispatching to one of from_chars(), from_chars_float() or from_chars_integral() as appropriate.
template<class T>
size_t c4::yml::scalar_serialize (substr buf, T const &a)
 Serialize a scalar to the buffer, dispatching to to_chars() or to_chars_float() as appropriate.

Detailed Description

These functions are used by the parser and emitter to convert scalars to and from chars.

Function Documentation

◆ scalar_is_null()

bool c4::yml::scalar_is_null ( csubstr s)
inlinenoexcept

YAML-sense query of nullity.

returns true if the scalar points to nullptr or is otherwise equal to one of the strings "~","null","Null","NULL"

Definition at line 28 of file scalar_charconv.hpp.

29{
30 return s.str == nullptr ||
31 (s.len == 1 && (s.str[0] == '~')) ||
32 (s.len == 4 && ((0 == memcmp("null", s.str, 4))
33 || (0 == memcmp("Null", s.str, 4))
34 || (0 == memcmp("NULL", s.str, 4))));
35}
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

Referenced by c4::yml::Tree::key_is_null(), sample_empty_null_values(), and c4::yml::Tree::val_is_null().

◆ scalar_is_plain_number_json()

bool c4::yml::scalar_is_plain_number_json ( csubstr s)
inlinenoexcept

JSON-sense query of plain number.

Definition at line 39 of file scalar_charconv.hpp.

40{
41 return s.is_number()
42 &&
43 (
44 // quote integral numbers if they have a leading 0
45 // https://github.com/biojppm/rapidyaml/issues/291
46 (!(s.len > 1 && s.begins_with('0')))
47 // do not quote reals with leading 0
48 // https://github.com/biojppm/rapidyaml/issues/313
49 || (s.find('.') != csubstr::npos)
50 );
51}
bool begins_with(const C c) const noexcept
true if the first character of the string is c
Definition substr.hpp:850
size_t find(const C c, size_t start_pos=0) const
Definition substr.hpp:713
bool is_number() const
Definition substr.hpp:1216

Referenced by scalar_style_choose_json().

◆ scalar_is_inf3()

bool c4::yml::scalar_is_inf3 ( const char * s)
inlinenoexcept

Query if a scalar is inf (inf, Inf, INF).

Warning
length must be 3

Definition at line 57 of file scalar_charconv.hpp.

58{
59 switch(s[0])
60 {
61 case 'i': return ((s[1] == 'n') && (s[2] == 'f'));
62 case 'I': return ((s[1] == 'n') && (s[2] == 'f')) ||
63 ((s[1] == 'N') && (s[2] == 'F'));
64 }
65 return false;
66}

Referenced by scalar_is_special_json().

◆ scalar_is_nan3()

bool c4::yml::scalar_is_nan3 ( const char * s)
inlinenoexcept

Query if a scalar is nan (nan, NaN, Nan, NAN).

Warning
length must be 3

Definition at line 72 of file scalar_charconv.hpp.

73{
74 switch(s[0])
75 {
76 case 'n': return ((s[1] == 'a') && (s[2] == 'n'));
77 case 'N': return ((s[1] == 'a') && (s[2] == 'N')) ||
78 ((s[1] == 'a') && (s[2] == 'n')) ||
79 ((s[1] == 'A') && (s[2] == 'N'));
80 }
81 return false;
82}

◆ scalar_is_inf_or_nan3()

bool c4::yml::scalar_is_inf_or_nan3 ( const char * s)
inlinenoexcept

Same as scalar_is_inf3() || scalar_is_nan3().

Warning
length must be 3

Definition at line 88 of file scalar_charconv.hpp.

89{
90 switch(s[0])
91 {
92 case 'i': return ((s[1] == 'n') && (s[2] == 'f'));
93 case 'I': return ((s[1] == 'n') && (s[2] == 'f')) ||
94 ((s[1] == 'N') && (s[2] == 'F'));
95 case 'n': return ((s[1] == 'a') && (s[2] == 'n'));
96 case 'N': return ((s[1] == 'a') && (s[2] == 'N')) ||
97 ((s[1] == 'a') && (s[2] == 'n')) ||
98 ((s[1] == 'A') && (s[2] == 'N'));
99 }
100 return false;
101}

Referenced by scalar_is_special_json().

◆ scalar_is_special_json()

bool c4::yml::scalar_is_special_json ( csubstr s)
inlinenoexcept

Query if a scalar is plain, eg, true, false, null, +-.inf or .nan.

Definition at line 105 of file scalar_charconv.hpp.

106{
107 if(s.len == 4)
108 return 0 == memcmp("true", s.str, 4)
109 || 0 == memcmp("null", s.str, 4)
110 || ((s[0] == '.') && scalar_is_inf_or_nan3(s.str + 1))
111 || ((s[0] == '-' || s[0] == '+') && scalar_is_inf3(s.str + 1));
112 else if(s.len == 5)
113 return 0 == memcmp("false", s.str, 5)
114 || ((s[0] == '-' || s[0] == '+') && s[1] == '.' && scalar_is_inf3(s.str + 2));
115 else if(s.len == 3)
116 return scalar_is_inf_or_nan3(s.str);
117 return false;
118}
bool scalar_is_inf_or_nan3(const char *s) noexcept
Same as scalar_is_inf3() || scalar_is_nan3().
bool scalar_is_inf3(const char *s) noexcept
Query if a scalar is inf (inf, Inf, INF).

Referenced by scalar_style_choose_json().

◆ from_chars_float()

template<class T>
bool c4::yml::from_chars_float ( csubstr scalar,
T * val )

Deserialize a floating point from string.

Accepts special values: .nan, .inf, -.inf, with upper-case variations.

Unlike non-floating types, only the leading part of the string that may constitute a number is processed. This happens because the float parsing is delegated to fast_float, which is implemented that way. Consequently, for example, all of "34", "34 " "34hg" "34 gh" will be read as 34. If you are not sure about the contents of the data, you can use csubstr::first_real_span() to check before deserializing, for example like this:

csubstr val = node.val();
if(val.first_real_span() == val)
node >> v; // or call from_chars_float(val, &v);
else
ERROR("not a real")
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
basic_substring first_real_span() const
get the first span which can be interpreted as a real (floating-point) number
Definition substr.hpp:1364

Definition at line 183 of file scalar_charconv.hpp.

184{
185 static_assert(std::is_floating_point<T>::value, "must be floating point");
186 if C4_LIKELY(scalar.len > 0)
187 {
188 if(scalar.str[0] == '+')
189 scalar = scalar.sub(1);
190 if C4_LIKELY(from_chars(scalar, val))
191 return true;
192 else if(scalar.len == 4 || scalar.len == 5)
193 return detail::from_chars_float_yaml_special(scalar, val);
194 }
195 return false;
196}
bool from_chars(csubstr buf, uint8_t *v) noexcept
basic_substring sub(size_t first) const noexcept
return [first,len[
Definition substr.hpp:502

Referenced by scalar_deserialize().

◆ to_chars_float()

template<class T>
size_t c4::yml::to_chars_float ( substr buf,
T val )

Serialize a floating point value to a string.

Definition at line 202 of file scalar_charconv.hpp.

203{
204 static_assert(std::is_floating_point<T>::value, "must be floating point");
205 C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wfloat-equal");
206 if C4_UNLIKELY(std::isnan(val))
207 return to_chars(buf, csubstr(".nan"));
208 else if C4_UNLIKELY(val == std::numeric_limits<T>::infinity())
209 return to_chars(buf, csubstr(".inf"));
210 else if C4_UNLIKELY(val == -std::numeric_limits<T>::infinity())
211 return to_chars(buf, csubstr("-.inf"));
212 return to_chars(buf, val);
213 C4_SUPPRESS_WARNING_GCC_CLANG_POP
214}
size_t to_chars(substr buf, escaped_scalar e)
formatting implementation to escape a scalar with escape_scalar()

Referenced by scalar_serialize().

◆ from_chars_integral()

template<class T>
bool c4::yml::from_chars_integral ( csubstr scalar,
T * val )
inline

Deserialize an integral scalar.

Trims leading +, and then dispatches to from_chars<T>(). The full string is used.

Note
Unlike with the floating case (see to_chars_float()), there is no need for an analogous to_chars_integral(), because the lower-level atoi() and atou() functions used by to_chars() do not produce leading + characters.

Definition at line 227 of file scalar_charconv.hpp.

228{
229 if C4_LIKELY(scalar.len > 0)
230 {
231 if(scalar.str[0] == '+')
232 scalar = scalar.sub(1);
233 return from_chars(scalar, val);
234 }
235 return false;
236}

Referenced by scalar_deserialize().

◆ scalar_deserialize()

template<class T>
bool c4::yml::scalar_deserialize ( csubstr str,
T * val )
inline

Deserialize a scalar from its string representation, dispatching to one of from_chars(), from_chars_float() or from_chars_integral() as appropriate.

Note
When using a standard older than C++17, if constexpr is not available, and the implementation reverts to SFINAE to achieve the compile-time dispatch.
Returns
true if the deserialization succeeded

Definition at line 254 of file scalar_charconv.hpp.

255{
256 if constexpr (std::is_floating_point<T>::value)
257 return from_chars_float(str, val);
258 else if constexpr (std::is_arithmetic<T>::value)
259 return from_chars_integral(str, val);
260 else
261 return from_chars(str, val);
262}
bool from_chars_integral(csubstr scalar, T *val) RYML_NOEXCEPT
Deserialize an integral scalar.
bool from_chars_float(csubstr scalar, T *val) RYML_NOEXCEPT
Deserialize a floating point from string.

Referenced by read(), and read_key().

◆ scalar_serialize()

template<class T>
size_t c4::yml::scalar_serialize ( substr buf,
T const & a )
inline

Serialize a scalar to the buffer, dispatching to to_chars() or to_chars_float() as appropriate.

Note
When using a standard older than C++17, if constexpr is not available, and the implementation reverts to SFINAE to achieve the compile-time dispatch.
Returns
the size of the serialization, (the buffer size is strictly respected and never overflowed)

Definition at line 308 of file scalar_charconv.hpp.

309{
310 if constexpr (std::is_floating_point<T>::value)
311 return to_chars_float(buf, a);
312 else
313 return to_chars(buf, a);
314}
size_t to_chars_float(substr buf, T val) RYML_NOEXCEPT
Serialize a floating point value to a string.

Referenced by serialize_to_arena_scalar().