mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-04 14:09:11 +00:00
added additional metafunctions
also: - reduced bloat by removing unnecessary std::forwards and std::moves - minor cleanup of example code
This commit is contained in:
parent
7bf8c03f7a
commit
6135deb6a3
@ -2,26 +2,21 @@
|
||||
// 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
|
||||
/*
|
||||
|
||||
This example is one of diagnostics; it forces a set of specific parsing
|
||||
failures and prints their error messages to stdout so you can see what the
|
||||
default error messages look like.
|
||||
// This example shows the error messages the library produces by forcing a set of specific parsing
|
||||
// failures and printing their results.
|
||||
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "utf8_console.h"
|
||||
#include "examples.h"
|
||||
|
||||
#define TOML_EXCEPTIONS 0
|
||||
#define TOML_UNRELEASED_FEATURES 0
|
||||
#include <toml++/toml.h>
|
||||
|
||||
using namespace std::string_view_literals;
|
||||
using toml::operator""_sz;
|
||||
|
||||
namespace
|
||||
{
|
||||
inline constexpr std::string_view invalid_parses[] =
|
||||
inline constexpr auto invalid_parses = std::array
|
||||
{
|
||||
"########## comments"sv,
|
||||
"# bar\rkek"sv,
|
||||
@ -104,44 +99,36 @@ namespace
|
||||
"########## floats"sv,
|
||||
R"(val = 9999999999999999999999999999999999999999999999999999999999999995.0)"sv,
|
||||
};
|
||||
|
||||
inline constexpr auto divider =
|
||||
"################################################################################"sv;
|
||||
}
|
||||
|
||||
|
||||
int main(int /*argc*/, char** /*argv*/)
|
||||
int main()
|
||||
{
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
init_utf8_console();
|
||||
examples::init();
|
||||
|
||||
for (auto str : invalid_parses)
|
||||
{
|
||||
if (str.empty())
|
||||
continue;
|
||||
|
||||
if (str.substr(0_sz, 10_sz) == "##########"sv)
|
||||
// section headings
|
||||
if (str.substr(0, 10) == "##########"sv)
|
||||
{
|
||||
const auto substr = str.substr(11_sz);
|
||||
size_t cols = 80_sz;
|
||||
for (size_t i = (cols - substr.length()) / 2_sz - 1_sz; i-- > 0_sz; )
|
||||
{
|
||||
std::cout.put('#');
|
||||
cols--;
|
||||
}
|
||||
std::cout.put(' ');
|
||||
std::cout << substr;
|
||||
std::cout.put(' ');
|
||||
cols -= substr.length() + 2_sz;
|
||||
while (cols--)
|
||||
std::cout.put('#');
|
||||
|
||||
std::cout << "\n\n"sv;
|
||||
std::cout << divider << '\n';
|
||||
std::cout << "# "sv << str.substr(11) << '\n';
|
||||
std::cout << divider << "\n\n"sv;
|
||||
}
|
||||
|
||||
// error messages
|
||||
else
|
||||
{
|
||||
toml::parse_result result;
|
||||
|
||||
if (str == "PATHOLOGICALLY_NESTED"sv)
|
||||
{
|
||||
std::string s(1000_sz, '[');
|
||||
std::string s(1000u, '[');
|
||||
constexpr auto start = "array = "sv;
|
||||
memcpy(s.data(), start.data(), start.length());
|
||||
result = toml::parse(s);
|
||||
@ -150,10 +137,7 @@ int main(int /*argc*/, char** /*argv*/)
|
||||
result = toml::parse(str);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
std::cout << result.error();
|
||||
std::cout << "\n\n"sv;
|
||||
}
|
||||
std::cout << result.error() << "\n\n"sv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -51,5 +51,11 @@
|
||||
<ItemGroup>
|
||||
<None Include="meson.build" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="examples.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
52
examples/examples.h
Normal file
52
examples/examples.h
Normal file
@ -0,0 +1,52 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 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
|
||||
|
||||
// this file is for boilerplate unrelated to the toml++ example learning outcomes.
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Weverything"
|
||||
#elif defined (__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wall"
|
||||
#pragma GCC diagnostic ignored "-Wextra"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push, 0)
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace examples
|
||||
{
|
||||
inline void init() noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(65001); //CP_UTF8
|
||||
#endif
|
||||
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
std::cout << std::boolalpha;
|
||||
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
}
|
||||
}
|
@ -2,14 +2,10 @@
|
||||
// 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
|
||||
/*
|
||||
|
||||
This example demonstrates how to parse TOML from a file and
|
||||
re-serialize it (print it out) to stdout.
|
||||
// This example demonstrates how to parse TOML from a file and re-serialize it (print it out) to stdout.
|
||||
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "utf8_console.h"
|
||||
#include "examples.h"
|
||||
|
||||
#define TOML_UNRELEASED_FEATURES 1
|
||||
#include <toml++/toml.h>
|
||||
@ -18,14 +14,13 @@ using namespace std::string_view_literals;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
init_utf8_console();
|
||||
examples::init();
|
||||
|
||||
auto path = std::string{ argc > 1 ? argv[1] : "example.toml" };
|
||||
const auto path = argc > 1 ? std::string_view{ argv[1] } : "example.toml"sv;
|
||||
try
|
||||
{
|
||||
const auto tbl = toml::parse_file(path);
|
||||
std::cout << tbl << "\n";
|
||||
const auto table = toml::parse_file(path);
|
||||
std::cout << table << "\n";
|
||||
}
|
||||
catch (const toml::parse_error& err)
|
||||
{
|
||||
|
@ -52,5 +52,11 @@
|
||||
<ItemGroup>
|
||||
<Natvis Include="..\toml++.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="examples.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
@ -2,17 +2,10 @@
|
||||
// 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
|
||||
/*
|
||||
|
||||
This example demonstrates some slightly advanced techniques
|
||||
being used to randomly generate a tree of TOML data.
|
||||
// This example demonstrates the use of some more advanced features to generate a tree of random TOML data.
|
||||
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <array>
|
||||
#include <ctime>
|
||||
#include "utf8_console.h"
|
||||
#include "examples.h"
|
||||
|
||||
#define TOML_PARSER 0
|
||||
#include <toml++/toml.h>
|
||||
@ -63,7 +56,7 @@ namespace
|
||||
[[nodiscard]]
|
||||
static T rand(T excl_max) noexcept
|
||||
{
|
||||
return static_cast<T>(static_cast<T>(::rand()) % excl_max);
|
||||
return static_cast<T>(static_cast<T>(std::rand()) % excl_max);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -107,12 +100,9 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
init_utf8_console();
|
||||
srand(static_cast<unsigned int>(time(nullptr)));
|
||||
examples::init();
|
||||
|
||||
int node_budget{};
|
||||
for (int i = 1; i < argc; i++)
|
||||
@ -132,34 +122,48 @@ int main(int argc, char** argv)
|
||||
int container_min_values = 10;
|
||||
bool in_arr = false;
|
||||
|
||||
const auto add = [&](auto&& obj) noexcept -> toml::node&
|
||||
const auto add = [&](auto&& val) noexcept -> auto&
|
||||
{
|
||||
using value_ref = decltype(val);
|
||||
using value_type = std::remove_reference_t<value_ref>;
|
||||
using node_type = toml::inserted_type_of<value_type>;
|
||||
|
||||
toml::node* new_node{};
|
||||
|
||||
// we're adding an element to an array
|
||||
if (auto arr = tree.back()->as_array())
|
||||
{
|
||||
arr->push_back(std::forward<decltype(obj)>(obj));
|
||||
arr->push_back(std::forward<value_ref>(val));
|
||||
new_node = &arr->back();
|
||||
}
|
||||
else
|
||||
new_node = &(*tree.back()->ref<toml::table>().insert_or_assign(
|
||||
rand_string(rand<size_t>(1u, 4u), '-'),
|
||||
std::forward<decltype(obj)>(obj)
|
||||
).first).second;
|
||||
|
||||
if constexpr (toml::is_array<decltype(obj)> || toml::is_table<decltype(obj)>)
|
||||
// we're adding a new kvp to a table
|
||||
else
|
||||
{
|
||||
auto& table = tree.back()->ref<toml::table>();
|
||||
|
||||
const auto it = table.insert_or_assign(
|
||||
rand_string(rand<size_t>(1u, 4u), '-'),
|
||||
std::forward<value_ref>(val)
|
||||
);
|
||||
|
||||
new_node = &it.first->second;
|
||||
}
|
||||
|
||||
// we added a new array or table, so now we need to step into it
|
||||
if constexpr (toml::is_container<value_type>)
|
||||
{
|
||||
tree.push_back(new_node);
|
||||
container_min_values = rand(1, 4);
|
||||
in_arr = toml::is_array<decltype(obj)>;
|
||||
if constexpr (toml::is_array<decltype(obj)>)
|
||||
in_arr = toml::is_array<value_type>;
|
||||
if constexpr (toml::is_array<value_type>)
|
||||
tree.back()->as_array()->reserve(static_cast<size_t>(container_min_values));
|
||||
}
|
||||
else
|
||||
container_min_values--;
|
||||
|
||||
node_budget--;
|
||||
return *new_node;
|
||||
return *new_node->as<node_type>();
|
||||
};
|
||||
|
||||
while (node_budget)
|
||||
@ -167,7 +171,7 @@ int main(int argc, char** argv)
|
||||
if (!in_arr && rand(100) >= 75)
|
||||
{
|
||||
if (container_min_values <= 0 && tree.size() < max_depth)
|
||||
add(toml::table{}).ref<toml::table>().is_inline(tree.size() >= max_depth - 2u && rand(100) >= 85);
|
||||
add(toml::table{}).is_inline(tree.size() >= max_depth - 2u && rand(100) >= 85);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -179,41 +183,41 @@ int main(int argc, char** argv)
|
||||
|
||||
switch (new_node_type)
|
||||
{
|
||||
case toml::node_type::array:
|
||||
if (container_min_values <= 0 && tree.size() < max_depth)
|
||||
add(toml::array{});
|
||||
break;
|
||||
case toml::node_type::array:
|
||||
if (container_min_values <= 0 && tree.size() < max_depth)
|
||||
add(toml::array{});
|
||||
break;
|
||||
|
||||
case toml::node_type::string:
|
||||
add(rand_string(rand<size_t>(8u)));
|
||||
break;
|
||||
case toml::node_type::string:
|
||||
add(rand_string(rand<size_t>(8u)));
|
||||
break;
|
||||
|
||||
case toml::node_type::integer:
|
||||
add(rand());
|
||||
break;
|
||||
case toml::node_type::integer:
|
||||
add(rand());
|
||||
break;
|
||||
|
||||
case toml::node_type::floating_point:
|
||||
add(rand(10001u) / 10000.0);
|
||||
break;
|
||||
case toml::node_type::floating_point:
|
||||
add(rand(10001u) / 10000.0);
|
||||
break;
|
||||
|
||||
case toml::node_type::boolean:
|
||||
add(!rand(2u));
|
||||
break;
|
||||
case toml::node_type::boolean:
|
||||
add(!rand(2u));
|
||||
break;
|
||||
|
||||
case toml::node_type::date:
|
||||
add(rand_date());
|
||||
break;
|
||||
case toml::node_type::date:
|
||||
add(rand_date());
|
||||
break;
|
||||
|
||||
case toml::node_type::time:
|
||||
add(rand_time());
|
||||
break;
|
||||
case toml::node_type::time:
|
||||
add(rand_time());
|
||||
break;
|
||||
|
||||
case toml::node_type::date_time:
|
||||
add(rand(100) >= 75
|
||||
? toml::date_time{ rand_date(), rand_time() }
|
||||
: toml::date_time{ rand_date(), rand_time(), toml::time_offset{ rand<int8_t>(-11, 12), rand<int8_t>(-45, +46) } }
|
||||
);
|
||||
break;
|
||||
case toml::node_type::date_time:
|
||||
add(rand(100) >= 75
|
||||
? toml::date_time{ rand_date(), rand_time() }
|
||||
: toml::date_time{ rand_date(), rand_time(), toml::time_offset{ rand<int8_t>(-11, 12), rand<int8_t>(-45, +46) } }
|
||||
);
|
||||
break;
|
||||
}
|
||||
if (container_min_values <= 0 && tree.size() >= 2u && rand(100) >= 85)
|
||||
{
|
||||
|
@ -52,5 +52,11 @@
|
||||
<ItemGroup>
|
||||
<None Include="meson.build" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="examples.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
@ -2,14 +2,10 @@
|
||||
// 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
|
||||
/*
|
||||
|
||||
This example demonstrates how to use the toml::json_formatter to
|
||||
re-serialize TOML data as JSON.
|
||||
// This example demonstrates how to use the toml::json_formatter to re-serialize TOML data as JSON.
|
||||
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "utf8_console.h"
|
||||
#include "examples.h"
|
||||
|
||||
#define TOML_UNRELEASED_FEATURES 1
|
||||
#include <toml++/toml.h>
|
||||
@ -18,38 +14,28 @@ using namespace std::string_view_literals;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
init_utf8_console();
|
||||
examples::init();
|
||||
|
||||
// read from a file if a path argument is given
|
||||
if (argc > 1)
|
||||
toml::table table;
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto table = toml::parse_file(argv[1]);
|
||||
std::cout << toml::json_formatter{ table } << "\n";
|
||||
}
|
||||
catch (const toml::parse_error& err)
|
||||
{
|
||||
std::cerr << err << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise read directly from stdin
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto table = toml::parse(std::cin, "stdin"sv);
|
||||
std::cout << toml::json_formatter{ table } << "\n";
|
||||
}
|
||||
catch (const toml::parse_error& err)
|
||||
{
|
||||
std::cerr << err << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// read from a file if a path argument is given
|
||||
if (argc > 1)
|
||||
table = toml::parse_file(argv[1]);
|
||||
|
||||
// otherwise read directly from stdin
|
||||
else
|
||||
table = toml::parse(std::cin, "stdin"sv);
|
||||
|
||||
std::cout << toml::json_formatter{ table } << "\n";
|
||||
}
|
||||
catch (const toml::parse_error& err)
|
||||
{
|
||||
std::cerr << err << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << toml::json_formatter{ table } << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
@ -52,5 +52,11 @@
|
||||
<ItemGroup>
|
||||
<None Include="meson.build" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="examples.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
@ -1,18 +0,0 @@
|
||||
//# This file is a part of toml++ and is subject to the the terms of the MIT license.
|
||||
//# Copyright (c) 2019-2020 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 <iostream>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
inline void init_utf8_console() noexcept
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(65001); //CP_UTF8
|
||||
#endif
|
||||
|
||||
std::cout << std::boolalpha;
|
||||
}
|
@ -176,78 +176,6 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_ENABLE_WARNINGS;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref_t<T>, type>)
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
is_native<type> || is_losslessly_convertible_to_native<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
using value_type = native_type_of<remove_cvref_t<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
#else
|
||||
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return new value<value_type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
{
|
||||
if constexpr (is_node_view<type>)
|
||||
{
|
||||
if (!val)
|
||||
return static_cast<toml::node*>(nullptr);
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(std::forward<decltype(concrete)>(concrete)));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(std::move(val.value));
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
/// \endcond
|
||||
@ -330,7 +258,7 @@ TOML_NAMESPACE_START
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(std::forward<T>(val)));
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val)));
|
||||
}
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
@ -418,11 +346,11 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1_sz);
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(
|
||||
emplace_back_if_not_empty_view(std::forward<ElemTypes>(vals)),
|
||||
emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals)),
|
||||
...
|
||||
);
|
||||
}
|
||||
@ -544,7 +472,7 @@ TOML_NAMESPACE_START
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(std::forward<ElemType>(val))) };
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val))) };
|
||||
}
|
||||
|
||||
/// \brief Repeatedly inserts a new element starting at a specific position in the array.
|
||||
@ -595,7 +523,7 @@ TOML_NAMESPACE_START
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, std::forward<ElemType>(val));
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val));
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
@ -605,7 +533,7 @@ TOML_NAMESPACE_START
|
||||
elements[i].reset(impl::make_node(val));
|
||||
|
||||
//# potentially move the initial value into the last element
|
||||
elements[i].reset(impl::make_node(std::forward<ElemType>(val)));
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val)));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
@ -714,7 +642,7 @@ TOML_NAMESPACE_START
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
return { elements.emplace(pos.raw_, new impl::wrap_node<type>{ std::forward<Args>(args)...} ) };
|
||||
return { elements.emplace(pos.raw_, new impl::wrap_node<type>{ static_cast<Args&&>(args)...} ) };
|
||||
}
|
||||
|
||||
/// \brief Removes the specified element from the array.
|
||||
@ -800,7 +728,7 @@ TOML_NAMESPACE_START
|
||||
else if (new_size < elements.size())
|
||||
elements.resize(new_size);
|
||||
else if (new_size > elements.size())
|
||||
insert(cend(), new_size - elements.size(), std::forward<ElemType>(default_init_val));
|
||||
insert(cend(), new_size - elements.size(), static_cast<ElemType&&>(default_init_val));
|
||||
}
|
||||
|
||||
/// \brief Shrinks the array to the given size.
|
||||
@ -851,7 +779,7 @@ TOML_NAMESPACE_START
|
||||
template <typename ElemType>
|
||||
void push_back(ElemType&& val) noexcept
|
||||
{
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new element at the end of the array.
|
||||
@ -885,7 +813,7 @@ TOML_NAMESPACE_START
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
auto nde = new impl::wrap_node<type>{ std::forward<Args>(args)... };
|
||||
auto nde = new impl::wrap_node<type>{ static_cast<Args&&>(args)... };
|
||||
elements.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
|
@ -549,47 +549,64 @@ TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief Metafunction for determining if a type is a toml::table.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::table.
|
||||
template <typename T>
|
||||
inline constexpr bool is_table = std::is_same_v<impl::remove_cvref_t<T>, table>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::array.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::array.
|
||||
template <typename T>
|
||||
inline constexpr bool is_array = std::is_same_v<impl::remove_cvref_t<T>, array>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a std::string or toml::value<std::string>.
|
||||
/// \brief Metafunction for determining if a type satisfies either toml::is_table or toml::is_array.
|
||||
template <typename T>
|
||||
inline constexpr bool is_container = is_table<T> || is_array<T>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a std::string or toml::value<std::string>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_string = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<std::string>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is an int64_t or toml::value<int64_t>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_integer = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<int64_t>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a double or toml::value<double>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a double or toml::value<double>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_floating_point = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<double>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type satisfies `toml::is_integer || toml::is_floating_point`.
|
||||
/// \brief Metafunction for determining if a type satisfies either toml::is_integer or toml::is_floating_point.
|
||||
template <typename T>
|
||||
inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a bool toml::value<bool>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a bool or toml::value<bool>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_boolean = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<bool>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::date or toml::value<date>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::date or toml::value<date>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_date = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<date>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::time or toml::value<time>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::time or toml::value<time>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_time = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<time>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::date_time or toml::value<date_time>.
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::date_time or toml::value<date_time>.
|
||||
template <typename T>
|
||||
inline constexpr bool is_date_time = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is a toml::node_view.
|
||||
/// \brief Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time or toml::is_date_time.
|
||||
template <typename T>
|
||||
inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, any of the toml value types. Excludes tables and arrays.
|
||||
template <typename T>
|
||||
inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclasses).
|
||||
template <typename T>
|
||||
inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref_t<T>>
|
||||
|| std::is_base_of_v<toml::node, impl::remove_cvref_t<T>>;
|
||||
|
||||
/// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
|
||||
template <typename T>
|
||||
inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref_t<T>, node_view<node>, node_view<const node>>;
|
||||
}
|
||||
@ -618,6 +635,8 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_ATTR(pure)
|
||||
inline fp_class fpclassify(const double& val) noexcept
|
||||
{
|
||||
static_assert(sizeof(uint64_t) == sizeof(double));
|
||||
|
||||
constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
|
||||
constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
|
||||
constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
|
||||
@ -693,12 +712,105 @@ TOML_IMPL_NAMESPACE_START
|
||||
"time"sv,
|
||||
"date-time"sv
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref_t<T>, type>)
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
is_native<type> || is_losslessly_convertible_to_native<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
using value_type = native_type_of<remove_cvref_t<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
#else
|
||||
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return new value<value_type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
{
|
||||
if constexpr (is_node_view<type>)
|
||||
{
|
||||
if (!val)
|
||||
return static_cast<toml::node*>(nullptr);
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(static_cast<decltype(concrete)&&>(concrete)));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(static_cast<T&&>(val.value));
|
||||
}
|
||||
|
||||
template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
|
||||
struct inserted_type_of_
|
||||
{
|
||||
using type = std::remove_pointer_t<decltype(make_node(std::declval<T>()))>;
|
||||
};
|
||||
template <typename T>
|
||||
struct inserted_type_of_<inserter<T>, false>
|
||||
{
|
||||
using type = typename inserted_type_of_<T>::type;
|
||||
};
|
||||
template <typename T>
|
||||
struct inserted_type_of_<T, false>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
/// \endcond
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
/// \brief Metafunction for determining which toml node type would be constructed
|
||||
// if an object of this type was inserted into a toml::table or toml::array.
|
||||
template <typename T>
|
||||
using inserted_type_of = typename impl::inserted_type_of_<impl::remove_cvref_t<T>>::type;
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
|
@ -89,9 +89,9 @@ TOML_NAMESPACE_START
|
||||
&& "template type argument T provided to toml::node::ref() didn't match the node's actual type"
|
||||
);
|
||||
if constexpr (impl::is_native<type>)
|
||||
return std::forward<N>(n).template ref_cast<type>().get();
|
||||
return static_cast<N&&>(n).template ref_cast<type>().get();
|
||||
else
|
||||
return std::forward<N>(n).template ref_cast<type>();
|
||||
return static_cast<N&&>(n).template ref_cast<type>();
|
||||
}
|
||||
|
||||
/// \endcond
|
||||
@ -737,47 +737,47 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
case node_type::table:
|
||||
if constexpr (can_visit<Func&&, N&&, table>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<table>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<table>());
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if constexpr (can_visit<Func&&, N&&, array>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<array>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<array>());
|
||||
break;
|
||||
|
||||
case node_type::string:
|
||||
if constexpr (can_visit<Func&&, N&&, std::string>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<std::string>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<std::string>());
|
||||
break;
|
||||
|
||||
case node_type::integer:
|
||||
if constexpr (can_visit<Func&&, N&&, int64_t>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<int64_t>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<int64_t>());
|
||||
break;
|
||||
|
||||
case node_type::floating_point:
|
||||
if constexpr (can_visit<Func&&, N&&, double>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<double>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<double>());
|
||||
break;
|
||||
|
||||
case node_type::boolean:
|
||||
if constexpr (can_visit<Func&&, N&&, bool>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<bool>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<bool>());
|
||||
break;
|
||||
|
||||
case node_type::date:
|
||||
if constexpr (can_visit<Func&&, N&&, date>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date>());
|
||||
break;
|
||||
|
||||
case node_type::time:
|
||||
if constexpr (can_visit<Func&&, N&&, time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<time>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<time>());
|
||||
break;
|
||||
|
||||
case node_type::date_time:
|
||||
if constexpr (can_visit<Func&&, N&&, date_time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date_time>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date_time>());
|
||||
break;
|
||||
|
||||
case node_type::none: TOML_UNREACHABLE;
|
||||
@ -850,7 +850,7 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) &
|
||||
noexcept(visit_is_nothrow<Func&&, node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
/// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
|
||||
@ -858,7 +858,7 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) &&
|
||||
noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||
{
|
||||
return do_visit(std::move(*this), std::forward<Func>(visitor));
|
||||
return do_visit(static_cast<node&&>(*this), static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
/// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue overload).
|
||||
@ -866,7 +866,7 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) const&
|
||||
noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
@ -396,8 +396,8 @@ TOML_NAMESPACE_START
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
return node_->value_or(static_cast<T&&>(default_value));
|
||||
return std::wstring{ static_cast<T&&>(default_value) };
|
||||
|
||||
#else
|
||||
|
||||
@ -414,11 +414,11 @@ TOML_NAMESPACE_START
|
||||
>;
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
return node_->value_or(static_cast<T&&>(default_value));
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
return value_type{ default_value };
|
||||
else
|
||||
return std::forward<T>(default_value);
|
||||
return static_cast<T&&>(default_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,9 +467,9 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) const
|
||||
noexcept(visit_is_nothrow<Func&&>)
|
||||
{
|
||||
using return_type = decltype(node_->visit(std::forward<Func>(visitor)));
|
||||
using return_type = decltype(node_->visit(static_cast<Func&&>(visitor)));
|
||||
if (node_)
|
||||
return node_->visit(std::forward<Func>(visitor));
|
||||
return node_->visit(static_cast<Func&&>(visitor));
|
||||
if constexpr (!std::is_void_v<return_type>)
|
||||
return return_type{};
|
||||
}
|
||||
|
@ -155,19 +155,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename V>
|
||||
table_init_pair(std::string&& k, V&& v) noexcept
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::string_view k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(const char* k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -175,19 +175,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring&& k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring_view k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(const wchar_t* k, V&& v) noexcept
|
||||
: key{ narrow(std::wstring_view{ k }) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
@ -216,14 +216,14 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename U, typename String = std::string_view>
|
||||
explicit utf8_reader(U && source, String&& source_path = {})
|
||||
noexcept(std::is_nothrow_constructible_v<utf8_byte_stream<T>, U&&>)
|
||||
: stream{ std::forward<U>(source) }
|
||||
: stream{ static_cast<U&&>(source) }
|
||||
{
|
||||
std::memset(codepoints, 0, sizeof(codepoints));
|
||||
codepoints[0].position = { 1, 1 };
|
||||
codepoints[1].position = { 1, 1 };
|
||||
|
||||
if (!source_path.empty())
|
||||
source_path_ = std::make_shared<const std::string>(std::forward<String>(source_path));
|
||||
source_path_ = std::make_shared<const std::string>(static_cast<String&&>(source_path));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -79,7 +79,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
static T make(Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
|
||||
{
|
||||
return T(std::forward<Args>(args)...);
|
||||
return T(static_cast<Args&&>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
@ -91,7 +91,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_ALWAYS_INLINE
|
||||
static U&& make(U&& val) noexcept
|
||||
{
|
||||
return std::forward<U>(val);
|
||||
return static_cast<U&&>(val);
|
||||
}
|
||||
};
|
||||
|
||||
@ -112,7 +112,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (is_wide_string<T>)
|
||||
return narrow(std::forward<T>(arg));
|
||||
return narrow(static_cast<T&&>(arg));
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
}
|
||||
};
|
||||
@ -244,9 +244,9 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit value(Args&&... args)
|
||||
noexcept(noexcept(value_type(
|
||||
impl::native_value_maker<value_type, std::decay_t<Args>...>::make(std::forward<Args>(args)...)
|
||||
impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...)
|
||||
)))
|
||||
: val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(std::forward<Args>(args)...))
|
||||
: val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...))
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
@ -406,21 +406,21 @@ TOML_NAMESPACE_START
|
||||
/// \brief Returns a reference to the underlying value.
|
||||
[[nodiscard]] value_type& get() & noexcept { return val_; }
|
||||
/// \brief Returns a reference to the underlying value (rvalue overload).
|
||||
[[nodiscard]] value_type&& get() && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] value_type&& get() && noexcept { return static_cast<value_type&&>(val_); }
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] const value_type& get() const & noexcept { return val_; }
|
||||
|
||||
/// \brief Returns a reference to the underlying value.
|
||||
[[nodiscard]] value_type& operator* () & noexcept { return val_; }
|
||||
/// \brief Returns a reference to the underlying value (rvalue overload).
|
||||
[[nodiscard]] value_type&& operator* () && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] value_type&& operator* () && noexcept { return static_cast<value_type&&>(val_); }
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] const value_type& operator* () const& noexcept { return val_; }
|
||||
|
||||
/// \brief Returns a reference to the underlying value.
|
||||
[[nodiscard]] explicit operator value_type& () & noexcept { return val_; }
|
||||
/// \brief Returns a reference to the underlying value (rvalue overload).
|
||||
[[nodiscard]] explicit operator value_type && () && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] explicit operator value_type && () && noexcept { return static_cast<value_type&&>(val_); }
|
||||
/// \brief Returns a reference to the underlying value (const overload).
|
||||
[[nodiscard]] explicit operator const value_type& () const& noexcept { return val_; }
|
||||
|
||||
@ -843,7 +843,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
if (type() == node_type::string)
|
||||
return widen(*ref_cast<std::string>());
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
return std::wstring{ static_cast<T&&>(default_value) };
|
||||
|
||||
#else
|
||||
|
||||
@ -911,7 +911,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
return value_type{ default_value };
|
||||
else
|
||||
return std::forward<T>(default_value);
|
||||
return static_cast<T&&>(default_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -274,6 +274,35 @@ namespace toml
|
||||
CHECK_VALUE_OR( const std::wstring&&, std::wstring);
|
||||
#endif
|
||||
|
||||
#define CHECK_INSERTED_AS(T, expected) \
|
||||
static_assert(std::is_same_v<expected, toml::inserted_type_of<T>>); \
|
||||
static_assert(std::is_same_v<expected, toml::inserted_type_of<const T>>); \
|
||||
static_assert(std::is_same_v<expected, toml::inserted_type_of<T&>>); \
|
||||
static_assert(std::is_same_v<expected, toml::inserted_type_of<const T&>>); \
|
||||
static_assert(std::is_same_v<expected, toml::inserted_type_of<T&&>>)
|
||||
|
||||
CHECK_INSERTED_AS(table, table);
|
||||
CHECK_INSERTED_AS(array, array);
|
||||
CHECK_INSERTED_AS(node, node);
|
||||
CHECK_INSERTED_AS(time, value<time>);
|
||||
CHECK_INSERTED_AS(date, value<date>);
|
||||
CHECK_INSERTED_AS(date_time, value<date_time>);
|
||||
CHECK_INSERTED_AS(bool, value<bool>);
|
||||
CHECK_INSERTED_AS(int8_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(int16_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(int32_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(int64_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(uint8_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(uint16_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(uint32_t, value<int64_t>);
|
||||
CHECK_INSERTED_AS(float, value<double>);
|
||||
CHECK_INSERTED_AS(double, value<double>);
|
||||
#ifdef TOML_FP16
|
||||
CHECK_INSERTED_AS(TOML_FP16, value<double>);
|
||||
#endif
|
||||
#ifdef TOML_FLOAT16
|
||||
CHECK_INSERTED_AS(TOML_FLOAT16, value<double>);
|
||||
#endif
|
||||
|
||||
static_assert(is_same_v<decltype(declval<node&>().ref<double>()), double&>);
|
||||
static_assert(is_same_v<decltype(declval<node&&>().ref<double>()), double&&>);
|
||||
|
@ -69,6 +69,10 @@
|
||||
<None Include=".gitattributes" />
|
||||
<None Include=".gitignore" />
|
||||
<None Include=".runsettings" />
|
||||
<None Include="cmake\install-rules.cmake" />
|
||||
<None Include="cmake\project-is-top-level.cmake" />
|
||||
<None Include="cmake\tomlplusplusConfig.cmake" />
|
||||
<None Include="cmake\variables.cmake" />
|
||||
<None Include="CODE_OF_CONDUCT.md" />
|
||||
<None Include="CONTRIBUTING.md" />
|
||||
<None Include="cpp.hint" />
|
||||
|
@ -119,6 +119,18 @@
|
||||
<Filter>docs</Filter>
|
||||
</None>
|
||||
<None Include=".runsettings" />
|
||||
<None Include="cmake\install-rules.cmake">
|
||||
<Filter>cmake</Filter>
|
||||
</None>
|
||||
<None Include="cmake\project-is-top-level.cmake">
|
||||
<Filter>cmake</Filter>
|
||||
</None>
|
||||
<None Include="cmake\tomlplusplusConfig.cmake">
|
||||
<Filter>cmake</Filter>
|
||||
</None>
|
||||
<None Include="cmake\variables.cmake">
|
||||
<Filter>cmake</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include=".circleci">
|
||||
@ -136,6 +148,9 @@
|
||||
<Filter Include="docs\pages">
|
||||
<UniqueIdentifier>{9bdc71ff-34f1-4312-9f15-1850d4c5908b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="cmake">
|
||||
<UniqueIdentifier>{47351d16-986b-4f4b-bd5e-b7c66a7a68d3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="toml++.natvis" />
|
||||
|
275
toml.hpp
275
toml.hpp
@ -1244,6 +1244,9 @@ TOML_NAMESPACE_START
|
||||
template <typename T>
|
||||
inline constexpr bool is_array = std::is_same_v<impl::remove_cvref_t<T>, array>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_container = is_table<T> || is_array<T>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_string = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<std::string>>;
|
||||
|
||||
@ -1268,6 +1271,16 @@ TOML_NAMESPACE_START
|
||||
template <typename T>
|
||||
inline constexpr bool is_date_time = std::is_same_v<impl::wrap_node<impl::remove_cvref_t<T>>, value<date_time>>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref_t<T>>
|
||||
|| std::is_base_of_v<toml::node, impl::remove_cvref_t<T>>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref_t<T>, node_view<node>, node_view<const node>>;
|
||||
}
|
||||
@ -1291,6 +1304,8 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_ATTR(pure)
|
||||
inline fp_class fpclassify(const double& val) noexcept
|
||||
{
|
||||
static_assert(sizeof(uint64_t) == sizeof(double));
|
||||
|
||||
constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
|
||||
constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
|
||||
constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
|
||||
@ -1366,11 +1381,103 @@ TOML_IMPL_NAMESPACE_START
|
||||
"time"sv,
|
||||
"date-time"sv
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref_t<T>, type>)
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
is_native<type> || is_losslessly_convertible_to_native<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
using value_type = native_type_of<remove_cvref_t<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
#else
|
||||
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return new value<value_type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
{
|
||||
if constexpr (is_node_view<type>)
|
||||
{
|
||||
if (!val)
|
||||
return static_cast<toml::node*>(nullptr);
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(static_cast<decltype(concrete)&&>(concrete)));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(static_cast<T&&>(val.value));
|
||||
}
|
||||
|
||||
template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
|
||||
struct inserted_type_of_
|
||||
{
|
||||
using type = std::remove_pointer_t<decltype(make_node(std::declval<T>()))>;
|
||||
};
|
||||
template <typename T>
|
||||
struct inserted_type_of_<inserter<T>, false>
|
||||
{
|
||||
using type = typename inserted_type_of_<T>::type;
|
||||
};
|
||||
template <typename T>
|
||||
struct inserted_type_of_<T, false>
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
// if an object of this type was inserted into a toml::table or toml::array.
|
||||
template <typename T>
|
||||
using inserted_type_of = typename impl::inserted_type_of_<impl::remove_cvref_t<T>>::type;
|
||||
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(const)
|
||||
TOML_ALWAYS_INLINE
|
||||
@ -2363,9 +2470,9 @@ TOML_NAMESPACE_START
|
||||
&& "template type argument T provided to toml::node::ref() didn't match the node's actual type"
|
||||
);
|
||||
if constexpr (impl::is_native<type>)
|
||||
return std::forward<N>(n).template ref_cast<type>().get();
|
||||
return static_cast<N&&>(n).template ref_cast<type>().get();
|
||||
else
|
||||
return std::forward<N>(n).template ref_cast<type>();
|
||||
return static_cast<N&&>(n).template ref_cast<type>();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -2667,47 +2774,47 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
case node_type::table:
|
||||
if constexpr (can_visit<Func&&, N&&, table>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<table>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<table>());
|
||||
break;
|
||||
|
||||
case node_type::array:
|
||||
if constexpr (can_visit<Func&&, N&&, array>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<array>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<array>());
|
||||
break;
|
||||
|
||||
case node_type::string:
|
||||
if constexpr (can_visit<Func&&, N&&, std::string>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<std::string>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<std::string>());
|
||||
break;
|
||||
|
||||
case node_type::integer:
|
||||
if constexpr (can_visit<Func&&, N&&, int64_t>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<int64_t>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<int64_t>());
|
||||
break;
|
||||
|
||||
case node_type::floating_point:
|
||||
if constexpr (can_visit<Func&&, N&&, double>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<double>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<double>());
|
||||
break;
|
||||
|
||||
case node_type::boolean:
|
||||
if constexpr (can_visit<Func&&, N&&, bool>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<bool>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<bool>());
|
||||
break;
|
||||
|
||||
case node_type::date:
|
||||
if constexpr (can_visit<Func&&, N&&, date>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date>());
|
||||
break;
|
||||
|
||||
case node_type::time:
|
||||
if constexpr (can_visit<Func&&, N&&, time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<time>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<time>());
|
||||
break;
|
||||
|
||||
case node_type::date_time:
|
||||
if constexpr (can_visit<Func&&, N&&, date_time>)
|
||||
return std::forward<Func>(visitor)(std::forward<N>(n).template ref_cast<date_time>());
|
||||
return static_cast<Func&&>(visitor)(static_cast<N&&>(n).template ref_cast<date_time>());
|
||||
break;
|
||||
|
||||
case node_type::none: TOML_UNREACHABLE;
|
||||
@ -2747,21 +2854,21 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) &
|
||||
noexcept(visit_is_nothrow<Func&&, node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) &&
|
||||
noexcept(visit_is_nothrow<Func&&, node&&>)
|
||||
{
|
||||
return do_visit(std::move(*this), std::forward<Func>(visitor));
|
||||
return do_visit(static_cast<node&&>(*this), static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
decltype(auto) visit(Func&& visitor) const&
|
||||
noexcept(visit_is_nothrow<Func&&, const node&>)
|
||||
{
|
||||
return do_visit(*this, std::forward<Func>(visitor));
|
||||
return do_visit(*this, static_cast<Func&&>(visitor));
|
||||
}
|
||||
|
||||
[[nodiscard]] explicit operator node_view<node>() noexcept;
|
||||
@ -2846,7 +2953,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
[[nodiscard]]
|
||||
static T make(Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
|
||||
{
|
||||
return T(std::forward<Args>(args)...);
|
||||
return T(static_cast<Args&&>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2858,7 +2965,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_ALWAYS_INLINE
|
||||
static U&& make(U&& val) noexcept
|
||||
{
|
||||
return std::forward<U>(val);
|
||||
return static_cast<U&&>(val);
|
||||
}
|
||||
};
|
||||
|
||||
@ -2879,7 +2986,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
if constexpr (is_wide_string<T>)
|
||||
return narrow(std::forward<T>(arg));
|
||||
return narrow(static_cast<T&&>(arg));
|
||||
#endif // TOML_WINDOWS_COMPAT
|
||||
}
|
||||
};
|
||||
@ -2985,9 +3092,9 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit value(Args&&... args)
|
||||
noexcept(noexcept(value_type(
|
||||
impl::native_value_maker<value_type, std::decay_t<Args>...>::make(std::forward<Args>(args)...)
|
||||
impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...)
|
||||
)))
|
||||
: val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(std::forward<Args>(args)...))
|
||||
: val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...))
|
||||
{
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
lh_ctor();
|
||||
@ -3114,15 +3221,15 @@ TOML_NAMESPACE_START
|
||||
[[nodiscard]] const value<date_time>* as_date_time() const noexcept override { return as_value<date_time>(this); }
|
||||
|
||||
[[nodiscard]] value_type& get() & noexcept { return val_; }
|
||||
[[nodiscard]] value_type&& get() && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] value_type&& get() && noexcept { return static_cast<value_type&&>(val_); }
|
||||
[[nodiscard]] const value_type& get() const & noexcept { return val_; }
|
||||
|
||||
[[nodiscard]] value_type& operator* () & noexcept { return val_; }
|
||||
[[nodiscard]] value_type&& operator* () && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] value_type&& operator* () && noexcept { return static_cast<value_type&&>(val_); }
|
||||
[[nodiscard]] const value_type& operator* () const& noexcept { return val_; }
|
||||
|
||||
[[nodiscard]] explicit operator value_type& () & noexcept { return val_; }
|
||||
[[nodiscard]] explicit operator value_type && () && noexcept { return std::move(val_); }
|
||||
[[nodiscard]] explicit operator value_type && () && noexcept { return static_cast<value_type&&>(val_); }
|
||||
[[nodiscard]] explicit operator const value_type& () const& noexcept { return val_; }
|
||||
|
||||
[[nodiscard]] value_flags flags() const noexcept
|
||||
@ -3467,7 +3574,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
if (type() == node_type::string)
|
||||
return widen(*ref_cast<std::string>());
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
return std::wstring{ static_cast<T&&>(default_value) };
|
||||
|
||||
#else
|
||||
|
||||
@ -3535,7 +3642,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
return value_type{ default_value };
|
||||
else
|
||||
return std::forward<T>(default_value);
|
||||
return static_cast<T&&>(default_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3767,78 +3874,6 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_ENABLE_WARNINGS;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref_t<T>, type>)
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(
|
||||
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
||||
"Instantiating values from wide-character strings is only "
|
||||
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
static_assert(
|
||||
is_native<type> || is_losslessly_convertible_to_native<type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types"
|
||||
);
|
||||
|
||||
using value_type = native_type_of<remove_cvref_t<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
#else
|
||||
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return new value<value_type>{ static_cast<T&&>(val) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
{
|
||||
if constexpr (is_node_view<type>)
|
||||
{
|
||||
if (!val)
|
||||
return static_cast<toml::node*>(nullptr);
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(std::forward<decltype(concrete)>(concrete)));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(std::move(val.value));
|
||||
}
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
||||
@ -3865,7 +3900,7 @@ TOML_NAMESPACE_START
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(std::forward<T>(val)));
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val)));
|
||||
}
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
@ -3907,11 +3942,11 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1_sz);
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(
|
||||
emplace_back_if_not_empty_view(std::forward<ElemTypes>(vals)),
|
||||
emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals)),
|
||||
...
|
||||
);
|
||||
}
|
||||
@ -3975,7 +4010,7 @@ TOML_NAMESPACE_START
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(std::forward<ElemType>(val))) };
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val))) };
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
@ -3989,7 +4024,7 @@ TOML_NAMESPACE_START
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, std::forward<ElemType>(val));
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val));
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
@ -3998,7 +4033,7 @@ TOML_NAMESPACE_START
|
||||
for (size_t e = start_idx + count - 1_sz; i < e; i++)
|
||||
elements[i].reset(impl::make_node(val));
|
||||
|
||||
elements[i].reset(impl::make_node(std::forward<ElemType>(val)));
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val)));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
@ -4057,7 +4092,7 @@ TOML_NAMESPACE_START
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
return { elements.emplace(pos.raw_, new impl::wrap_node<type>{ std::forward<Args>(args)...} ) };
|
||||
return { elements.emplace(pos.raw_, new impl::wrap_node<type>{ static_cast<Args&&>(args)...} ) };
|
||||
}
|
||||
|
||||
iterator erase(const_iterator pos) noexcept;
|
||||
@ -4076,7 +4111,7 @@ TOML_NAMESPACE_START
|
||||
else if (new_size < elements.size())
|
||||
elements.resize(new_size);
|
||||
else if (new_size > elements.size())
|
||||
insert(cend(), new_size - elements.size(), std::forward<ElemType>(default_init_val));
|
||||
insert(cend(), new_size - elements.size(), static_cast<ElemType&&>(default_init_val));
|
||||
}
|
||||
|
||||
void truncate(size_t new_size);
|
||||
@ -4084,7 +4119,7 @@ TOML_NAMESPACE_START
|
||||
template <typename ElemType>
|
||||
void push_back(ElemType&& val) noexcept
|
||||
{
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
}
|
||||
|
||||
template <typename ElemType, typename... Args>
|
||||
@ -4097,7 +4132,7 @@ TOML_NAMESPACE_START
|
||||
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
||||
);
|
||||
|
||||
auto nde = new impl::wrap_node<type>{ std::forward<Args>(args)... };
|
||||
auto nde = new impl::wrap_node<type>{ static_cast<Args&&>(args)... };
|
||||
elements.emplace_back(nde);
|
||||
return *nde;
|
||||
}
|
||||
@ -4338,19 +4373,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename V>
|
||||
table_init_pair(std::string&& k, V&& v) noexcept
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::string_view k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(const char* k, V&& v) noexcept
|
||||
: key{ k },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -4358,19 +4393,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring&& k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(std::wstring_view k, V&& v) noexcept
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
table_init_pair(const wchar_t* k, V&& v) noexcept
|
||||
: key{ narrow(std::wstring_view{ k }) },
|
||||
value{ make_node(std::forward<V>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
{}
|
||||
|
||||
#endif
|
||||
@ -4920,8 +4955,8 @@ TOML_NAMESPACE_START
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
return std::wstring{ std::forward<T>(default_value) };
|
||||
return node_->value_or(static_cast<T&&>(default_value));
|
||||
return std::wstring{ static_cast<T&&>(default_value) };
|
||||
|
||||
#else
|
||||
|
||||
@ -4938,11 +4973,11 @@ TOML_NAMESPACE_START
|
||||
>;
|
||||
|
||||
if (node_)
|
||||
return node_->value_or(std::forward<T>(default_value));
|
||||
return node_->value_or(static_cast<T&&>(default_value));
|
||||
if constexpr (std::is_pointer_v<value_type>)
|
||||
return value_type{ default_value };
|
||||
else
|
||||
return std::forward<T>(default_value);
|
||||
return static_cast<T&&>(default_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4961,9 +4996,9 @@ TOML_NAMESPACE_START
|
||||
decltype(auto) visit(Func&& visitor) const
|
||||
noexcept(visit_is_nothrow<Func&&>)
|
||||
{
|
||||
using return_type = decltype(node_->visit(std::forward<Func>(visitor)));
|
||||
using return_type = decltype(node_->visit(static_cast<Func&&>(visitor)));
|
||||
if (node_)
|
||||
return node_->visit(std::forward<Func>(visitor));
|
||||
return node_->visit(static_cast<Func&&>(visitor));
|
||||
if constexpr (!std::is_void_v<return_type>)
|
||||
return return_type{};
|
||||
}
|
||||
@ -6685,14 +6720,14 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename U, typename String = std::string_view>
|
||||
explicit utf8_reader(U && source, String&& source_path = {})
|
||||
noexcept(std::is_nothrow_constructible_v<utf8_byte_stream<T>, U&&>)
|
||||
: stream{ std::forward<U>(source) }
|
||||
: stream{ static_cast<U&&>(source) }
|
||||
{
|
||||
std::memset(codepoints, 0, sizeof(codepoints));
|
||||
codepoints[0].position = { 1, 1 };
|
||||
codepoints[1].position = { 1, 1 };
|
||||
|
||||
if (!source_path.empty())
|
||||
source_path_ = std::make_shared<const std::string>(std::forward<String>(source_path));
|
||||
source_path_ = std::make_shared<const std::string>(static_cast<String&&>(source_path));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
Loading…
Reference in New Issue
Block a user