mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-10-06 06:49:43 +00:00
added for_each()
for tables and arrays
also: - refactoring - documentation fixes - updated conformance tests - made submodules shallow
This commit is contained in:
parent
db04ac8918
commit
bf13bbd42e
20
.gitmodules
vendored
20
.gitmodules
vendored
@ -1,19 +1,21 @@
|
|||||||
[submodule "external/toml-test"]
|
[submodule "external/toml-test"]
|
||||||
path = external/toml-test
|
path = external/toml-test
|
||||||
url = https://github.com/BurntSushi/toml-test.git
|
url = https://github.com/BurntSushi/toml-test.git
|
||||||
|
shallow = true
|
||||||
[submodule "external/toml-spec-tests"]
|
[submodule "external/toml-spec-tests"]
|
||||||
path = external/toml-spec-tests
|
path = external/toml-spec-tests
|
||||||
url = https://github.com/iarna/toml-spec-tests.git
|
url = https://github.com/iarna/toml-spec-tests.git
|
||||||
[submodule "external/dox"]
|
shallow = true
|
||||||
path = external/dox
|
[submodule "external/tloptional"]
|
||||||
url = https://github.com/marzer/dox.git
|
path = external/tloptional
|
||||||
|
url = https://github.com/TartanLlama/optional.git
|
||||||
|
shallow = true
|
||||||
|
[submodule "external/json"]
|
||||||
|
path = external/json
|
||||||
|
url = https://github.com/nlohmann/json.git
|
||||||
|
shallow = true
|
||||||
[submodule "external/Catch2"]
|
[submodule "external/Catch2"]
|
||||||
path = external/Catch2
|
path = external/Catch2
|
||||||
url = https://github.com/catchorg/Catch2.git
|
url = https://github.com/catchorg/Catch2.git
|
||||||
branch = v2.x
|
branch = v2.x
|
||||||
[submodule "external/tloptional"]
|
shallow = true
|
||||||
path = external/tloptional
|
|
||||||
url = https://github.com/TartanLlama/optional.git
|
|
||||||
[submodule "external/json"]
|
|
||||||
path = external/json
|
|
||||||
url = https://github.com/nlohmann/json.git
|
|
||||||
|
@ -14,7 +14,7 @@ template:
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
## Unreleased
|
## [v3.1.0](https://github.com/marzer/tomlplusplus/releases/tag/v3.1.0) - 2022-04-22
|
||||||
|
|
||||||
#### Fixes:
|
#### Fixes:
|
||||||
- Fixed potential segfault when calling `at_path()` with an empty string
|
- Fixed potential segfault when calling `at_path()` with an empty string
|
||||||
@ -22,9 +22,11 @@ template:
|
|||||||
- Fixed a number of spurious warnings with Clang 10 (#145, #146) (@chronoxor)
|
- Fixed a number of spurious warnings with Clang 10 (#145, #146) (@chronoxor)
|
||||||
|
|
||||||
#### Additions:
|
#### Additions:
|
||||||
|
- Added `toml::array::for_each()`
|
||||||
|
- Added `toml::table::for_each()`
|
||||||
- Added config options `TOML_EXPORTED_CLASS`, `TOML_EXPORTED_MEMBER_FUNCTION`, `TOML_EXPORTED_STATIC_FUNCTION` & `TOML_EXPORTED_FREE_FUNCTION`
|
- Added config options `TOML_EXPORTED_CLASS`, `TOML_EXPORTED_MEMBER_FUNCTION`, `TOML_EXPORTED_STATIC_FUNCTION` & `TOML_EXPORTED_FREE_FUNCTION`
|
||||||
- Add support for escape sequence `\e` when using `TOML_ENABLE_UNRELEASED_FEATURES` ([toml/790](https://github.com/toml-lang/toml/pull/790))
|
- Added support for escape sequence `\e` when using `TOML_ENABLE_UNRELEASED_FEATURES` ([toml/790](https://github.com/toml-lang/toml/pull/790))
|
||||||
- Add support for more unicode in bare keys when using `TOML_ENABLE_UNRELEASED_FEATURES` ([toml/891](https://github.com/toml-lang/toml/pull/891))
|
- Added support for more unicode in bare keys when using `TOML_ENABLE_UNRELEASED_FEATURES` ([toml/891](https://github.com/toml-lang/toml/pull/891))
|
||||||
|
|
||||||
#### Removals/Deprecations:
|
#### Removals/Deprecations:
|
||||||
- Deprecated old `TOML_API` option in favour new `TOML_EXPORTED_X` options
|
- Deprecated old `TOML_API` option in favour new `TOML_EXPORTED_X` options
|
||||||
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||||||
|
|
||||||
project(
|
project(
|
||||||
tomlplusplus
|
tomlplusplus
|
||||||
VERSION 3.0.1
|
VERSION 3.1.0
|
||||||
DESCRIPTION "Header-only TOML config file parser and serializer for C++17"
|
DESCRIPTION "Header-only TOML config file parser and serializer for C++17"
|
||||||
HOMEPAGE_URL "https://marzer.github.io/tomlplusplus/"
|
HOMEPAGE_URL "https://marzer.github.io/tomlplusplus/"
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
|
15
README.md
15
README.md
@ -99,13 +99,13 @@ You'll find some more code examples in the `examples` directory, and plenty more
|
|||||||
2. `#include <toml++/toml.h>`
|
2. `#include <toml++/toml.h>`
|
||||||
|
|
||||||
### Conan
|
### Conan
|
||||||
Add `tomlplusplus/3.0.1` to your conanfile.
|
Add `tomlplusplus/3.1.0` to your conanfile.
|
||||||
|
|
||||||
### DDS
|
### DDS
|
||||||
Add `tomlpp` to your `package.json5`, e.g.:
|
Add `tomlpp` to your `package.json5`, e.g.:
|
||||||
```
|
```
|
||||||
depends: [
|
depends: [
|
||||||
'tomlpp^3.0.1',
|
'tomlpp^3.1.0',
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
> ℹ️ _[What is DDS?](https://dds.pizza/)_
|
> ℹ️ _[What is DDS?](https://dds.pizza/)_
|
||||||
@ -121,12 +121,21 @@ include(FetchContent)
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
tomlplusplus
|
tomlplusplus
|
||||||
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
||||||
GIT_TAG v3.0.1
|
GIT_TAG v3.1.0
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(tomlplusplus)
|
FetchContent_MakeAvailable(tomlplusplus)
|
||||||
```
|
```
|
||||||
> ℹ️ _[What is FetchContent?](https://cmake.org/cmake/help/latest/module/FetchContent.html)_
|
> ℹ️ _[What is FetchContent?](https://cmake.org/cmake/help/latest/module/FetchContent.html)_
|
||||||
|
|
||||||
|
### Git submodules
|
||||||
|
```
|
||||||
|
git submodule add --depth 1 https://github.com/marzer/tomlplusplus.git tomlplusplus
|
||||||
|
git config -f .gitmodules submodule.tomlplusplus.shallow true
|
||||||
|
```
|
||||||
|
> ℹ️ The toml++ repository has some submodules of its own, but **they are only used for testing**!
|
||||||
|
> You do not need to use the `--recursive` option for regular library consumption.
|
||||||
|
|
||||||
|
|
||||||
### Other environments and package managers
|
### Other environments and package managers
|
||||||
`toml++` is a fairly new project and I'm not up-to-speed with all of the available packaging and integration options
|
`toml++` is a fairly new project and I'm not up-to-speed with all of the available packaging and integration options
|
||||||
in the C++ ecosystem. I'm also a cmake novice, for better or worse. If there's an integration option missing be
|
in the C++ ecosystem. I'm also a cmake novice, for better or worse. If there's an integration option missing be
|
||||||
|
@ -457,7 +457,7 @@
|
|||||||
|
|
||||||
|
|
||||||
\subsection mainpage-adding-lib-conan Conan
|
\subsection mainpage-adding-lib-conan Conan
|
||||||
Add `tomlplusplus/3.0.1` to your conanfile.
|
Add `tomlplusplus/3.1.0` to your conanfile.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -465,7 +465,7 @@
|
|||||||
Add `tomlpp` to your `package.json5`, e.g.:
|
Add `tomlpp` to your `package.json5`, e.g.:
|
||||||
\bash
|
\bash
|
||||||
depends: [
|
depends: [
|
||||||
'tomlpp^3.0.1',
|
'tomlpp^3.1.0',
|
||||||
]
|
]
|
||||||
\ebash
|
\ebash
|
||||||
|
|
||||||
@ -497,7 +497,7 @@
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
tomlplusplus
|
tomlplusplus
|
||||||
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
||||||
GIT_TAG v3.0.1
|
GIT_TAG v3.1.0
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(tomlplusplus)
|
FetchContent_MakeAvailable(tomlplusplus)
|
||||||
\endcode
|
\endcode
|
||||||
@ -506,6 +506,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\subsection mainpage-adding-lib-git-submodules Git submodules
|
||||||
|
\bash
|
||||||
|
git submodule add --depth 1 https://github.com/marzer/tomlplusplus.git tomlplusplus
|
||||||
|
git config -f .gitmodules submodule.tomlplusplus.shallow true
|
||||||
|
\ebash
|
||||||
|
\note The toml++ repository has some submodules of its own, but **they are only used for testing**! You do not need to
|
||||||
|
use the `--recursive` option for regular library consumption.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\subsection mainpage-adding-lib-other Other environments and package managers
|
\subsection mainpage-adding-lib-other Other environments and package managers
|
||||||
toml++ is a fairly new project and I'm not up-to-speed with all of the available packaging and integration options
|
toml++ is a fairly new project and I'm not up-to-speed with all of the available packaging and integration options
|
||||||
in the C++ ecosystem. I'm also a cmake novice, for better or worse. If there's an integration option missing
|
in the C++ ecosystem. I'm also a cmake novice, for better or worse. If there's an integration option missing
|
||||||
|
2
external/Catch2
vendored
2
external/Catch2
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 958944d27a2d2fb82aa008377bf4f8752f6b848e
|
Subproject commit d71b4617e9935f8589870af211f5b7552d743654
|
2
external/json
vendored
2
external/json
vendored
@ -1 +1 @@
|
|||||||
Subproject commit e4643d1f1b03fc7a1d7b65f17e012ca93680cad8
|
Subproject commit fcc36f99ba1afc7baebe24e0c7429d2039d32d99
|
2
external/toml-test
vendored
2
external/toml-test
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 983c1a54c5faad31b5d217b1e47c0e074dea7840
|
Subproject commit 10cdc99d96fbf1350a8891a9d93295fcc85aa694
|
@ -773,7 +773,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Iterators
|
/// \name Iteration
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// \brief A RandomAccessIterator for iterating over elements in a toml::array.
|
/// \brief A RandomAccessIterator for iterating over elements in a toml::array.
|
||||||
@ -824,6 +824,232 @@ TOML_NAMESPACE_START
|
|||||||
return const_iterator{ elems_.cend() };
|
return const_iterator{ elems_.cend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \cond
|
||||||
|
|
||||||
|
template <typename T, typename Array>
|
||||||
|
using for_each_elem_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool can_for_each = std::is_invocable_v<Func, for_each_elem_ref<T, Array>, size_t> //
|
||||||
|
|| std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>> //
|
||||||
|
|| std::is_invocable_v<Func, for_each_elem_ref<T, Array>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool can_for_each_nothrow =
|
||||||
|
std::is_nothrow_invocable_v<Func, for_each_elem_ref<T, Array>, size_t> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, size_t, for_each_elem_ref<T, Array>> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, for_each_elem_ref<T, Array>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static constexpr bool can_for_each_any = can_for_each<Func, Array, table> //
|
||||||
|
|| can_for_each<Func, Array, array> //
|
||||||
|
|| can_for_each<Func, Array, std::string> //
|
||||||
|
|| can_for_each<Func, Array, int64_t> //
|
||||||
|
|| can_for_each<Func, Array, double> //
|
||||||
|
|| can_for_each<Func, Array, bool> //
|
||||||
|
|| can_for_each<Func, Array, date> //
|
||||||
|
|| can_for_each<Func, Array, time> //
|
||||||
|
|| can_for_each<Func, Array, date_time>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool for_each_is_nothrow_one = !can_for_each<Func, Array, T> //
|
||||||
|
|| can_for_each_nothrow<Func, Array, T>;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static constexpr bool for_each_is_nothrow = for_each_is_nothrow_one<Func, Array, table> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, array> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, std::string> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, int64_t> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, double> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, bool> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, date> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, time> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, date_time>;
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static void do_for_each(Func&& visitor, Array&& arr) noexcept(for_each_is_nothrow<Func&&, Array&&>)
|
||||||
|
{
|
||||||
|
static_assert(can_for_each_any<Func&&, Array&&>,
|
||||||
|
"TOML array for_each visitors must be invocable for at least one of the toml::node "
|
||||||
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arr.size(); i++)
|
||||||
|
{
|
||||||
|
using node_ref = impl::copy_cvref<toml::node, Array&&>;
|
||||||
|
static_assert(std::is_reference_v<node_ref>);
|
||||||
|
|
||||||
|
const auto keep_going =
|
||||||
|
static_cast<node_ref>(static_cast<Array&&>(arr)[i])
|
||||||
|
.visit(
|
||||||
|
[&](auto&& elem) noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>)
|
||||||
|
{
|
||||||
|
using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
|
||||||
|
static_assert(std::is_reference_v<elem_ref>);
|
||||||
|
|
||||||
|
// func(elem, i)
|
||||||
|
if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(i, elem)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(elem)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// visitor not compatible with this particular type
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keep_going)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief Invokes a visitor on each element in the array.
|
||||||
|
///
|
||||||
|
/// \tparam Func A callable type invocable with one of the following signatures:
|
||||||
|
/// <ul>
|
||||||
|
/// <li> `func(elem, index)`
|
||||||
|
/// <li> `func(elem)`
|
||||||
|
/// <li> `func(index, elem)`
|
||||||
|
/// </ul>
|
||||||
|
/// Where:
|
||||||
|
/// <ul>
|
||||||
|
/// <li> `elem` will recieve the element as it's concrete type with cvref-qualifications matching the array
|
||||||
|
/// <li> `index` will recieve a `size_t` indicating the element's index
|
||||||
|
/// </ul>
|
||||||
|
/// Visitors returning `bool` (or something convertible to `bool`) will cause iteration to
|
||||||
|
/// stop if they return `false`.
|
||||||
|
///
|
||||||
|
/// \param visitor The visitor object.
|
||||||
|
///
|
||||||
|
/// \returns A reference to the array.
|
||||||
|
///
|
||||||
|
/// \details \cpp
|
||||||
|
/// toml::array arr{ 0, 1, 2, 3.0, "four", "five", 6 };
|
||||||
|
///
|
||||||
|
/// // select only the integers using a strongly-typed visitor
|
||||||
|
/// arr.for_each([](toml::value<int64_t>& elem)
|
||||||
|
/// {
|
||||||
|
/// std::cout << elem << ", ";
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n";
|
||||||
|
///
|
||||||
|
/// // select all the numeric values using a generic visitor + is_number<> metafunction
|
||||||
|
/// arr.for_each([](auto&& elem)
|
||||||
|
/// {
|
||||||
|
/// if constexpr (toml::is_number<decltype(elem)>)
|
||||||
|
/// std::cout << elem << ", ";
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n";
|
||||||
|
///
|
||||||
|
/// // select all the numeric values until we encounter something non-numeric
|
||||||
|
/// arr.for_each([](auto&& elem)
|
||||||
|
/// {
|
||||||
|
/// if constexpr (toml::is_number<decltype(elem)>)
|
||||||
|
/// {
|
||||||
|
/// std::cout << elem << ", ";
|
||||||
|
/// return true; // "keep going"
|
||||||
|
/// }
|
||||||
|
/// else
|
||||||
|
/// return false; // "stop!"
|
||||||
|
///
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n";
|
||||||
|
///
|
||||||
|
/// \ecpp
|
||||||
|
/// \out
|
||||||
|
/// 0, 1, 2, 6,
|
||||||
|
/// 0, 1, 2, 3.0, 6,
|
||||||
|
/// 0, 1, 2, 3.0,
|
||||||
|
/// \eout
|
||||||
|
///
|
||||||
|
/// \see node::visit()
|
||||||
|
template <typename Func>
|
||||||
|
array& for_each(Func&& visitor) & noexcept(for_each_is_nothrow<Func&&, array&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each element in the array (rvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
array&& for_each(Func&& visitor) && noexcept(for_each_is_nothrow<Func&&, array&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<array&&>(*this));
|
||||||
|
return static_cast<array&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each element in the array (const lvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
const array& for_each(Func&& visitor) const& noexcept(for_each_is_nothrow<Func&&, const array&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each element in the array (const rvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
const array&& for_each(Func&& visitor) const&& noexcept(for_each_is_nothrow<Func&&, const array&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<const array&&>(*this));
|
||||||
|
return static_cast<const array&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Size and Capacity
|
/// \name Size and Capacity
|
||||||
@ -1004,8 +1230,6 @@ TOML_NAMESPACE_START
|
|||||||
array& flatten() &;
|
array& flatten() &;
|
||||||
|
|
||||||
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
|
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
|
||||||
///
|
|
||||||
/// \returns An rvalue reference to the array.
|
|
||||||
array&& flatten() &&
|
array&& flatten() &&
|
||||||
{
|
{
|
||||||
return static_cast<toml::array&&>(this->flatten());
|
return static_cast<toml::array&&>(this->flatten());
|
||||||
|
@ -916,6 +916,10 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
|
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
|
||||||
|
|
||||||
|
template <typename T, typename ConvertFrom>
|
||||||
|
inline constexpr bool is_constructible_or_convertible = std::is_constructible_v<T, ConvertFrom> //
|
||||||
|
|| std::is_convertible_v<ConvertFrom, T>;
|
||||||
}
|
}
|
||||||
TOML_IMPL_NAMESPACE_END;
|
TOML_IMPL_NAMESPACE_END;
|
||||||
/// \endcond
|
/// \endcond
|
||||||
@ -990,8 +994,8 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclasses).
|
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclasses).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_node =
|
inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
|
||||||
std::is_same_v<toml::node, impl::remove_cvref<T>> || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
|
|| std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
|
||||||
|
|
||||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
|
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -287,7 +287,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Iterators
|
/// \name Iteration
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// A const iterator for iterating over the characters in the key.
|
/// A const iterator for iterating over the characters in the key.
|
||||||
@ -327,8 +327,8 @@ TOML_NAMESPACE_START
|
|||||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::key,
|
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::key,
|
||||||
/// or is implicitly or explicitly convertible to one.
|
/// or is implicitly or explicitly convertible to one.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_key_or_convertible =
|
inline constexpr bool is_key_or_convertible = is_key<T> //
|
||||||
is_key<T> || std::is_constructible_v<toml::key, T> || std::is_convertible_v<T, toml::key>;
|
|| impl::is_constructible_or_convertible<toml::key, T>;
|
||||||
}
|
}
|
||||||
TOML_NAMESPACE_END;
|
TOML_NAMESPACE_END;
|
||||||
|
|
||||||
|
@ -530,7 +530,7 @@ TOML_NAMESPACE_START
|
|||||||
/// {
|
/// {
|
||||||
/// std::cout << "- " << std::setw(18) << std::left << type_name;
|
/// std::cout << "- " << std::setw(18) << std::left << type_name;
|
||||||
/// using type = std::remove_pointer_t<decltype(dummy)>;
|
/// using type = std::remove_pointer_t<decltype(dummy)>;
|
||||||
/// if (std::optional<type> val = tbl.get(key)->value<type>())
|
/// if (auto val = tbl.get(key)->value<type>(); val)
|
||||||
/// std::cout << *val << "\n";
|
/// std::cout << *val << "\n";
|
||||||
/// else
|
/// else
|
||||||
/// std::cout << "n/a\n";
|
/// std::cout << "n/a\n";
|
||||||
@ -732,145 +732,141 @@ TOML_NAMESPACE_START
|
|||||||
private:
|
private:
|
||||||
/// \cond
|
/// \cond
|
||||||
|
|
||||||
|
template <typename Func, typename Node, typename T>
|
||||||
|
static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Node, typename T>
|
||||||
|
static constexpr bool can_visit_nothrow = std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Node>
|
||||||
|
static constexpr bool can_visit_any = can_visit<Func, Node, table> //
|
||||||
|
|| can_visit<Func, Node, array> //
|
||||||
|
|| can_visit<Func, Node, std::string> //
|
||||||
|
|| can_visit<Func, Node, int64_t> //
|
||||||
|
|| can_visit<Func, Node, double> //
|
||||||
|
|| can_visit<Func, Node, bool> //
|
||||||
|
|| can_visit<Func, Node, date> //
|
||||||
|
|| can_visit<Func, Node, time> //
|
||||||
|
|| can_visit<Func, Node, date_time>;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node>
|
||||||
static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, N>>;
|
static constexpr bool can_visit_all = can_visit<Func, Node, table> //
|
||||||
|
&& can_visit<Func, Node, array> //
|
||||||
|
&& can_visit<Func, Node, std::string> //
|
||||||
|
&& can_visit<Func, Node, int64_t> //
|
||||||
|
&& can_visit<Func, Node, double> //
|
||||||
|
&& can_visit<Func, Node, bool> //
|
||||||
|
&& can_visit<Func, Node, date> //
|
||||||
|
&& can_visit<Func, Node, time> //
|
||||||
|
&& can_visit<Func, Node, date_time>;
|
||||||
|
|
||||||
template <typename Func, typename N>
|
template <typename Func, typename Node, typename T>
|
||||||
static constexpr bool can_visit_any =
|
static constexpr bool visit_is_nothrow_one = !can_visit<Func, Node, T> || can_visit_nothrow<Func, Node, T>;
|
||||||
can_visit<Func, N, table>
|
|
||||||
|| can_visit<Func, N, array>
|
|
||||||
|| can_visit<Func, N, std::string>
|
|
||||||
|| can_visit<Func, N, int64_t>
|
|
||||||
|| can_visit<Func, N, double>
|
|
||||||
|| can_visit<Func, N, bool>
|
|
||||||
|| can_visit<Func, N, date>
|
|
||||||
|| can_visit<Func, N, time>
|
|
||||||
|| can_visit<Func, N, date_time>;
|
|
||||||
|
|
||||||
template <typename Func, typename N>
|
template <typename Func, typename Node>
|
||||||
static constexpr bool can_visit_all =
|
static constexpr bool visit_is_nothrow = visit_is_nothrow_one<Func, Node, table> //
|
||||||
can_visit<Func, N, table>
|
&& visit_is_nothrow_one<Func, Node, array> //
|
||||||
&& can_visit<Func, N, array>
|
&& visit_is_nothrow_one<Func, Node, std::string> //
|
||||||
&& can_visit<Func, N, std::string>
|
&& visit_is_nothrow_one<Func, Node, int64_t> //
|
||||||
&& can_visit<Func, N, int64_t>
|
&& visit_is_nothrow_one<Func, Node, double> //
|
||||||
&& can_visit<Func, N, double>
|
&& visit_is_nothrow_one<Func, Node, bool> //
|
||||||
&& can_visit<Func, N, bool>
|
&& visit_is_nothrow_one<Func, Node, date> //
|
||||||
&& can_visit<Func, N, date>
|
&& visit_is_nothrow_one<Func, Node, time> //
|
||||||
&& can_visit<Func, N, time>
|
&& visit_is_nothrow_one<Func, Node, date_time>;
|
||||||
&& can_visit<Func, N, date_time>;
|
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
|
||||||
static constexpr bool visit_is_nothrow_one =
|
|
||||||
!can_visit<Func, N, T>
|
|
||||||
|| std::is_nothrow_invocable_v<Func, ref_cast_type<T, N>>;
|
|
||||||
|
|
||||||
template <typename Func, typename N>
|
|
||||||
static constexpr bool visit_is_nothrow =
|
|
||||||
visit_is_nothrow_one<Func, N, table>
|
|
||||||
&& visit_is_nothrow_one<Func, N, array>
|
|
||||||
&& visit_is_nothrow_one<Func, N, std::string>
|
|
||||||
&& visit_is_nothrow_one<Func, N, int64_t>
|
|
||||||
&& visit_is_nothrow_one<Func, N, double>
|
|
||||||
&& visit_is_nothrow_one<Func, N, bool>
|
|
||||||
&& visit_is_nothrow_one<Func, N, date>
|
|
||||||
&& visit_is_nothrow_one<Func, N, time>
|
|
||||||
&& visit_is_nothrow_one<Func, N, date_time>;
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
template <typename Func, typename N, typename T, bool = can_visit<Func, N, T>>
|
template <typename Func, typename Node, typename T, bool = can_visit<Func, Node, T>>
|
||||||
struct visit_return_type_
|
struct visit_return_type_
|
||||||
{
|
{
|
||||||
using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, N>>()));
|
using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
|
||||||
};
|
};
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node, typename T>
|
||||||
struct visit_return_type_<Func, N, T, false>
|
struct visit_return_type_<Func, Node, T, false>
|
||||||
{
|
{
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node, typename T>
|
||||||
using visit_return_type = typename visit_return_type_<Func, N, T>::type;
|
using visit_return_type = typename visit_return_type_<Func, Node, T>::type;
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
|
using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
|
||||||
|
|
||||||
template <typename N, typename Func>
|
template <typename Func, typename Node>
|
||||||
static decltype(auto) do_visit(N&& n, Func&& visitor) noexcept(visit_is_nothrow<Func&&, N&&>)
|
static decltype(auto) do_visit(Func&& visitor, Node&& n) noexcept(visit_is_nothrow<Func&&, Node&&>)
|
||||||
{
|
{
|
||||||
static_assert(can_visit_any<Func&&, N&&>,
|
static_assert(can_visit_any<Func&&, Node&&>,
|
||||||
"TOML node visitors must be invocable for at least one of the toml::node "
|
"TOML node visitors must be invocable for at least one of the toml::node "
|
||||||
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
switch (n.type())
|
switch (n.type())
|
||||||
{
|
{
|
||||||
case node_type::table:
|
case node_type::table:
|
||||||
if constexpr (can_visit<Func&&, N&&, table>)
|
if constexpr (can_visit<Func&&, Node&&, table>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<table>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<table>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::array:
|
case node_type::array:
|
||||||
if constexpr (can_visit<Func&&, N&&, array>)
|
if constexpr (can_visit<Func&&, Node&&, array>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<array>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<array>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::string:
|
case node_type::string:
|
||||||
if constexpr (can_visit<Func&&, N&&, std::string>)
|
if constexpr (can_visit<Func&&, Node&&, std::string>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<std::string>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<std::string>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::integer:
|
case node_type::integer:
|
||||||
if constexpr (can_visit<Func&&, N&&, int64_t>)
|
if constexpr (can_visit<Func&&, Node&&, int64_t>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<int64_t>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<int64_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::floating_point:
|
case node_type::floating_point:
|
||||||
if constexpr (can_visit<Func&&, N&&, double>)
|
if constexpr (can_visit<Func&&, Node&&, double>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<double>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<double>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::boolean:
|
case node_type::boolean:
|
||||||
if constexpr (can_visit<Func&&, N&&, bool>)
|
if constexpr (can_visit<Func&&, Node&&, bool>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<bool>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<bool>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::date:
|
case node_type::date:
|
||||||
if constexpr (can_visit<Func&&, N&&, date>)
|
if constexpr (can_visit<Func&&, Node&&, date>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::time:
|
case node_type::time:
|
||||||
if constexpr (can_visit<Func&&, N&&, time>)
|
if constexpr (can_visit<Func&&, Node&&, time>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<time>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<time>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::date_time:
|
case node_type::date_time:
|
||||||
if constexpr (can_visit<Func&&, N&&, date_time>)
|
if constexpr (can_visit<Func&&, Node&&, date_time>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date_time>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date_time>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::none: TOML_UNREACHABLE;
|
case node_type::none: TOML_UNREACHABLE;
|
||||||
default: TOML_UNREACHABLE;
|
default: TOML_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (can_visit_all<Func&&, N&&>)
|
if constexpr (!can_visit_all<Func&&, Node&&>)
|
||||||
TOML_UNREACHABLE;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
using return_type =
|
using return_type =
|
||||||
nonvoid<visit_return_type<Func&&, N&&, table>,
|
nonvoid<visit_return_type<Func&&, Node&&, table>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, array>,
|
nonvoid<visit_return_type<Func&&, Node&&, array>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, std::string>,
|
nonvoid<visit_return_type<Func&&, Node&&, std::string>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, int64_t>,
|
nonvoid<visit_return_type<Func&&, Node&&, int64_t>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, double>,
|
nonvoid<visit_return_type<Func&&, Node&&, double>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, bool>,
|
nonvoid<visit_return_type<Func&&, Node&&, bool>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, date>,
|
nonvoid<visit_return_type<Func&&, Node&&, date>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, time>,
|
nonvoid<visit_return_type<Func&&, Node&&, time>,
|
||||||
visit_return_type<Func&&, N&&, date_time>
|
visit_return_type<Func&&, Node&&, date_time>
|
||||||
>>>>>>>>;
|
>>>>>>>>;
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@ -903,13 +899,17 @@ TOML_NAMESPACE_START
|
|||||||
/// do_something_with_a_string(*n)); //n is a toml::value<std::string>
|
/// do_something_with_a_string(*n)); //n is a toml::value<std::string>
|
||||||
/// else if constexpr (toml::is_integer<decltype(n)>)
|
/// else if constexpr (toml::is_integer<decltype(n)>)
|
||||||
/// do_something_with_an_int(*n); //n is a toml::value<int64_t>
|
/// do_something_with_an_int(*n); //n is a toml::value<int64_t>
|
||||||
/// else
|
|
||||||
/// throw std::exception{ "Expected string or integer" };
|
|
||||||
/// });
|
/// });
|
||||||
/// \ecpp
|
/// \ecpp
|
||||||
///
|
///
|
||||||
/// \tparam Func A callable type invocable with one or more of the
|
/// Visitor functions need not be generic; specifying a concrete node type as the input argument type
|
||||||
/// toml++ node types.
|
/// effectively acts a 'filter', only invoking the visitor if the concrete type is compatible.
|
||||||
|
/// Thus the example above can be re-written as: \cpp
|
||||||
|
/// node.visit([](toml::value<std::string>& s) { do_something_with_a_string(*s)); });
|
||||||
|
/// node.visit([](toml::value<int64_t>& i) { do_something_with_an_int(*i)); });
|
||||||
|
/// \ecpp
|
||||||
|
///
|
||||||
|
/// \tparam Func A callable type invocable with one or more of the toml++ node types.
|
||||||
///
|
///
|
||||||
/// \param visitor The visitor object.
|
/// \param visitor The visitor object.
|
||||||
///
|
///
|
||||||
@ -920,28 +920,28 @@ TOML_NAMESPACE_START
|
|||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
||||||
{
|
{
|
||||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
|
/// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||||
{
|
{
|
||||||
return do_visit(static_cast<node&&>(*this), static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), static_cast<node&&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue overload).
|
/// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue overload).
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||||
{
|
{
|
||||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Invokes a visitor on the node based on the node's concrete type (const rvalue overload).
|
/// \brief Invokes a visitor on the node based on the node's concrete type (const rvalue overload).
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>)
|
decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>)
|
||||||
{
|
{
|
||||||
return do_visit(static_cast<const node&&>(*this), static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), static_cast<const node&&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -102,16 +102,13 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
if ((!lhs != !rhs) || lhs->type() != rhs->type())
|
if ((!lhs != !rhs) || lhs->type() != rhs->type())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool same;
|
return lhs->visit(
|
||||||
lhs->visit(
|
[=](auto& l) noexcept
|
||||||
[=, &same](auto& l) noexcept
|
|
||||||
{
|
{
|
||||||
using concrete_type = remove_cvref<decltype(l)>;
|
using concrete_type = remove_cvref<decltype(l)>;
|
||||||
|
|
||||||
same = (l == *(rhs->as<concrete_type>()));
|
return l == *(rhs->as<concrete_type>());
|
||||||
});
|
});
|
||||||
|
|
||||||
return same;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TOML_IMPL_NAMESPACE_END;
|
TOML_IMPL_NAMESPACE_END;
|
||||||
|
@ -269,7 +269,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Iterators
|
/// \name Iteration
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// \brief A BidirectionalIterator for iterating over key-value pairs in a wrapped toml::table.
|
/// \brief A BidirectionalIterator for iterating over key-value pairs in a wrapped toml::table.
|
||||||
|
@ -1102,8 +1102,8 @@
|
|||||||
/// \def TOML_SMALL_FLOAT_TYPE
|
/// \def TOML_SMALL_FLOAT_TYPE
|
||||||
/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it.
|
/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it.
|
||||||
/// \detail Not defined by default.
|
/// \detail Not defined by default.
|
||||||
/// \remark If you're building for a platform that has a built-in half precision float (e.g. `_Float16`), you don't
|
/// \remark If you're building for a platform that has `_Float16` and/or `__fp16`, you don't
|
||||||
/// need to use this configuration option to make toml++ aware of it; the library comes with that built-in.
|
/// need to use this configuration option to make toml++ aware of them. The library comes with that built-in.
|
||||||
|
|
||||||
|
|
||||||
#define TOML_SMALL_INT_TYPE
|
#define TOML_SMALL_INT_TYPE
|
||||||
|
@ -221,6 +221,7 @@ TOML_NAMESPACE_START
|
|||||||
/// \cond
|
/// \cond
|
||||||
|
|
||||||
using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
|
using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
|
||||||
|
using map_pair = std::pair<const toml::key, impl::node_ptr>;
|
||||||
using map_iterator = typename map_type::iterator;
|
using map_iterator = typename map_type::iterator;
|
||||||
using const_map_iterator = typename map_type::const_iterator;
|
using const_map_iterator = typename map_type::const_iterator;
|
||||||
map_type map_;
|
map_type map_;
|
||||||
@ -784,7 +785,7 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Iterators
|
/// \name Iteration
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
|
/// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
|
||||||
@ -835,6 +836,236 @@ TOML_NAMESPACE_START
|
|||||||
return const_iterator{ map_.cend() };
|
return const_iterator{ map_.cend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \cond
|
||||||
|
|
||||||
|
template <typename T, typename Table>
|
||||||
|
using for_each_value_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool can_for_each = std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>> //
|
||||||
|
|| std::is_invocable_v<Func, for_each_value_ref<T, Table>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool can_for_each_nothrow =
|
||||||
|
std::is_nothrow_invocable_v<Func, const key&, for_each_value_ref<T, Table>> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, for_each_value_ref<T, Table>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static constexpr bool can_for_each_any = can_for_each<Func, Table, table> //
|
||||||
|
|| can_for_each<Func, Table, array> //
|
||||||
|
|| can_for_each<Func, Table, std::string> //
|
||||||
|
|| can_for_each<Func, Table, int64_t> //
|
||||||
|
|| can_for_each<Func, Table, double> //
|
||||||
|
|| can_for_each<Func, Table, bool> //
|
||||||
|
|| can_for_each<Func, Table, date> //
|
||||||
|
|| can_for_each<Func, Table, time> //
|
||||||
|
|| can_for_each<Func, Table, date_time>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool for_each_is_nothrow_one = !can_for_each<Func, Table, T> //
|
||||||
|
|| can_for_each_nothrow<Func, Table, T>;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static constexpr bool for_each_is_nothrow = for_each_is_nothrow_one<Func, Table, table> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, array> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, std::string> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, int64_t> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, double> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, bool> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, date> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, time> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, date_time>;
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static void do_for_each(Func&& visitor, Table&& tbl) noexcept(for_each_is_nothrow<Func&&, Table&&>)
|
||||||
|
{
|
||||||
|
static_assert(can_for_each_any<Func&&, Table&&>,
|
||||||
|
"TOML table for_each visitors must be invocable for at least one of the toml::node "
|
||||||
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
|
using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
|
||||||
|
|
||||||
|
for (kvp_type& kvp : tbl.map_)
|
||||||
|
{
|
||||||
|
using node_ref = impl::copy_cvref<toml::node, Table&&>;
|
||||||
|
static_assert(std::is_reference_v<node_ref>);
|
||||||
|
|
||||||
|
const auto keep_going =
|
||||||
|
static_cast<node_ref>(*kvp.second)
|
||||||
|
.visit(
|
||||||
|
[&](auto&& v) noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>)
|
||||||
|
{
|
||||||
|
using value_ref = for_each_value_ref<decltype(v), Table&&>;
|
||||||
|
static_assert(std::is_reference_v<value_ref>);
|
||||||
|
|
||||||
|
// func(key, val)
|
||||||
|
if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
|
||||||
|
{
|
||||||
|
using return_type = decltype(static_cast<Func&&>(
|
||||||
|
visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(static_cast<Func&&>(
|
||||||
|
visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
|
||||||
|
static_cast<value_ref>(v));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(val)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, value_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// visitor not compatible with this particular type
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keep_going)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief Invokes a visitor on each key-value pair in the table.
|
||||||
|
///
|
||||||
|
/// \tparam Func A callable type invocable with one of the following signatures:
|
||||||
|
/// <ul>
|
||||||
|
/// <li> `func(key, val)`
|
||||||
|
/// <li> `func(val)`
|
||||||
|
/// </ul>
|
||||||
|
/// Where:
|
||||||
|
/// <ul>
|
||||||
|
/// <li> `key` will recieve a const reference to a toml::key
|
||||||
|
/// <li> `val` will recieve the value as it's concrete type with cvref-qualifications matching the table
|
||||||
|
/// </ul>
|
||||||
|
/// Visitors returning `bool` (or something convertible to `bool`) will cause iteration to
|
||||||
|
/// stop if they return `false`.
|
||||||
|
///
|
||||||
|
/// \param visitor The visitor object.
|
||||||
|
///
|
||||||
|
/// \returns A reference to the table.
|
||||||
|
///
|
||||||
|
/// \details \cpp
|
||||||
|
/// toml::table tbl{
|
||||||
|
/// { "0", 0 },
|
||||||
|
/// { "1", 1 },
|
||||||
|
/// { "2", 2 },
|
||||||
|
/// { "3", 3.0 },
|
||||||
|
/// { "4", "four" },
|
||||||
|
/// { "5", "five" },
|
||||||
|
/// { "6", 6 }
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// // select only the integers using a strongly-typed visitor
|
||||||
|
/// tbl.for_each([](toml::value<int64_t>& val)
|
||||||
|
/// {
|
||||||
|
/// std::cout << val << ", ";
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n";
|
||||||
|
///
|
||||||
|
/// // select all the numeric values using a generic visitor + is_number<> metafunction
|
||||||
|
/// tbl.for_each([](auto&& val)
|
||||||
|
/// {
|
||||||
|
/// if constexpr (toml::is_number<decltype(val)>)
|
||||||
|
/// std::cout << val << ", ";
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n";
|
||||||
|
///
|
||||||
|
/// // select all the numeric values until we encounter something non-numeric
|
||||||
|
/// tbl.for_each([](auto&& val)
|
||||||
|
/// {
|
||||||
|
/// if constexpr (toml::is_number<decltype(val)>)
|
||||||
|
/// {
|
||||||
|
/// std::cout << val << ", ";
|
||||||
|
/// return true; // "keep going"
|
||||||
|
/// }
|
||||||
|
/// else
|
||||||
|
/// return false; // "stop!"
|
||||||
|
///
|
||||||
|
/// });
|
||||||
|
/// std::cout << "\n\n";
|
||||||
|
///
|
||||||
|
/// // visitors may also recieve the key
|
||||||
|
/// tbl.for_each([](const toml::key& key, auto&& val)
|
||||||
|
/// {
|
||||||
|
/// std::cout << key << ": " << val << "\n";
|
||||||
|
/// });
|
||||||
|
///
|
||||||
|
/// \ecpp
|
||||||
|
/// \out
|
||||||
|
/// 0, 1, 2, 6,
|
||||||
|
/// 0, 1, 2, 3.0, 6,
|
||||||
|
/// 0, 1, 2, 3.0,
|
||||||
|
///
|
||||||
|
/// 0: 0
|
||||||
|
/// 1: 1
|
||||||
|
/// 2: 2
|
||||||
|
/// 3: 3.0
|
||||||
|
/// 4: 'four'
|
||||||
|
/// 5: 'five'
|
||||||
|
/// 6: 6
|
||||||
|
/// \eout
|
||||||
|
///
|
||||||
|
/// \see node::visit()
|
||||||
|
template <typename Func>
|
||||||
|
table& for_each(Func&& visitor) & noexcept(for_each_is_nothrow<Func&&, table&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each key-value pair in the table (rvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
table&& for_each(Func&& visitor) && noexcept(for_each_is_nothrow<Func&&, table&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<table&&>(*this));
|
||||||
|
return static_cast<table&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each key-value pair in the table (const lvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
const table& for_each(Func&& visitor) const& noexcept(for_each_is_nothrow<Func&&, const table&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Invokes a visitor on each key-value pair in the table (const rvalue overload).
|
||||||
|
template <typename Func>
|
||||||
|
const table&& for_each(Func&& visitor) const&& noexcept(for_each_is_nothrow<Func&&, const table&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<const table&&>(*this));
|
||||||
|
return static_cast<const table&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \name Size and Capacity
|
/// \name Size and Capacity
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define TOML_LIB_MAJOR 3
|
#define TOML_LIB_MAJOR 3
|
||||||
#define TOML_LIB_MINOR 0
|
#define TOML_LIB_MINOR 1
|
||||||
#define TOML_LIB_PATCH 1
|
#define TOML_LIB_PATCH 0
|
||||||
|
|
||||||
#define TOML_LANG_MAJOR 1
|
#define TOML_LANG_MAJOR 1
|
||||||
#define TOML_LANG_MINOR 0
|
#define TOML_LANG_MINOR 0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
project(
|
project(
|
||||||
'tomlplusplus',
|
'tomlplusplus',
|
||||||
'cpp',
|
'cpp',
|
||||||
version: '3.0.1',
|
version: '3.1.0',
|
||||||
meson_version: '>=0.54.0',
|
meson_version: '>=0.54.0',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
subproject_dir: 'external',
|
subproject_dir: 'external',
|
||||||
|
@ -555,6 +555,12 @@ backslash = 'This string has a \\ backslash character.')"sv;
|
|||||||
static constexpr auto string_with_pound = R"(pound = "We see no # comments here."
|
static constexpr auto string_with_pound = R"(pound = "We see no # comments here."
|
||||||
poundcomment = "But there are # some comments here." # Did I # mess you up?)"sv;
|
poundcomment = "But there are # some comments here." # Did I # mess you up?)"sv;
|
||||||
|
|
||||||
|
#if TOML_LANG_UNRELEASED
|
||||||
|
|
||||||
|
static constexpr auto string_escape_esc = R"(esc = "\e There is no escape! \e")"sv;
|
||||||
|
|
||||||
|
#endif // TOML_LANG_UNRELEASED
|
||||||
|
|
||||||
#if UNICODE_LITERALS_OK
|
#if UNICODE_LITERALS_OK
|
||||||
|
|
||||||
static constexpr auto string_escape_tricky = R"(end_esc = "String does not end here\" but ends here\\"
|
static constexpr auto string_escape_tricky = R"(end_esc = "String does not end here\" but ends here\\"
|
||||||
@ -2287,6 +2293,20 @@ in it.)"sv },
|
|||||||
REQUIRE(tbl == expected);
|
REQUIRE(tbl == expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#if TOML_LANG_UNRELEASED
|
||||||
|
|
||||||
|
parsing_should_succeed(FILE_LINE_ARGS,
|
||||||
|
string_escape_esc,
|
||||||
|
[](toml::table&& tbl) // string-escape-esc
|
||||||
|
{
|
||||||
|
const auto expected = toml::table{
|
||||||
|
{ R"(esc)"sv, "\x1B There is no escape! \x1B"sv },
|
||||||
|
};
|
||||||
|
REQUIRE(tbl == expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
#endif // TOML_LANG_UNRELEASED
|
||||||
|
|
||||||
#if UNICODE_LITERALS_OK
|
#if UNICODE_LITERALS_OK
|
||||||
|
|
||||||
parsing_should_succeed(FILE_LINE_ARGS,
|
parsing_should_succeed(FILE_LINE_ARGS,
|
||||||
|
372
tests/for_each.cpp
Normal file
372
tests/for_each.cpp
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
// This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||||
|
// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||||
|
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include "tests.h"
|
||||||
|
TOML_DISABLE_SPAM_WARNINGS;
|
||||||
|
|
||||||
|
TEST_CASE("array::for_each")
|
||||||
|
{
|
||||||
|
toml::array arr{ 0, 1, 2, 3.0, "four", "five", 6 };
|
||||||
|
|
||||||
|
// check lvalue propagates correctly
|
||||||
|
static_cast<array&>(arr).for_each(
|
||||||
|
[](auto&& elem, size_t) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<array&>(arr).for_each(
|
||||||
|
[](size_t, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<array&>(arr).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check rvalue propagates correctly
|
||||||
|
static_cast<array&&>(arr).for_each(
|
||||||
|
[](auto&& elem, size_t) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<array&&>(arr).for_each(
|
||||||
|
[](size_t, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<array&&>(arr).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check const lvalue propagates correctly
|
||||||
|
static_cast<const array&>(arr).for_each(
|
||||||
|
[](auto&& elem, size_t) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const array&>(arr).for_each(
|
||||||
|
[](size_t, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const array&>(arr).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check const rvalue propagates correctly
|
||||||
|
static_cast<const array&&>(arr).for_each(
|
||||||
|
[](auto&& elem, size_t) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const array&&>(arr).for_each(
|
||||||
|
[](size_t, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const array&&>(arr).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check noexcept - func(elem, i)
|
||||||
|
{
|
||||||
|
static constexpr auto throwing_visitor = [](auto&&, size_t) noexcept(false) {};
|
||||||
|
static constexpr auto non_throwing_visitor = [](auto&&, size_t) noexcept(true) {};
|
||||||
|
static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check noexcept - func(i, elem)
|
||||||
|
{
|
||||||
|
static constexpr auto throwing_visitor = [](size_t, auto&&) noexcept(false) {};
|
||||||
|
static constexpr auto non_throwing_visitor = [](size_t, auto&&) noexcept(true) {};
|
||||||
|
static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check noexcept - func(elem)
|
||||||
|
{
|
||||||
|
static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
|
||||||
|
static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
|
||||||
|
static_assert(!noexcept(static_cast<array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const array&&>(arr).for_each(throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const array&&>(arr).for_each(non_throwing_visitor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the iteration actually does what it says on the box
|
||||||
|
{
|
||||||
|
toml::array arr2;
|
||||||
|
arr.for_each([&](const auto& val) { arr2.push_back(val); });
|
||||||
|
CHECK(arr == arr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that visitation works for a specific type
|
||||||
|
{
|
||||||
|
toml::array arr2;
|
||||||
|
arr.for_each([&](const toml::value<int64_t>& val) { arr2.push_back(val); });
|
||||||
|
CHECK(arr2 == toml::array{ 0, 1, 2, 6 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that early-stopping works
|
||||||
|
{
|
||||||
|
toml::array arr2;
|
||||||
|
arr.for_each(
|
||||||
|
[&](const auto& val)
|
||||||
|
{
|
||||||
|
if constexpr (!toml::is_number<decltype(val)>)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arr2.push_back(val);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CHECK(arr2 == toml::array{ 0, 1, 2, 3.0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("table::for_each")
|
||||||
|
{
|
||||||
|
table tbl{ { "zero", 0 }, //
|
||||||
|
{ "one", 1 }, //
|
||||||
|
{ "two", 2 }, //
|
||||||
|
{ "three", 3.0 }, //
|
||||||
|
{ "four", "four" }, //
|
||||||
|
{ "five", "five" }, //
|
||||||
|
{ "six", 6 } };
|
||||||
|
|
||||||
|
// check lvalue propagates correctly
|
||||||
|
static_cast<table&>(tbl).for_each(
|
||||||
|
[](const toml::key&, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<table&>(tbl).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check rvalue propagates correctly
|
||||||
|
static_cast<table&&>(tbl).for_each(
|
||||||
|
[](const toml::key&, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<table&&>(tbl).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(!std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check const lvalue propagates correctly
|
||||||
|
static_cast<const table&>(tbl).for_each(
|
||||||
|
[](const toml::key&, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const table&>(tbl).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_lvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check const rvalue propagates correctly
|
||||||
|
static_cast<const table&&>(tbl).for_each(
|
||||||
|
[](const toml::key&, auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
static_cast<const table&&>(tbl).for_each(
|
||||||
|
[](auto&& elem) noexcept
|
||||||
|
{
|
||||||
|
using elem_ref_type = decltype(elem);
|
||||||
|
static_assert(std::is_rvalue_reference_v<elem_ref_type>);
|
||||||
|
|
||||||
|
using elem_type = std::remove_reference_t<elem_ref_type>;
|
||||||
|
static_assert(std::is_const_v<elem_type>);
|
||||||
|
static_assert(!std::is_volatile_v<elem_type>);
|
||||||
|
});
|
||||||
|
|
||||||
|
// check noexcept - func(key, value)
|
||||||
|
{
|
||||||
|
static constexpr auto throwing_visitor = [](const toml::key&, auto&&) noexcept(false) {};
|
||||||
|
static constexpr auto non_throwing_visitor = [](const toml::key&, auto&&) noexcept(true) {};
|
||||||
|
static_assert(!noexcept(static_cast<table&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<table&&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const table&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const table&&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<table&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<table&&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const table&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const table&&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check noexcept - func(value)
|
||||||
|
{
|
||||||
|
static constexpr auto throwing_visitor = [](auto&&) noexcept(false) {};
|
||||||
|
static constexpr auto non_throwing_visitor = [](auto&&) noexcept(true) {};
|
||||||
|
static_assert(!noexcept(static_cast<table&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<table&&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const table&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(!noexcept(static_cast<const table&&>(tbl).for_each(throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<table&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<table&&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const table&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
static_assert(noexcept(static_cast<const table&&>(tbl).for_each(non_throwing_visitor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the iteration actually does what it says on the box
|
||||||
|
{
|
||||||
|
toml::table tbl2;
|
||||||
|
tbl.for_each([&](auto&& key, auto&& val) { tbl2.insert_or_assign(key, val); });
|
||||||
|
CHECK(tbl == tbl2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that visitation works for a specific type
|
||||||
|
{
|
||||||
|
toml::table tbl2;
|
||||||
|
tbl.for_each([&](auto&& key, const toml::value<int64_t>& val) { tbl2.insert_or_assign(key, val); });
|
||||||
|
CHECK(tbl2
|
||||||
|
== table{ { "zero", 0 }, //
|
||||||
|
{ "one", 1 }, //
|
||||||
|
{ "two", 2 }, //
|
||||||
|
{ "six", 6 } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that early-stopping works
|
||||||
|
{
|
||||||
|
toml::table tbl2;
|
||||||
|
size_t added{};
|
||||||
|
tbl.for_each(
|
||||||
|
[&](auto&& key, const auto& val)
|
||||||
|
{
|
||||||
|
tbl2.insert_or_assign(key, val);
|
||||||
|
added++;
|
||||||
|
return added < 3u;
|
||||||
|
});
|
||||||
|
CHECK(tbl2.size() == 3u);
|
||||||
|
}
|
||||||
|
}
|
@ -5,25 +5,27 @@ test_sources = [
|
|||||||
'conformance_iarna_invalid.cpp',
|
'conformance_iarna_invalid.cpp',
|
||||||
'conformance_iarna_valid.cpp',
|
'conformance_iarna_valid.cpp',
|
||||||
'formatters.cpp',
|
'formatters.cpp',
|
||||||
|
'for_each.cpp',
|
||||||
'impl_toml.cpp',
|
'impl_toml.cpp',
|
||||||
'tests.cpp',
|
'main.cpp',
|
||||||
'parsing_floats.cpp',
|
'manipulating_arrays.cpp',
|
||||||
|
'manipulating_parse_result.cpp',
|
||||||
|
'manipulating_tables.cpp',
|
||||||
|
'manipulating_values.cpp',
|
||||||
'parsing_arrays.cpp',
|
'parsing_arrays.cpp',
|
||||||
'parsing_booleans.cpp',
|
'parsing_booleans.cpp',
|
||||||
'parsing_comments.cpp',
|
'parsing_comments.cpp',
|
||||||
'parsing_dates_and_times.cpp',
|
'parsing_dates_and_times.cpp',
|
||||||
|
'parsing_floats.cpp',
|
||||||
'parsing_integers.cpp',
|
'parsing_integers.cpp',
|
||||||
'parsing_key_value_pairs.cpp',
|
'parsing_key_value_pairs.cpp',
|
||||||
'parsing_spec_example.cpp',
|
'parsing_spec_example.cpp',
|
||||||
'parsing_strings.cpp',
|
'parsing_strings.cpp',
|
||||||
'parsing_tables.cpp',
|
'parsing_tables.cpp',
|
||||||
'main.cpp',
|
'tests.cpp',
|
||||||
'manipulating_arrays.cpp',
|
|
||||||
'manipulating_tables.cpp',
|
|
||||||
'manipulating_values.cpp',
|
|
||||||
'visit.cpp',
|
|
||||||
'user_feedback.cpp',
|
'user_feedback.cpp',
|
||||||
'using_iterators.cpp',
|
'using_iterators.cpp',
|
||||||
|
'visit.cpp',
|
||||||
'windows_compat.cpp'
|
'windows_compat.cpp'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
@ -78,6 +78,7 @@
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
495
toml.hpp
495
toml.hpp
@ -1,6 +1,6 @@
|
|||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// toml++ v3.0.1
|
// toml++ v3.1.0
|
||||||
// https://github.com/marzer/tomlplusplus
|
// https://github.com/marzer/tomlplusplus
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
//
|
//
|
||||||
@ -846,8 +846,8 @@
|
|||||||
//******** impl/version.h ********************************************************************************************
|
//******** impl/version.h ********************************************************************************************
|
||||||
|
|
||||||
#define TOML_LIB_MAJOR 3
|
#define TOML_LIB_MAJOR 3
|
||||||
#define TOML_LIB_MINOR 0
|
#define TOML_LIB_MINOR 1
|
||||||
#define TOML_LIB_PATCH 1
|
#define TOML_LIB_PATCH 0
|
||||||
|
|
||||||
#define TOML_LANG_MAJOR 1
|
#define TOML_LANG_MAJOR 1
|
||||||
#define TOML_LANG_MINOR 0
|
#define TOML_LANG_MINOR 0
|
||||||
@ -1892,6 +1892,10 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
};
|
};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
|
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
|
||||||
|
|
||||||
|
template <typename T, typename ConvertFrom>
|
||||||
|
inline constexpr bool is_constructible_or_convertible = std::is_constructible_v<T, ConvertFrom> //
|
||||||
|
|| std::is_convertible_v<ConvertFrom, T>;
|
||||||
}
|
}
|
||||||
TOML_IMPL_NAMESPACE_END;
|
TOML_IMPL_NAMESPACE_END;
|
||||||
|
|
||||||
@ -1951,8 +1955,8 @@ TOML_NAMESPACE_START
|
|||||||
inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
|
inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_node =
|
inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
|
||||||
std::is_same_v<toml::node, impl::remove_cvref<T>> || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
|
|| std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
|
inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
|
||||||
@ -2990,145 +2994,141 @@ TOML_NAMESPACE_START
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
template <typename Func, typename Node, typename T>
|
||||||
|
static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Node, typename T>
|
||||||
|
static constexpr bool can_visit_nothrow = std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Node>
|
||||||
|
static constexpr bool can_visit_any = can_visit<Func, Node, table> //
|
||||||
|
|| can_visit<Func, Node, array> //
|
||||||
|
|| can_visit<Func, Node, std::string> //
|
||||||
|
|| can_visit<Func, Node, int64_t> //
|
||||||
|
|| can_visit<Func, Node, double> //
|
||||||
|
|| can_visit<Func, Node, bool> //
|
||||||
|
|| can_visit<Func, Node, date> //
|
||||||
|
|| can_visit<Func, Node, time> //
|
||||||
|
|| can_visit<Func, Node, date_time>;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node>
|
||||||
static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, N>>;
|
static constexpr bool can_visit_all = can_visit<Func, Node, table> //
|
||||||
|
&& can_visit<Func, Node, array> //
|
||||||
|
&& can_visit<Func, Node, std::string> //
|
||||||
|
&& can_visit<Func, Node, int64_t> //
|
||||||
|
&& can_visit<Func, Node, double> //
|
||||||
|
&& can_visit<Func, Node, bool> //
|
||||||
|
&& can_visit<Func, Node, date> //
|
||||||
|
&& can_visit<Func, Node, time> //
|
||||||
|
&& can_visit<Func, Node, date_time>;
|
||||||
|
|
||||||
template <typename Func, typename N>
|
template <typename Func, typename Node, typename T>
|
||||||
static constexpr bool can_visit_any =
|
static constexpr bool visit_is_nothrow_one = !can_visit<Func, Node, T> || can_visit_nothrow<Func, Node, T>;
|
||||||
can_visit<Func, N, table>
|
|
||||||
|| can_visit<Func, N, array>
|
|
||||||
|| can_visit<Func, N, std::string>
|
|
||||||
|| can_visit<Func, N, int64_t>
|
|
||||||
|| can_visit<Func, N, double>
|
|
||||||
|| can_visit<Func, N, bool>
|
|
||||||
|| can_visit<Func, N, date>
|
|
||||||
|| can_visit<Func, N, time>
|
|
||||||
|| can_visit<Func, N, date_time>;
|
|
||||||
|
|
||||||
template <typename Func, typename N>
|
template <typename Func, typename Node>
|
||||||
static constexpr bool can_visit_all =
|
static constexpr bool visit_is_nothrow = visit_is_nothrow_one<Func, Node, table> //
|
||||||
can_visit<Func, N, table>
|
&& visit_is_nothrow_one<Func, Node, array> //
|
||||||
&& can_visit<Func, N, array>
|
&& visit_is_nothrow_one<Func, Node, std::string> //
|
||||||
&& can_visit<Func, N, std::string>
|
&& visit_is_nothrow_one<Func, Node, int64_t> //
|
||||||
&& can_visit<Func, N, int64_t>
|
&& visit_is_nothrow_one<Func, Node, double> //
|
||||||
&& can_visit<Func, N, double>
|
&& visit_is_nothrow_one<Func, Node, bool> //
|
||||||
&& can_visit<Func, N, bool>
|
&& visit_is_nothrow_one<Func, Node, date> //
|
||||||
&& can_visit<Func, N, date>
|
&& visit_is_nothrow_one<Func, Node, time> //
|
||||||
&& can_visit<Func, N, time>
|
&& visit_is_nothrow_one<Func, Node, date_time>;
|
||||||
&& can_visit<Func, N, date_time>;
|
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
|
||||||
static constexpr bool visit_is_nothrow_one =
|
|
||||||
!can_visit<Func, N, T>
|
|
||||||
|| std::is_nothrow_invocable_v<Func, ref_cast_type<T, N>>;
|
|
||||||
|
|
||||||
template <typename Func, typename N>
|
|
||||||
static constexpr bool visit_is_nothrow =
|
|
||||||
visit_is_nothrow_one<Func, N, table>
|
|
||||||
&& visit_is_nothrow_one<Func, N, array>
|
|
||||||
&& visit_is_nothrow_one<Func, N, std::string>
|
|
||||||
&& visit_is_nothrow_one<Func, N, int64_t>
|
|
||||||
&& visit_is_nothrow_one<Func, N, double>
|
|
||||||
&& visit_is_nothrow_one<Func, N, bool>
|
|
||||||
&& visit_is_nothrow_one<Func, N, date>
|
|
||||||
&& visit_is_nothrow_one<Func, N, time>
|
|
||||||
&& visit_is_nothrow_one<Func, N, date_time>;
|
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
template <typename Func, typename N, typename T, bool = can_visit<Func, N, T>>
|
template <typename Func, typename Node, typename T, bool = can_visit<Func, Node, T>>
|
||||||
struct visit_return_type_
|
struct visit_return_type_
|
||||||
{
|
{
|
||||||
using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, N>>()));
|
using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
|
||||||
};
|
};
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node, typename T>
|
||||||
struct visit_return_type_<Func, N, T, false>
|
struct visit_return_type_<Func, Node, T, false>
|
||||||
{
|
{
|
||||||
using type = void;
|
using type = void;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Func, typename N, typename T>
|
template <typename Func, typename Node, typename T>
|
||||||
using visit_return_type = typename visit_return_type_<Func, N, T>::type;
|
using visit_return_type = typename visit_return_type_<Func, Node, T>::type;
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
|
using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
|
||||||
|
|
||||||
template <typename N, typename Func>
|
template <typename Func, typename Node>
|
||||||
static decltype(auto) do_visit(N&& n, Func&& visitor) noexcept(visit_is_nothrow<Func&&, N&&>)
|
static decltype(auto) do_visit(Func&& visitor, Node&& n) noexcept(visit_is_nothrow<Func&&, Node&&>)
|
||||||
{
|
{
|
||||||
static_assert(can_visit_any<Func&&, N&&>,
|
static_assert(can_visit_any<Func&&, Node&&>,
|
||||||
"TOML node visitors must be invocable for at least one of the toml::node "
|
"TOML node visitors must be invocable for at least one of the toml::node "
|
||||||
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
switch (n.type())
|
switch (n.type())
|
||||||
{
|
{
|
||||||
case node_type::table:
|
case node_type::table:
|
||||||
if constexpr (can_visit<Func&&, N&&, table>)
|
if constexpr (can_visit<Func&&, Node&&, table>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<table>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<table>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::array:
|
case node_type::array:
|
||||||
if constexpr (can_visit<Func&&, N&&, array>)
|
if constexpr (can_visit<Func&&, Node&&, array>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<array>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<array>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::string:
|
case node_type::string:
|
||||||
if constexpr (can_visit<Func&&, N&&, std::string>)
|
if constexpr (can_visit<Func&&, Node&&, std::string>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<std::string>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<std::string>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::integer:
|
case node_type::integer:
|
||||||
if constexpr (can_visit<Func&&, N&&, int64_t>)
|
if constexpr (can_visit<Func&&, Node&&, int64_t>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<int64_t>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<int64_t>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::floating_point:
|
case node_type::floating_point:
|
||||||
if constexpr (can_visit<Func&&, N&&, double>)
|
if constexpr (can_visit<Func&&, Node&&, double>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<double>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<double>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::boolean:
|
case node_type::boolean:
|
||||||
if constexpr (can_visit<Func&&, N&&, bool>)
|
if constexpr (can_visit<Func&&, Node&&, bool>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<bool>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<bool>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::date:
|
case node_type::date:
|
||||||
if constexpr (can_visit<Func&&, N&&, date>)
|
if constexpr (can_visit<Func&&, Node&&, date>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::time:
|
case node_type::time:
|
||||||
if constexpr (can_visit<Func&&, N&&, time>)
|
if constexpr (can_visit<Func&&, Node&&, time>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<time>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<time>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::date_time:
|
case node_type::date_time:
|
||||||
if constexpr (can_visit<Func&&, N&&, date_time>)
|
if constexpr (can_visit<Func&&, Node&&, date_time>)
|
||||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date_time>());
|
return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date_time>());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case node_type::none: TOML_UNREACHABLE;
|
case node_type::none: TOML_UNREACHABLE;
|
||||||
default: TOML_UNREACHABLE;
|
default: TOML_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (can_visit_all<Func&&, N&&>)
|
if constexpr (!can_visit_all<Func&&, Node&&>)
|
||||||
TOML_UNREACHABLE;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
using return_type =
|
using return_type =
|
||||||
nonvoid<visit_return_type<Func&&, N&&, table>,
|
nonvoid<visit_return_type<Func&&, Node&&, table>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, array>,
|
nonvoid<visit_return_type<Func&&, Node&&, array>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, std::string>,
|
nonvoid<visit_return_type<Func&&, Node&&, std::string>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, int64_t>,
|
nonvoid<visit_return_type<Func&&, Node&&, int64_t>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, double>,
|
nonvoid<visit_return_type<Func&&, Node&&, double>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, bool>,
|
nonvoid<visit_return_type<Func&&, Node&&, bool>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, date>,
|
nonvoid<visit_return_type<Func&&, Node&&, date>,
|
||||||
nonvoid<visit_return_type<Func&&, N&&, time>,
|
nonvoid<visit_return_type<Func&&, Node&&, time>,
|
||||||
visit_return_type<Func&&, N&&, date_time>
|
visit_return_type<Func&&, Node&&, date_time>
|
||||||
>>>>>>>>;
|
>>>>>>>>;
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@ -3147,25 +3147,25 @@ TOML_NAMESPACE_START
|
|||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
|
||||||
{
|
{
|
||||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||||
{
|
{
|
||||||
return do_visit(static_cast<node&&>(*this), static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), static_cast<node&&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||||
{
|
{
|
||||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>)
|
decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>)
|
||||||
{
|
{
|
||||||
return do_visit(static_cast<const node&&>(*this), static_cast<Func&&>(visitor));
|
return do_visit(static_cast<Func&&>(visitor), static_cast<const node&&>(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
@ -5564,6 +5564,166 @@ TOML_NAMESPACE_START
|
|||||||
return const_iterator{ elems_.cend() };
|
return const_iterator{ elems_.cend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename T, typename Array>
|
||||||
|
using for_each_elem_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool can_for_each = std::is_invocable_v<Func, for_each_elem_ref<T, Array>, size_t> //
|
||||||
|
|| std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>> //
|
||||||
|
|| std::is_invocable_v<Func, for_each_elem_ref<T, Array>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool can_for_each_nothrow =
|
||||||
|
std::is_nothrow_invocable_v<Func, for_each_elem_ref<T, Array>, size_t> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, size_t, for_each_elem_ref<T, Array>> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, for_each_elem_ref<T, Array>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static constexpr bool can_for_each_any = can_for_each<Func, Array, table> //
|
||||||
|
|| can_for_each<Func, Array, array> //
|
||||||
|
|| can_for_each<Func, Array, std::string> //
|
||||||
|
|| can_for_each<Func, Array, int64_t> //
|
||||||
|
|| can_for_each<Func, Array, double> //
|
||||||
|
|| can_for_each<Func, Array, bool> //
|
||||||
|
|| can_for_each<Func, Array, date> //
|
||||||
|
|| can_for_each<Func, Array, time> //
|
||||||
|
|| can_for_each<Func, Array, date_time>;
|
||||||
|
|
||||||
|
template <typename Func, typename Array, typename T>
|
||||||
|
static constexpr bool for_each_is_nothrow_one = !can_for_each<Func, Array, T> //
|
||||||
|
|| can_for_each_nothrow<Func, Array, T>;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static constexpr bool for_each_is_nothrow = for_each_is_nothrow_one<Func, Array, table> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, array> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, std::string> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, int64_t> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, double> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, bool> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, date> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, time> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Array, date_time>;
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
template <typename Func, typename Array>
|
||||||
|
static void do_for_each(Func&& visitor, Array&& arr) noexcept(for_each_is_nothrow<Func&&, Array&&>)
|
||||||
|
{
|
||||||
|
static_assert(can_for_each_any<Func&&, Array&&>,
|
||||||
|
"TOML array for_each visitors must be invocable for at least one of the toml::node "
|
||||||
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arr.size(); i++)
|
||||||
|
{
|
||||||
|
using node_ref = impl::copy_cvref<toml::node, Array&&>;
|
||||||
|
static_assert(std::is_reference_v<node_ref>);
|
||||||
|
|
||||||
|
const auto keep_going =
|
||||||
|
static_cast<node_ref>(static_cast<Array&&>(arr)[i])
|
||||||
|
.visit(
|
||||||
|
[&](auto&& elem) noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>)
|
||||||
|
{
|
||||||
|
using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
|
||||||
|
static_assert(std::is_reference_v<elem_ref>);
|
||||||
|
|
||||||
|
// func(elem, i)
|
||||||
|
if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(i, elem)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(elem)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// visitor not compatible with this particular type
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keep_going)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
array& for_each(Func&& visitor) & noexcept(for_each_is_nothrow<Func&&, array&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
array&& for_each(Func&& visitor) && noexcept(for_each_is_nothrow<Func&&, array&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<array&&>(*this));
|
||||||
|
return static_cast<array&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
const array& for_each(Func&& visitor) const& noexcept(for_each_is_nothrow<Func&&, const array&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
const array&& for_each(Func&& visitor) const&& noexcept(for_each_is_nothrow<Func&&, const array&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<const array&&>(*this));
|
||||||
|
return static_cast<const array&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
bool empty() const noexcept
|
bool empty() const noexcept
|
||||||
{
|
{
|
||||||
@ -6115,8 +6275,8 @@ TOML_NAMESPACE_START
|
|||||||
inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>;
|
inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_key_or_convertible =
|
inline constexpr bool is_key_or_convertible = is_key<T> //
|
||||||
is_key<T> || std::is_constructible_v<toml::key, T> || std::is_convertible_v<T, toml::key>;
|
|| impl::is_constructible_or_convertible<toml::key, T>;
|
||||||
}
|
}
|
||||||
TOML_NAMESPACE_END;
|
TOML_NAMESPACE_END;
|
||||||
|
|
||||||
@ -6316,6 +6476,7 @@ TOML_NAMESPACE_START
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
|
using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
|
||||||
|
using map_pair = std::pair<const toml::key, impl::node_ptr>;
|
||||||
using map_iterator = typename map_type::iterator;
|
using map_iterator = typename map_type::iterator;
|
||||||
using const_map_iterator = typename map_type::const_iterator;
|
using const_map_iterator = typename map_type::const_iterator;
|
||||||
map_type map_;
|
map_type map_;
|
||||||
@ -6709,6 +6870,149 @@ TOML_NAMESPACE_START
|
|||||||
return const_iterator{ map_.cend() };
|
return const_iterator{ map_.cend() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename T, typename Table>
|
||||||
|
using for_each_value_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool can_for_each = std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>> //
|
||||||
|
|| std::is_invocable_v<Func, for_each_value_ref<T, Table>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool can_for_each_nothrow =
|
||||||
|
std::is_nothrow_invocable_v<Func, const key&, for_each_value_ref<T, Table>> //
|
||||||
|
|| std::is_nothrow_invocable_v<Func, for_each_value_ref<T, Table>>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static constexpr bool can_for_each_any = can_for_each<Func, Table, table> //
|
||||||
|
|| can_for_each<Func, Table, array> //
|
||||||
|
|| can_for_each<Func, Table, std::string> //
|
||||||
|
|| can_for_each<Func, Table, int64_t> //
|
||||||
|
|| can_for_each<Func, Table, double> //
|
||||||
|
|| can_for_each<Func, Table, bool> //
|
||||||
|
|| can_for_each<Func, Table, date> //
|
||||||
|
|| can_for_each<Func, Table, time> //
|
||||||
|
|| can_for_each<Func, Table, date_time>;
|
||||||
|
|
||||||
|
template <typename Func, typename Table, typename T>
|
||||||
|
static constexpr bool for_each_is_nothrow_one = !can_for_each<Func, Table, T> //
|
||||||
|
|| can_for_each_nothrow<Func, Table, T>;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static constexpr bool for_each_is_nothrow = for_each_is_nothrow_one<Func, Table, table> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, array> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, std::string> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, int64_t> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, double> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, bool> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, date> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, time> //
|
||||||
|
&& for_each_is_nothrow_one<Func, Table, date_time>;
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
template <typename Func, typename Table>
|
||||||
|
static void do_for_each(Func&& visitor, Table&& tbl) noexcept(for_each_is_nothrow<Func&&, Table&&>)
|
||||||
|
{
|
||||||
|
static_assert(can_for_each_any<Func&&, Table&&>,
|
||||||
|
"TOML table for_each visitors must be invocable for at least one of the toml::node "
|
||||||
|
"specializations:" TOML_SA_NODE_TYPE_LIST);
|
||||||
|
|
||||||
|
using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
|
||||||
|
|
||||||
|
for (kvp_type& kvp : tbl.map_)
|
||||||
|
{
|
||||||
|
using node_ref = impl::copy_cvref<toml::node, Table&&>;
|
||||||
|
static_assert(std::is_reference_v<node_ref>);
|
||||||
|
|
||||||
|
const auto keep_going =
|
||||||
|
static_cast<node_ref>(*kvp.second)
|
||||||
|
.visit(
|
||||||
|
[&](auto&& v) noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>)
|
||||||
|
{
|
||||||
|
using value_ref = for_each_value_ref<decltype(v), Table&&>;
|
||||||
|
static_assert(std::is_reference_v<value_ref>);
|
||||||
|
|
||||||
|
// func(key, val)
|
||||||
|
if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
|
||||||
|
{
|
||||||
|
using return_type = decltype(static_cast<Func&&>(
|
||||||
|
visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(static_cast<Func&&>(
|
||||||
|
visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
|
||||||
|
static_cast<value_ref>(v));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func(val)
|
||||||
|
else if constexpr (std::is_invocable_v<Func&&, value_ref>)
|
||||||
|
{
|
||||||
|
using return_type =
|
||||||
|
decltype(static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
|
||||||
|
|
||||||
|
if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
|
||||||
|
{
|
||||||
|
return static_cast<bool>(
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// visitor not compatible with this particular type
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keep_going)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
table& for_each(Func&& visitor) & noexcept(for_each_is_nothrow<Func&&, table&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
table&& for_each(Func&& visitor) && noexcept(for_each_is_nothrow<Func&&, table&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<table&&>(*this));
|
||||||
|
return static_cast<table&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
const table& for_each(Func&& visitor) const& noexcept(for_each_is_nothrow<Func&&, const table&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), *this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
const table&& for_each(Func&& visitor) const&& noexcept(for_each_is_nothrow<Func&&, const table&&>)
|
||||||
|
{
|
||||||
|
do_for_each(static_cast<Func&&>(visitor), static_cast<const table&&>(*this));
|
||||||
|
return static_cast<const table&&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
TOML_PURE_INLINE_GETTER
|
TOML_PURE_INLINE_GETTER
|
||||||
bool empty() const noexcept
|
bool empty() const noexcept
|
||||||
{
|
{
|
||||||
@ -9190,16 +9494,13 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
if ((!lhs != !rhs) || lhs->type() != rhs->type())
|
if ((!lhs != !rhs) || lhs->type() != rhs->type())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool same;
|
return lhs->visit(
|
||||||
lhs->visit(
|
[=](auto& l) noexcept
|
||||||
[=, &same](auto& l) noexcept
|
|
||||||
{
|
{
|
||||||
using concrete_type = remove_cvref<decltype(l)>;
|
using concrete_type = remove_cvref<decltype(l)>;
|
||||||
|
|
||||||
same = (l == *(rhs->as<concrete_type>()));
|
return l == *(rhs->as<concrete_type>());
|
||||||
});
|
});
|
||||||
|
|
||||||
return same;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TOML_IMPL_NAMESPACE_END;
|
TOML_IMPL_NAMESPACE_END;
|
||||||
|
@ -446,6 +446,9 @@ def load_valid_inputs(tests, extern_root):
|
|||||||
add_condition(tests['valid']['burntsushi'], '!TOML_MSVC', (
|
add_condition(tests['valid']['burntsushi'], '!TOML_MSVC', (
|
||||||
'inline-table-key-dotted', # causes MSVC to run out of heap space during compilation O_o
|
'inline-table-key-dotted', # causes MSVC to run out of heap space during compilation O_o
|
||||||
))
|
))
|
||||||
|
add_condition(tests['valid']['burntsushi'], 'TOML_LANG_UNRELEASED', (
|
||||||
|
'string-escape-esc', # \e in strings
|
||||||
|
))
|
||||||
|
|
||||||
tests['valid']['iarna'] = load_tests(Path(extern_root, 'toml-spec-tests', 'values'), True, (
|
tests['valid']['iarna'] = load_tests(Path(extern_root, 'toml-spec-tests', 'values'), True, (
|
||||||
# these are stress-tests for 'large' datasets. I test these separately. Having them inline in C++ code is insane.
|
# these are stress-tests for 'large' datasets. I test these separately. Having them inline in C++ code is insane.
|
||||||
|
@ -121,6 +121,7 @@ def main():
|
|||||||
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
<ClCompile Include="..\conformance_iarna_invalid.cpp" />
|
||||||
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
<ClCompile Include="..\conformance_iarna_valid.cpp" />
|
||||||
|
<ClCompile Include="..\for_each.cpp" />
|
||||||
<ClCompile Include="..\formatters.cpp" />
|
<ClCompile Include="..\formatters.cpp" />
|
||||||
<ClCompile Include="..\impl_toml.cpp">
|
<ClCompile Include="..\impl_toml.cpp">
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
Loading…
Reference in New Issue
Block a user