mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
fixed treating non-ASCII horizontal whitespace as valid (closes #135)
also: - added `parse_result::at_path()`
This commit is contained in:
parent
cdf85a9b60
commit
e37e6d2bce
75
CHANGELOG.md
75
CHANGELOG.md
@ -18,9 +18,7 @@ template:
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
This release will be a major version bump, so it's ABI breaks all around.
|
This release will be a major version bump, so it's ABI breaks all around.
|
||||||
Any changes that might cause code or build systems to break are indicated with ⚠️.
|
Any changes that are likely to cause migration issues (API changes, build system breakage, etc.) are indicated with ⚠️.
|
||||||
|
|
||||||
Highlights are indicated with ❤️.
|
|
||||||
|
|
||||||
#### Fixes:
|
#### Fixes:
|
||||||
- ⚠️ fixed `toml::table` init-list constructor requiring double-brackets
|
- ⚠️ fixed `toml::table` init-list constructor requiring double-brackets
|
||||||
@ -28,50 +26,50 @@ Highlights are indicated with ❤️.
|
|||||||
- ⚠️ fixed incorrect `noexcept` specifications on many functions
|
- ⚠️ fixed incorrect `noexcept` specifications on many functions
|
||||||
- ⚠️ fixed missing `TOML_API` on some interfaces
|
- ⚠️ fixed missing `TOML_API` on some interfaces
|
||||||
- fixed `toml::json_formatter` not formatting inf and nan incorrectly
|
- fixed `toml::json_formatter` not formatting inf and nan incorrectly
|
||||||
- fixed a number of spec conformance issues (#127, #128, #129, #130, #131, #132) (@moorereason)
|
- fixed a number of spec conformance issues (#127, #128, #129, #130, #131, #132, #135) (@moorereason)
|
||||||
- fixed an illegal table redefinition edge case (#112) (@python36)
|
- fixed an illegal table redefinition edge case (#112) (@python36)
|
||||||
- fixed documentation issues
|
- fixed documentation issues
|
||||||
|
- fixed GCC bug causing memory leak during parse failures (#123, #124) (@rsmmr, @ronalabraham)
|
||||||
- fixed incorrect handling of vertical whitespace in keys when printing TOML to streams
|
- fixed incorrect handling of vertical whitespace in keys when printing TOML to streams
|
||||||
- fixed incorrect source position in redefinition error messages
|
- fixed incorrect source position in redefinition error messages
|
||||||
- fixed memory leak during parse failures when compiled using GCC (#123, #124) (@rsmmr, @ronalabraham)
|
- fixed missing includes `<initializer_list>`, `<utility>`
|
||||||
- fixed missing `#include <initializer_list>`
|
|
||||||
- fixed missing `#include <utility>`
|
|
||||||
- fixed parser not correctly round-tripping the format of binary and octal integers in some cases
|
- fixed parser not correctly round-tripping the format of binary and octal integers in some cases
|
||||||
- fixed some incorrect unicode scalar sequence transformations (#125)
|
- fixed some incorrect unicode scalar sequence transformations (#125)
|
||||||
- fixed strong exception guarantee edge-cases in `toml::table` and `toml::array`
|
- fixed strong exception guarantee edge-cases in `toml::table` and `toml::array`
|
||||||
|
|
||||||
#### Additions:
|
#### Additions:
|
||||||
- ❤️ added `operator->` to `toml::value` for class types
|
- added value flags to array + table insert methods (#44) (@levicki)
|
||||||
- ❤️ added `toml::at_path()`, `toml::node::at_path()` and `toml::node_view::at_path()` for qualified path-based lookups (#118) (@ben-crowhurst)
|
- added support for Unicode 14.0
|
||||||
- ❤️ added `toml::key` - provides a facility to access the source_regions of parsed keys (#82) (@vaartis)
|
- added support for ref categories and cv-qualifiers in `toml::node::ref()`
|
||||||
- ❤️ added `toml::yaml_formatter`
|
- added magic `toml::value_flags` constant `toml::preserve_source_value_flags`
|
||||||
- ❤️ added support for Unicode 14.0
|
- added clang's enum annotation attributes to all enums
|
||||||
- added `parse_benchmark` example
|
- added `TOML_ENABLE_FORMATTERS` option
|
||||||
- added `toml::array::at()` (same semantics as `std::vector::at()`)
|
- added `toml::yaml_formatter`
|
||||||
- added `toml::array::prune()`
|
- added `toml::value` copy+move constructor overloads with flags override
|
||||||
- added `toml::array::replace()` (#109) (@LebJe)
|
- added `toml::table::prune()`
|
||||||
- added `toml::array::resize()` param `default_init_flags`
|
- added `toml::table::lower_bound()` (same semantics as `std::map::lower_bound()`)
|
||||||
- added `toml::date_time` converting constructors from `toml::date` and `toml::time`
|
- added `toml::table::emplace_hint()` (same semantics as `std::map::emplace_hint()`)
|
||||||
- added `toml::format_flags::allow_binary_integers`
|
- added `toml::table::at()` (same semantics as `std::map::at()`)
|
||||||
- added `toml::format_flags::allow_hexadecimal_integers`
|
- added `toml::node_view::operator==`
|
||||||
- added `toml::format_flags::allow_octal_integers`
|
- added `toml::key` - provides a facility to access the source_regions of parsed keys (#82) (@vaartis)
|
||||||
- added `toml::format_flags::allow_real_tabs_in_strings`
|
- added `toml::is_key<>` and toml::is_key_or_convertible<>` metafunctions
|
||||||
- added `toml::format_flags::allow_unicode_strings`
|
|
||||||
- added `toml::format_flags::indent_array_elements` (#120) (@W4RH4WK)
|
|
||||||
- added `toml::format_flags::indent_sub_tables` (#120) (@W4RH4WK)
|
|
||||||
- added `toml::format_flags::relaxed_float_precision` (#89) (@vaartis)
|
- added `toml::format_flags::relaxed_float_precision` (#89) (@vaartis)
|
||||||
- added `toml::format_flags::quote_infinities_and_nans`
|
- added `toml::format_flags::quote_infinities_and_nans`
|
||||||
- added `toml::is_key<>` and toml::is_key_or_convertible<>` metafunctions
|
- added `toml::format_flags::indent_sub_tables` (#120) (@W4RH4WK)
|
||||||
- added `toml::node_view::operator==`
|
- added `toml::format_flags::indent_array_elements` (#120) (@W4RH4WK)
|
||||||
- added `toml::table::at()` (same semantics as `std::map::at()`)
|
- added `toml::format_flags::allow_unicode_strings`
|
||||||
- added `toml::table::emplace_hint()` (same semantics as `std::map::emplace_hint()`)
|
- added `toml::format_flags::allow_real_tabs_in_strings`
|
||||||
- added `toml::table::lower_bound()` (same semantics as `std::map::lower_bound()`)
|
- added `toml::format_flags::allow_octal_integers`
|
||||||
- added `toml::table::prune()`
|
- added `toml::format_flags::allow_hexadecimal_integers`
|
||||||
- added `toml::value` copy+move constructor overloads with flags override
|
- added `toml::format_flags::allow_binary_integers`
|
||||||
- added `TOML_ENABLE_FORMATTERS` option
|
- added `toml::date_time` converting constructors from `toml::date` and `toml::time`
|
||||||
- added clang's enum annotation attributes to all enums
|
- added `toml::at_path()`, `toml::node::at_path()` and `toml::node_view::at_path()` for qualified path-based lookups (#118) (@ben-crowhurst)
|
||||||
- added magic `toml::value_flags` constant `toml::preserve_source_value_flags`
|
- added `toml::array::resize()` param `default_init_flags`
|
||||||
- added value flags to array + table insert methods (#44) (@levicki)
|
- added `toml::array::replace()` (#109) (@LebJe)
|
||||||
|
- added `toml::array::prune()`
|
||||||
|
- added `toml::array::at()` (same semantics as `std::vector::at()`)
|
||||||
|
- added `parse_benchmark` example
|
||||||
|
- added `operator->` to `toml::value` for class types
|
||||||
|
|
||||||
#### Changes:
|
#### Changes:
|
||||||
- ⚠️ `toml::format_flags` is now backed by `uint64_t` (was previously `uint8_t`)
|
- ⚠️ `toml::format_flags` is now backed by `uint64_t` (was previously `uint8_t`)
|
||||||
@ -83,8 +81,7 @@ Highlights are indicated with ❤️.
|
|||||||
- ⚠️ renamed `TOML_PARSER` option to `TOML_ENABLE_PARSER` (`TOML_PARSER` will continue to work but is deprecated)
|
- ⚠️ renamed `TOML_PARSER` option to `TOML_ENABLE_PARSER` (`TOML_PARSER` will continue to work but is deprecated)
|
||||||
- ⚠️ renamed `TOML_UNRELEASED_FEATURES` to `TOML_ENABLE_UNRELEASED_FEATURES` (`TOML_UNRELEASED_FEATURES` will continue to work but is deprecated)
|
- ⚠️ renamed `TOML_UNRELEASED_FEATURES` to `TOML_ENABLE_UNRELEASED_FEATURES` (`TOML_UNRELEASED_FEATURES` will continue to work but is deprecated)
|
||||||
- ⚠️ renamed `TOML_WINDOWS_COMPAT` to `TOML_ENABLE_WINDOWS_COMPAT` (`TOML_WINDOWS_COMPAT` will continue to work but is deprecated)
|
- ⚠️ renamed `TOML_WINDOWS_COMPAT` to `TOML_ENABLE_WINDOWS_COMPAT` (`TOML_WINDOWS_COMPAT` will continue to work but is deprecated)
|
||||||
- ❤️ `toml::node::ref()` now supports explicit ref categories and cv-qualifiers
|
- applied clang-format to all the things 🎉️
|
||||||
- ❤️ applied clang-format to all the things 🎉️
|
|
||||||
- exposed `TOML_NAMESPACE_START` and `TOML_NAMESPACE_END` macros to help with ADL specialization scenarios
|
- exposed `TOML_NAMESPACE_START` and `TOML_NAMESPACE_END` macros to help with ADL specialization scenarios
|
||||||
- improved performance of parser
|
- improved performance of parser
|
||||||
- made date/time constructors accept any integral types
|
- made date/time constructors accept any integral types
|
||||||
@ -95,7 +92,7 @@ Highlights are indicated with ❤️.
|
|||||||
#### Removals:
|
#### Removals:
|
||||||
- ⚠️ removed `toml::format_flags::allow_value_format_flags`
|
- ⚠️ removed `toml::format_flags::allow_value_format_flags`
|
||||||
- ⚠️ removed `TOML_LARGE_FILES` (it is now default - explicitly setting `TOML_LARGE_FILES` to `0` will invoke an `#error`)
|
- ⚠️ removed `TOML_LARGE_FILES` (it is now default - explicitly setting `TOML_LARGE_FILES` to `0` will invoke an `#error`)
|
||||||
- removed unnecessary template machinery (esp. where ostreams were involved)
|
- ⚠️ removed unnecessary template machinery (esp. where ostreams were involved)
|
||||||
- removed unnecessary uses of `final`
|
- removed unnecessary uses of `final`
|
||||||
|
|
||||||
#### Build system:
|
#### Build system:
|
||||||
|
@ -22,6 +22,7 @@ namespace
|
|||||||
"# bar\bkek"sv,
|
"# bar\bkek"sv,
|
||||||
"# \xf1\x63"sv,
|
"# \xf1\x63"sv,
|
||||||
"# val1 = 1\fval2 = 2"sv,
|
"# val1 = 1\fval2 = 2"sv,
|
||||||
|
"foo = 1\n\u2000\nbar = 2"sv,
|
||||||
|
|
||||||
"########## inline tables"sv,
|
"########## inline tables"sv,
|
||||||
"val = {,}"sv,
|
"val = {,}"sv,
|
||||||
|
@ -39,7 +39,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \ecpp
|
/// \ecpp
|
||||||
/// <br>
|
/// <br>
|
||||||
/// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
|
/// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
|
||||||
/// This function makes no allowance for this this, instead treating all period characters as sub-table delimiters.
|
/// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
|
||||||
/// If you have periods in your table keys, first consider:
|
/// If you have periods in your table keys, first consider:
|
||||||
/// 1. Not doing that
|
/// 1. Not doing that
|
||||||
/// 2. Using node_view::operator[] instead.
|
/// 2. Using node_view::operator[] instead.
|
||||||
|
@ -312,25 +312,6 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Iterators (ADL)
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/// \brief Returns an iterator to the first character in a key's backing string.
|
|
||||||
TOML_PURE_INLINE_GETTER
|
|
||||||
friend const_iterator begin(const key& k) noexcept
|
|
||||||
{
|
|
||||||
return k.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns an iterator to one-past-the-last character in a key's backing string.
|
|
||||||
TOML_PURE_INLINE_GETTER
|
|
||||||
friend const_iterator end(const key& k) noexcept
|
|
||||||
{
|
|
||||||
return k.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \brief Prints the key's underlying string out to the stream.
|
/// \brief Prints the key's underlying string out to the stream.
|
||||||
friend std::ostream& operator<<(std::ostream& lhs, const key& rhs)
|
friend std::ostream& operator<<(std::ostream& lhs, const key& rhs)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ TOML_NAMESPACE_START
|
|||||||
/// or a toml::parse_error. Most member functions assume a particular one of these two states,
|
/// or a toml::parse_error. Most member functions assume a particular one of these two states,
|
||||||
/// and calling them when in the wrong state will cause errors (e.g. attempting to access the
|
/// and calling them when in the wrong state will cause errors (e.g. attempting to access the
|
||||||
/// error object when parsing was successful). \cpp
|
/// error object when parsing was successful). \cpp
|
||||||
/// parse_result result = toml::parse_file("config.toml");
|
/// toml::parse_result result = toml::parse_file("config.toml");
|
||||||
/// if (result)
|
/// if (result)
|
||||||
/// do_stuff_with_a_table(result); //implicitly converts to table&
|
/// do_stuff_with_a_table(result); //implicitly converts to table&
|
||||||
/// else
|
/// else
|
||||||
@ -45,7 +45,7 @@ TOML_NAMESPACE_START
|
|||||||
/// (error occurred at line 1, column 13 of 'config.toml')
|
/// (error occurred at line 1, column 13 of 'config.toml')
|
||||||
/// \eout
|
/// \eout
|
||||||
///
|
///
|
||||||
/// Getting node_views (`operator[]`) and using the iterator accessor functions (`begin(), end()` etc.) are
|
/// Getting node_views (`operator[]`, `at_path()`) and using the iterator accessor functions (`begin()`, `end()` etc.) are
|
||||||
/// unconditionally safe; when parsing fails these just return 'empty' values. A ranged-for loop on a failed
|
/// unconditionally safe; when parsing fails these just return 'empty' values. A ranged-for loop on a failed
|
||||||
/// parse_result is also safe since `begin()` and `end()` return the same iterator and will not lead to any
|
/// parse_result is also safe since `begin()` and `end()` return the same iterator and will not lead to any
|
||||||
/// dereferences and iterations.
|
/// dereferences and iterations.
|
||||||
@ -88,117 +88,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \brief A BidirectionalIterator for iterating over const key-value pairs in a wrapped toml::table.
|
/// \brief A BidirectionalIterator for iterating over const key-value pairs in a wrapped toml::table.
|
||||||
using const_iterator = const_table_iterator;
|
using const_iterator = const_table_iterator;
|
||||||
|
|
||||||
/// \brief Returns true if parsing succeeeded.
|
/// \brief Default constructs an 'error' result.
|
||||||
TOML_NODISCARD
|
|
||||||
bool succeeded() const noexcept
|
|
||||||
{
|
|
||||||
return !err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns true if parsing failed.
|
|
||||||
TOML_NODISCARD
|
|
||||||
bool failed() const noexcept
|
|
||||||
{
|
|
||||||
return err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns true if parsing succeeded.
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator bool() const noexcept
|
|
||||||
{
|
|
||||||
return !err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table.
|
|
||||||
TOML_NODISCARD
|
|
||||||
toml::table& table() & noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return *get_as<toml::table>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table (rvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
toml::table&& table() && noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
const toml::table& table() const& noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return *get_as<const toml::table>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error.
|
|
||||||
TOML_NODISCARD
|
|
||||||
parse_error& error() & noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return *get_as<parse_error>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
parse_error&& error() && noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
const parse_error& error() const& noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return *get_as<const parse_error>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table.
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator toml::table&() noexcept
|
|
||||||
{
|
|
||||||
return table();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table (rvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator toml::table&&() noexcept
|
|
||||||
{
|
|
||||||
return std::move(table());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::table (const lvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator const toml::table&() const noexcept
|
|
||||||
{
|
|
||||||
return table();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error.
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator parse_error&() noexcept
|
|
||||||
{
|
|
||||||
return error();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator parse_error&&() noexcept
|
|
||||||
{
|
|
||||||
return std::move(error());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator const parse_error&() const noexcept
|
|
||||||
{
|
|
||||||
return error();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
parse_result() noexcept //
|
parse_result() noexcept //
|
||||||
: err_{ true }
|
: err_{ true }
|
||||||
@ -259,69 +149,134 @@ TOML_NAMESPACE_START
|
|||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
/// \name Result state
|
||||||
///
|
/// @{
|
||||||
/// \param key The key used for the lookup.
|
|
||||||
///
|
/// \brief Returns true if parsing succeeeded.
|
||||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
|
||||||
/// or an empty node view.
|
|
||||||
///
|
|
||||||
/// \see toml::node_view
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<node> operator[](std::string_view key) noexcept
|
bool succeeded() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<node>{} : table()[key];
|
return !err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
/// \brief Returns true if parsing failed.
|
||||||
///
|
|
||||||
/// \param key The key used for the lookup.
|
|
||||||
///
|
|
||||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
|
||||||
/// or an empty node view.
|
|
||||||
///
|
|
||||||
/// \see toml::node_view
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<const node> operator[](std::string_view key) const noexcept
|
bool failed() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<const node>{} : table()[key];
|
return err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TOML_ENABLE_WINDOWS_COMPAT
|
/// \brief Returns true if parsing succeeded.
|
||||||
|
|
||||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
|
||||||
///
|
|
||||||
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
|
||||||
///
|
|
||||||
/// \param key The key used for the lookup.
|
|
||||||
///
|
|
||||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
|
||||||
/// or an empty node view.
|
|
||||||
///
|
|
||||||
/// \see toml::node_view
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<node> operator[](std::wstring_view key) noexcept
|
explicit operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<node>{} : table()[key];
|
return !err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
/// @}
|
||||||
///
|
|
||||||
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
/// \name Successful parses
|
||||||
///
|
/// @{
|
||||||
/// \param key The key used for the lookup.
|
|
||||||
///
|
/// \brief Returns the internal toml::table.
|
||||||
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
|
||||||
/// or an empty node view.
|
|
||||||
///
|
|
||||||
/// \see toml::node_view
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<const node> operator[](std::wstring_view key) const noexcept
|
toml::table& table() & noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<const node>{} : table()[key];
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return *get_as<toml::table>(storage_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
/// \brief Returns the internal toml::table (rvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
toml::table&& table() && noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
const toml::table& table() const& noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return *get_as<const toml::table>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::table.
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator toml::table&() noexcept
|
||||||
|
{
|
||||||
|
return table();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::table (rvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator toml::table&&() noexcept
|
||||||
|
{
|
||||||
|
return std::move(table());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::table (const lvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator const toml::table&() const noexcept
|
||||||
|
{
|
||||||
|
return table();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Failed parses
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error.
|
||||||
|
TOML_NODISCARD
|
||||||
|
parse_error& error() & noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return *get_as<parse_error>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
parse_error&& error() && noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
const parse_error& error() const& noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return *get_as<const parse_error>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error.
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator parse_error&() noexcept
|
||||||
|
{
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error (rvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator parse_error&&() noexcept
|
||||||
|
{
|
||||||
|
return std::move(error());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns the internal toml::parse_error (const lvalue overload).
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator const parse_error&() const noexcept
|
||||||
|
{
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Iterators
|
||||||
|
/// @{
|
||||||
|
|
||||||
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
/// \brief Returns an iterator to the first key-value pair in the wrapped table.
|
||||||
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
/// \remarks Returns a default-constructed 'nothing' iterator if the parsing failed.
|
||||||
@ -371,6 +326,117 @@ TOML_NAMESPACE_START
|
|||||||
return err_ ? const_table_iterator{} : table().cend();
|
return err_ ? const_table_iterator{} : table().cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Node views
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
||||||
|
///
|
||||||
|
/// \param key The key used for the lookup.
|
||||||
|
///
|
||||||
|
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||||
|
/// or an empty node view.
|
||||||
|
///
|
||||||
|
/// \see toml::node_view
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> operator[](std::string_view key) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||||
|
///
|
||||||
|
/// \param key The key used for the lookup.
|
||||||
|
///
|
||||||
|
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||||
|
/// or an empty node view.
|
||||||
|
///
|
||||||
|
/// \see toml::node_view
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> operator[](std::string_view key) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
|
||||||
|
///
|
||||||
|
/// \see #toml::at_path(node&, std::string_view)
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> at_path(std::string_view path) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
|
||||||
|
///
|
||||||
|
/// \see #toml::at_path(node&, std::string_view)
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> at_path(std::string_view path) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOML_ENABLE_WINDOWS_COMPAT
|
||||||
|
|
||||||
|
/// \brief Gets a node_view for the selected key-value pair in the wrapped table.
|
||||||
|
///
|
||||||
|
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
||||||
|
///
|
||||||
|
/// \param key The key used for the lookup.
|
||||||
|
///
|
||||||
|
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||||
|
/// or an empty node view.
|
||||||
|
///
|
||||||
|
/// \see toml::node_view
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> operator[](std::wstring_view key) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
|
||||||
|
///
|
||||||
|
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
||||||
|
///
|
||||||
|
/// \param key The key used for the lookup.
|
||||||
|
///
|
||||||
|
/// \returns A view of the value at the given key if parsing was successful and a matching key existed,
|
||||||
|
/// or an empty node view.
|
||||||
|
///
|
||||||
|
/// \see toml::node_view
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> operator[](std::wstring_view key) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
|
||||||
|
///
|
||||||
|
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
||||||
|
///
|
||||||
|
/// \see #toml::at_path(node&, std::string_view)
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> at_path(std::wstring_view path) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
|
||||||
|
///
|
||||||
|
/// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
|
||||||
|
///
|
||||||
|
/// \see #toml::at_path(node&, std::string_view)
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> at_path(std::wstring_view path) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
#if TOML_ENABLE_FORMATTERS
|
#if TOML_ENABLE_FORMATTERS
|
||||||
|
|
||||||
/// \brief Prints the held error or table object out to a text stream.
|
/// \brief Prints the held error or table object out to a text stream.
|
||||||
|
@ -686,9 +686,9 @@ TOML_ANON_NAMESPACE_START
|
|||||||
TOML_INTERNAL_LINKAGE
|
TOML_INTERNAL_LINKAGE
|
||||||
std::string_view to_sv(const utf8_codepoint& cp) noexcept
|
std::string_view to_sv(const utf8_codepoint& cp) noexcept
|
||||||
{
|
{
|
||||||
if TOML_UNLIKELY(cp.value <= U'\x1F')
|
if (cp.value <= U'\x1F')
|
||||||
return impl::control_char_escapes[cp.value];
|
return impl::control_char_escapes[cp.value];
|
||||||
else if TOML_UNLIKELY(cp.value == U'\x7F')
|
else if (cp.value == U'\x7F')
|
||||||
return "\\u007F"sv;
|
return "\\u007F"sv;
|
||||||
else
|
else
|
||||||
return std::string_view{ cp.bytes, cp.count };
|
return std::string_view{ cp.bytes, cp.count };
|
||||||
@ -703,15 +703,21 @@ TOML_ANON_NAMESPACE_START
|
|||||||
return ""sv;
|
return ""sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct escaped_codepoint
|
||||||
|
{
|
||||||
|
const utf8_codepoint& cp;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TOML_ATTR(nonnull)
|
TOML_ATTR(nonnull)
|
||||||
TOML_INTERNAL_LINKAGE
|
TOML_INTERNAL_LINKAGE
|
||||||
TOML_NEVER_INLINE
|
TOML_NEVER_INLINE
|
||||||
void concatenate(char*& write_pos, char* const buf_end, const T& arg) noexcept
|
void concatenate(char*& write_pos, char* const buf_end, const T& arg) noexcept
|
||||||
{
|
{
|
||||||
static_assert(impl::is_one_of<impl::remove_cvref<T>, std::string_view, int64_t, uint64_t, double>,
|
static_assert(
|
||||||
"concatenate inputs are limited to std::string_view, int64_t, uint64_t and double to keep "
|
impl::is_one_of<impl::remove_cvref<T>, std::string_view, int64_t, uint64_t, double, escaped_codepoint>,
|
||||||
"instantiations to a minimum as an anti-bloat measure (hint: to_sv will probably help)");
|
"concatenate inputs are limited to [std::string_view, int64_t, uint64_t, double, escaped_codepoint] to "
|
||||||
|
"keep instantiations at a minimum as an anti-bloat measure (hint: to_sv will probably help)");
|
||||||
|
|
||||||
if (write_pos >= buf_end)
|
if (write_pos >= buf_end)
|
||||||
return;
|
return;
|
||||||
@ -750,6 +756,25 @@ TOML_ANON_NAMESPACE_START
|
|||||||
concatenate(write_pos, buf_end, to_sv(std::move(ss).str()));
|
concatenate(write_pos, buf_end, to_sv(std::move(ss).str()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if constexpr (std::is_same_v<arg_t, escaped_codepoint>)
|
||||||
|
{
|
||||||
|
if (arg.cp.value <= U'\x7F')
|
||||||
|
concatenate(write_pos, buf_end, to_sv(arg.cp));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto val = static_cast<uint_least32_t>(arg.cp.value);
|
||||||
|
const auto digits = val > 0xFFFFu ? 8u : 4u;
|
||||||
|
constexpr auto mask = uint_least32_t{ 0xFu };
|
||||||
|
char buf[10] = { '\\', digits > 4 ? 'U' : 'u' };
|
||||||
|
for (auto i = 2u + digits; i-- > 2u;)
|
||||||
|
{
|
||||||
|
const auto hexdig = val & mask;
|
||||||
|
buf[i] = static_cast<char>(hexdig >= 0xAu ? ('A' + (hexdig - 0xAu)) : ('0' + hexdig));
|
||||||
|
val >>= 4;
|
||||||
|
}
|
||||||
|
concatenate(write_pos, buf_end, std::string_view{ buf, digits + 2u });
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
||||||
}
|
}
|
||||||
@ -1143,6 +1168,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
while (!is_eof() && is_horizontal_whitespace(*cp))
|
while (!is_eof() && is_horizontal_whitespace(*cp))
|
||||||
{
|
{
|
||||||
|
if TOML_UNLIKELY(!is_ascii_horizontal_whitespace(*cp))
|
||||||
|
set_error_and_return_default("expected space or tab, saw '"sv, escaped_codepoint{ *cp }, "'"sv);
|
||||||
|
|
||||||
consumed = true;
|
consumed = true;
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
}
|
}
|
||||||
@ -1155,17 +1183,19 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
if TOML_UNLIKELY(is_match(*cp, U'\v', U'\f'))
|
if TOML_UNLIKELY(is_match(*cp, U'\v', U'\f'))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
R"(vertical tabs '\v' and form-feeds '\f' are not legal whitespace in TOML.)"sv);
|
R"(vertical tabs '\v' and form-feeds '\f' are not legal line breaks in TOML)"sv);
|
||||||
|
|
||||||
if (*cp == U'\r')
|
if (*cp == U'\r')
|
||||||
{
|
{
|
||||||
advance_and_return_if_error({}); // skip \r
|
advance_and_return_if_error({}); // skip \r
|
||||||
|
|
||||||
if TOML_UNLIKELY(is_eof())
|
if TOML_UNLIKELY(is_eof())
|
||||||
set_error_and_return_default("expected \\n after \\r, saw EOF"sv);
|
set_error_and_return_default("expected '\\n' after '\\r', saw EOF"sv);
|
||||||
|
|
||||||
if TOML_UNLIKELY(*cp != U'\n')
|
if TOML_UNLIKELY(*cp != U'\n')
|
||||||
set_error_and_return_default("expected \\n after \\r, saw '"sv, to_sv(*cp), "'"sv);
|
set_error_and_return_default("expected '\\n' after '\\r', saw '"sv,
|
||||||
|
escaped_codepoint{ *cp },
|
||||||
|
"'"sv);
|
||||||
}
|
}
|
||||||
else if (*cp != U'\n')
|
else if (*cp != U'\n')
|
||||||
return false;
|
return false;
|
||||||
@ -2807,7 +2837,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
utf8_buffered_reader::max_history_length - 2u;
|
utf8_buffered_reader::max_history_length - 2u;
|
||||||
if TOML_UNLIKELY(!eof_while_scanning && advance_count > max_numeric_value_length)
|
if TOML_UNLIKELY(!eof_while_scanning && advance_count > max_numeric_value_length)
|
||||||
set_error_and_return_default("numeric value too long to identify type - cannot exceed "sv,
|
set_error_and_return_default("numeric value too long to identify type - cannot exceed "sv,
|
||||||
max_numeric_value_length,
|
static_cast<uint64_t>(max_numeric_value_length),
|
||||||
" characters"sv);
|
" characters"sv);
|
||||||
|
|
||||||
val.reset(new value{ parse_integer<10>() });
|
val.reset(new value{ parse_integer<10>() });
|
||||||
@ -3359,7 +3389,8 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_after_error({});
|
return_after_error({});
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the key first since the key buffer will likely get overritten during value parsing (inline tables)
|
// create the key first since the key buffer will likely get overwritten during value parsing (inline
|
||||||
|
// tables)
|
||||||
auto last_key = make_key(key_buffer.size() - 1u);
|
auto last_key = make_key(key_buffer.size() - 1u);
|
||||||
|
|
||||||
// now we can actually parse the value
|
// now we can actually parse the value
|
||||||
|
@ -302,4 +302,22 @@ b = []
|
|||||||
parsing_should_fail(FILE_LINE_ARGS, " val = 0x8000000000000000"sv); // int64_t max + 1
|
parsing_should_fail(FILE_LINE_ARGS, " val = 0x8000000000000000"sv); // int64_t max + 1
|
||||||
parse_expected_value(FILE_LINE_ARGS, " 0x7FFFFFFFFFFFFFFF"sv, INT64_MAX);
|
parse_expected_value(FILE_LINE_ARGS, " 0x7FFFFFFFFFFFFFFF"sv, INT64_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("github/issues/135") // https://github.com/marzer/tomlplusplus/issues/135
|
||||||
|
{
|
||||||
|
parsing_should_succeed(FILE_LINE_ARGS, "0=0"sv);
|
||||||
|
parsing_should_succeed(FILE_LINE_ARGS, "1=1"sv);
|
||||||
|
parsing_should_succeed(FILE_LINE_ARGS, "2=2"sv);
|
||||||
|
|
||||||
|
parsing_should_succeed(FILE_LINE_ARGS,
|
||||||
|
"0=0\n"
|
||||||
|
"1=1\n"
|
||||||
|
"2=2\n"sv);
|
||||||
|
|
||||||
|
parsing_should_fail(FILE_LINE_ARGS,
|
||||||
|
"0=0\n"
|
||||||
|
"\u2000\u2000\n"
|
||||||
|
"1=1\n"
|
||||||
|
"2=2\n"sv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
309
toml.hpp
309
toml.hpp
@ -6196,18 +6196,6 @@ TOML_NAMESPACE_START
|
|||||||
return key_.data() + key_.length();
|
return key_.data() + key_.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
TOML_PURE_INLINE_GETTER
|
|
||||||
friend const_iterator begin(const key& k) noexcept
|
|
||||||
{
|
|
||||||
return k.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_PURE_INLINE_GETTER
|
|
||||||
friend const_iterator end(const key& k) noexcept
|
|
||||||
{
|
|
||||||
return k.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& lhs, const key& rhs)
|
friend std::ostream& operator<<(std::ostream& lhs, const key& rhs)
|
||||||
{
|
{
|
||||||
impl::print_to_stream(lhs, rhs.key_);
|
impl::print_to_stream(lhs, rhs.key_);
|
||||||
@ -8406,102 +8394,6 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
using const_iterator = const_table_iterator;
|
using const_iterator = const_table_iterator;
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
bool succeeded() const noexcept
|
|
||||||
{
|
|
||||||
return !err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
bool failed() const noexcept
|
|
||||||
{
|
|
||||||
return err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator bool() const noexcept
|
|
||||||
{
|
|
||||||
return !err_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
toml::table& table() & noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return *get_as<toml::table>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
toml::table&& table() && noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
const toml::table& table() const& noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(!err_);
|
|
||||||
return *get_as<const toml::table>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
parse_error& error() & noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return *get_as<parse_error>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
parse_error&& error() && noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
const parse_error& error() const& noexcept
|
|
||||||
{
|
|
||||||
TOML_ASSERT_ASSUME(err_);
|
|
||||||
return *get_as<const parse_error>(storage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator toml::table&() noexcept
|
|
||||||
{
|
|
||||||
return table();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator toml::table&&() noexcept
|
|
||||||
{
|
|
||||||
return std::move(table());
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
operator const toml::table&() const noexcept
|
|
||||||
{
|
|
||||||
return table();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator parse_error&() noexcept
|
|
||||||
{
|
|
||||||
return error();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator parse_error&&() noexcept
|
|
||||||
{
|
|
||||||
return std::move(error());
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
explicit operator const parse_error&() const noexcept
|
|
||||||
{
|
|
||||||
return error();
|
|
||||||
}
|
|
||||||
|
|
||||||
TOML_NODISCARD_CTOR
|
TOML_NODISCARD_CTOR
|
||||||
parse_result() noexcept //
|
parse_result() noexcept //
|
||||||
: err_{ true }
|
: err_{ true }
|
||||||
@ -8560,32 +8452,100 @@ TOML_NAMESPACE_START
|
|||||||
}
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<node> operator[](std::string_view key) noexcept
|
bool succeeded() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<node>{} : table()[key];
|
return !err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<const node> operator[](std::string_view key) const noexcept
|
bool failed() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<const node>{} : table()[key];
|
return err_;
|
||||||
}
|
|
||||||
|
|
||||||
#if TOML_ENABLE_WINDOWS_COMPAT
|
|
||||||
|
|
||||||
TOML_NODISCARD
|
|
||||||
node_view<node> operator[](std::wstring_view key) noexcept
|
|
||||||
{
|
|
||||||
return err_ ? node_view<node>{} : table()[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
node_view<const node> operator[](std::wstring_view key) const noexcept
|
explicit operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return err_ ? node_view<const node>{} : table()[key];
|
return !err_;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
TOML_NODISCARD
|
||||||
|
toml::table& table() & noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return *get_as<toml::table>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
toml::table&& table() && noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
const toml::table& table() const& noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(!err_);
|
||||||
|
return *get_as<const toml::table>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator toml::table&() noexcept
|
||||||
|
{
|
||||||
|
return table();
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator toml::table&&() noexcept
|
||||||
|
{
|
||||||
|
return std::move(table());
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
/* implicit */ operator const toml::table&() const noexcept
|
||||||
|
{
|
||||||
|
return table();
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
parse_error& error() & noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return *get_as<parse_error>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
parse_error&& error() && noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
const parse_error& error() const& noexcept
|
||||||
|
{
|
||||||
|
TOML_ASSERT_ASSUME(err_);
|
||||||
|
return *get_as<const parse_error>(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator parse_error&() noexcept
|
||||||
|
{
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator parse_error&&() noexcept
|
||||||
|
{
|
||||||
|
return std::move(error());
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
explicit operator const parse_error&() const noexcept
|
||||||
|
{
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
table_iterator begin() noexcept
|
table_iterator begin() noexcept
|
||||||
@ -8623,6 +8583,58 @@ TOML_NAMESPACE_START
|
|||||||
return err_ ? const_table_iterator{} : table().cend();
|
return err_ ? const_table_iterator{} : table().cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> operator[](std::string_view key) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> operator[](std::string_view key) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> at_path(std::string_view path) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> at_path(std::string_view path) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TOML_ENABLE_WINDOWS_COMPAT
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> operator[](std::wstring_view key) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> operator[](std::wstring_view key) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<node> at_path(std::wstring_view path) noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
TOML_NODISCARD
|
||||||
|
node_view<const node> at_path(std::wstring_view path) const noexcept
|
||||||
|
{
|
||||||
|
return err_ ? node_view<const node>{} : table().at_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TOML_ENABLE_WINDOWS_COMPAT
|
||||||
|
|
||||||
#if TOML_ENABLE_FORMATTERS
|
#if TOML_ENABLE_FORMATTERS
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const parse_result& result)
|
friend std::ostream& operator<<(std::ostream& os, const parse_result& result)
|
||||||
@ -11693,9 +11705,9 @@ TOML_ANON_NAMESPACE_START
|
|||||||
TOML_INTERNAL_LINKAGE
|
TOML_INTERNAL_LINKAGE
|
||||||
std::string_view to_sv(const utf8_codepoint& cp) noexcept
|
std::string_view to_sv(const utf8_codepoint& cp) noexcept
|
||||||
{
|
{
|
||||||
if TOML_UNLIKELY(cp.value <= U'\x1F')
|
if (cp.value <= U'\x1F')
|
||||||
return impl::control_char_escapes[cp.value];
|
return impl::control_char_escapes[cp.value];
|
||||||
else if TOML_UNLIKELY(cp.value == U'\x7F')
|
else if (cp.value == U'\x7F')
|
||||||
return "\\u007F"sv;
|
return "\\u007F"sv;
|
||||||
else
|
else
|
||||||
return std::string_view{ cp.bytes, cp.count };
|
return std::string_view{ cp.bytes, cp.count };
|
||||||
@ -11710,15 +11722,21 @@ TOML_ANON_NAMESPACE_START
|
|||||||
return ""sv;
|
return ""sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct escaped_codepoint
|
||||||
|
{
|
||||||
|
const utf8_codepoint& cp;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TOML_ATTR(nonnull)
|
TOML_ATTR(nonnull)
|
||||||
TOML_INTERNAL_LINKAGE
|
TOML_INTERNAL_LINKAGE
|
||||||
TOML_NEVER_INLINE
|
TOML_NEVER_INLINE
|
||||||
void concatenate(char*& write_pos, char* const buf_end, const T& arg) noexcept
|
void concatenate(char*& write_pos, char* const buf_end, const T& arg) noexcept
|
||||||
{
|
{
|
||||||
static_assert(impl::is_one_of<impl::remove_cvref<T>, std::string_view, int64_t, uint64_t, double>,
|
static_assert(
|
||||||
"concatenate inputs are limited to std::string_view, int64_t, uint64_t and double to keep "
|
impl::is_one_of<impl::remove_cvref<T>, std::string_view, int64_t, uint64_t, double, escaped_codepoint>,
|
||||||
"instantiations to a minimum as an anti-bloat measure (hint: to_sv will probably help)");
|
"concatenate inputs are limited to [std::string_view, int64_t, uint64_t, double, escaped_codepoint] to "
|
||||||
|
"keep instantiations at a minimum as an anti-bloat measure (hint: to_sv will probably help)");
|
||||||
|
|
||||||
if (write_pos >= buf_end)
|
if (write_pos >= buf_end)
|
||||||
return;
|
return;
|
||||||
@ -11757,6 +11775,25 @@ TOML_ANON_NAMESPACE_START
|
|||||||
concatenate(write_pos, buf_end, to_sv(std::move(ss).str()));
|
concatenate(write_pos, buf_end, to_sv(std::move(ss).str()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if constexpr (std::is_same_v<arg_t, escaped_codepoint>)
|
||||||
|
{
|
||||||
|
if (arg.cp.value <= U'\x7F')
|
||||||
|
concatenate(write_pos, buf_end, to_sv(arg.cp));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto val = static_cast<uint_least32_t>(arg.cp.value);
|
||||||
|
const auto digits = val > 0xFFFFu ? 8u : 4u;
|
||||||
|
constexpr auto mask = uint_least32_t{ 0xFu };
|
||||||
|
char buf[10] = { '\\', digits > 4 ? 'U' : 'u' };
|
||||||
|
for (auto i = 2u + digits; i-- > 2u;)
|
||||||
|
{
|
||||||
|
const auto hexdig = val & mask;
|
||||||
|
buf[i] = static_cast<char>(hexdig >= 0xAu ? ('A' + (hexdig - 0xAu)) : ('0' + hexdig));
|
||||||
|
val >>= 4;
|
||||||
|
}
|
||||||
|
concatenate(write_pos, buf_end, std::string_view{ buf, digits + 2u });
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
static_assert(impl::dependent_false<T>, "Evaluated unreachable branch!");
|
||||||
}
|
}
|
||||||
@ -12150,6 +12187,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
while (!is_eof() && is_horizontal_whitespace(*cp))
|
while (!is_eof() && is_horizontal_whitespace(*cp))
|
||||||
{
|
{
|
||||||
|
if TOML_UNLIKELY(!is_ascii_horizontal_whitespace(*cp))
|
||||||
|
set_error_and_return_default("expected space or tab, saw '"sv, escaped_codepoint{ *cp }, "'"sv);
|
||||||
|
|
||||||
consumed = true;
|
consumed = true;
|
||||||
advance_and_return_if_error({});
|
advance_and_return_if_error({});
|
||||||
}
|
}
|
||||||
@ -12162,17 +12202,19 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
|
|
||||||
if TOML_UNLIKELY(is_match(*cp, U'\v', U'\f'))
|
if TOML_UNLIKELY(is_match(*cp, U'\v', U'\f'))
|
||||||
set_error_and_return_default(
|
set_error_and_return_default(
|
||||||
R"(vertical tabs '\v' and form-feeds '\f' are not legal whitespace in TOML.)"sv);
|
R"(vertical tabs '\v' and form-feeds '\f' are not legal line breaks in TOML)"sv);
|
||||||
|
|
||||||
if (*cp == U'\r')
|
if (*cp == U'\r')
|
||||||
{
|
{
|
||||||
advance_and_return_if_error({}); // skip \r
|
advance_and_return_if_error({}); // skip \r
|
||||||
|
|
||||||
if TOML_UNLIKELY(is_eof())
|
if TOML_UNLIKELY(is_eof())
|
||||||
set_error_and_return_default("expected \\n after \\r, saw EOF"sv);
|
set_error_and_return_default("expected '\\n' after '\\r', saw EOF"sv);
|
||||||
|
|
||||||
if TOML_UNLIKELY(*cp != U'\n')
|
if TOML_UNLIKELY(*cp != U'\n')
|
||||||
set_error_and_return_default("expected \\n after \\r, saw '"sv, to_sv(*cp), "'"sv);
|
set_error_and_return_default("expected '\\n' after '\\r', saw '"sv,
|
||||||
|
escaped_codepoint{ *cp },
|
||||||
|
"'"sv);
|
||||||
}
|
}
|
||||||
else if (*cp != U'\n')
|
else if (*cp != U'\n')
|
||||||
return false;
|
return false;
|
||||||
@ -13813,7 +13855,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
utf8_buffered_reader::max_history_length - 2u;
|
utf8_buffered_reader::max_history_length - 2u;
|
||||||
if TOML_UNLIKELY(!eof_while_scanning && advance_count > max_numeric_value_length)
|
if TOML_UNLIKELY(!eof_while_scanning && advance_count > max_numeric_value_length)
|
||||||
set_error_and_return_default("numeric value too long to identify type - cannot exceed "sv,
|
set_error_and_return_default("numeric value too long to identify type - cannot exceed "sv,
|
||||||
max_numeric_value_length,
|
static_cast<uint64_t>(max_numeric_value_length),
|
||||||
" characters"sv);
|
" characters"sv);
|
||||||
|
|
||||||
val.reset(new value{ parse_integer<10>() });
|
val.reset(new value{ parse_integer<10>() });
|
||||||
@ -14365,7 +14407,8 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_after_error({});
|
return_after_error({});
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the key first since the key buffer will likely get overritten during value parsing (inline tables)
|
// create the key first since the key buffer will likely get overwritten during value parsing (inline
|
||||||
|
// tables)
|
||||||
auto last_key = make_key(key_buffer.size() - 1u);
|
auto last_key = make_key(key_buffer.size() - 1u);
|
||||||
|
|
||||||
// now we can actually parse the value
|
// now we can actually parse the value
|
||||||
|
Loading…
Reference in New Issue
Block a user