mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-04 05:59:37 +00:00
added value flags to array + table insert methods (closes #44)
also: - made single header generation script `#pragma once`-aware
This commit is contained in:
parent
467ade4efc
commit
1bf09fe500
@ -255,14 +255,14 @@ TOML_NAMESPACE_START
|
||||
void preinsertion_resize(size_t idx, size_t count);
|
||||
|
||||
template <typename T>
|
||||
void emplace_back_if_not_empty_view(T&& val)
|
||||
void emplace_back_if_not_empty_view(T&& val, value_flags flags)
|
||||
{
|
||||
if constexpr (is_node_view<T>)
|
||||
{
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val)));
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val), flags));
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
@ -364,10 +364,10 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1u);
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), value_flags::none);
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals)), ...);
|
||||
(emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals), value_flags::none), ...);
|
||||
}
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
@ -586,6 +586,10 @@ TOML_NAMESPACE_START
|
||||
/// (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param val The node or value being inserted.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and `val` is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// An iterator to the newly-inserted element.
|
||||
@ -595,14 +599,14 @@ TOML_NAMESPACE_START
|
||||
/// \attention The return value will always be `end()` if the input value was an empty toml::node_view,
|
||||
/// because no insertion can take place. This is the only circumstance in which this can occur.
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, ElemType&& val)
|
||||
iterator insert(const_iterator pos, ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
if constexpr (is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val))) };
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val), flags)) };
|
||||
}
|
||||
|
||||
/// \brief Repeatedly inserts a new element starting at a specific position in the array.
|
||||
@ -632,6 +636,10 @@ TOML_NAMESPACE_START
|
||||
/// \param pos The insertion position.
|
||||
/// \param count The number of times the node or value should be inserted.
|
||||
/// \param val The node or value being inserted.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and `val` is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// An iterator to the newly-inserted element.
|
||||
@ -643,7 +651,7 @@ TOML_NAMESPACE_START
|
||||
/// \attention The return value will always be `end()` if the input value was an empty toml::node_view,
|
||||
/// because no insertion can take place. This is the only circumstance in which this can occur.
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, size_t count, ElemType&& val)
|
||||
iterator insert(const_iterator pos, size_t count, ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
if constexpr (is_node_view<ElemType>)
|
||||
{
|
||||
@ -653,17 +661,17 @@ TOML_NAMESPACE_START
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val));
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val), flags);
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, count);
|
||||
size_t i = start_idx;
|
||||
for (size_t e = start_idx + count - 1u; i < e; i++)
|
||||
elements[i].reset(impl::make_node(val));
|
||||
elements[i].reset(impl::make_node(val, flags));
|
||||
|
||||
//# potentially move the initial value into the last element
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val)));
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val), flags));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
@ -675,6 +683,10 @@ TOML_NAMESPACE_START
|
||||
/// \param pos The insertion position.
|
||||
/// \param first Iterator to the first node or value being inserted.
|
||||
/// \param last Iterator to the one-past-the-last node or value being inserted.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and a source value is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// An iterator to the first newly-inserted element.
|
||||
@ -683,7 +695,7 @@ TOML_NAMESPACE_START
|
||||
/// \conditional_return{All objects in the range were empty toml::node_views}
|
||||
/// A copy of pos
|
||||
template <typename Iter>
|
||||
iterator insert(const_iterator pos, Iter first, Iter last)
|
||||
iterator insert(const_iterator pos, Iter first, Iter last, value_flags flags = value_flags::none)
|
||||
{
|
||||
const auto distance = std::distance(first, last);
|
||||
if (distance <= 0)
|
||||
@ -711,9 +723,9 @@ TOML_NAMESPACE_START
|
||||
continue;
|
||||
}
|
||||
if constexpr (std::is_rvalue_reference_v<deref_type>)
|
||||
elements[i++].reset(impl::make_node(std::move(*it)));
|
||||
elements[i++].reset(impl::make_node(std::move(*it), flags));
|
||||
else
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
elements[i++].reset(impl::make_node(*it, flags));
|
||||
}
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
@ -725,6 +737,10 @@ TOML_NAMESPACE_START
|
||||
/// (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param ilist An initializer list containing the values to be inserted.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and a source value is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// An iterator to the first newly-inserted element.
|
||||
@ -733,9 +749,11 @@ TOML_NAMESPACE_START
|
||||
/// \conditional_return{All objects in the list were empty toml::node_views}
|
||||
/// A copy of pos
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist)
|
||||
iterator insert(const_iterator pos,
|
||||
std::initializer_list<ElemType> ilist,
|
||||
value_flags flags = value_flags::none)
|
||||
{
|
||||
return insert(pos, ilist.begin(), ilist.end());
|
||||
return insert(pos, ilist.begin(), ilist.end(), flags);
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new element at a specific position in the array.
|
||||
@ -908,13 +926,17 @@ TOML_NAMESPACE_START
|
||||
///
|
||||
/// \tparam ElemType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// \param val The node or value being added.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and `val` is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \attention No insertion takes place if the input value is an empty toml::node_view.
|
||||
/// This is the only circumstance in which this can occur.
|
||||
template <typename ElemType>
|
||||
void push_back(ElemType&& val)
|
||||
void push_back(ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), flags);
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new element at the end of the array.
|
||||
|
@ -99,7 +99,7 @@ TOML_NAMESPACE_START
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
|
||||
@ -128,7 +128,7 @@ TOML_NAMESPACE_START
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
@ -73,11 +73,11 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
case node_type::table:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const table*>(&node);
|
||||
if (n.empty())
|
||||
auto& tbl = *reinterpret_cast<const table*>(&node);
|
||||
if (tbl.empty())
|
||||
return 2u; // "{}"
|
||||
size_t weight = 3u; // "{ }"
|
||||
for (auto&& [k, v] : n)
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
weight += k.length() + count_inline_columns(v) + 2u; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
@ -88,11 +88,11 @@ TOML_NAMESPACE_START
|
||||
|
||||
case node_type::array:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const array*>(&node);
|
||||
if (n.empty())
|
||||
auto& arr = *reinterpret_cast<const array*>(&node);
|
||||
if (arr.empty())
|
||||
return 2u; // "[]"
|
||||
size_t weight = 3u; // "[ ]"
|
||||
for (auto& elem : n)
|
||||
for (auto& elem : arr)
|
||||
{
|
||||
weight += count_inline_columns(elem) + 2u; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
@ -103,38 +103,38 @@ TOML_NAMESPACE_START
|
||||
|
||||
case node_type::string:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<std::string>*>(&node);
|
||||
return n.get().length() + 2u; // + ""
|
||||
// todo: proper utf8 decoding?
|
||||
// todo: tab awareness?
|
||||
auto& str = (*reinterpret_cast<const value<std::string>*>(&node)).get();
|
||||
return str.length() + 2u; // + ""
|
||||
}
|
||||
|
||||
case node_type::integer:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<int64_t>*>(&node);
|
||||
auto v = n.get();
|
||||
if (!v)
|
||||
auto val = (*reinterpret_cast<const value<int64_t>*>(&node)).get();
|
||||
if (!val)
|
||||
return 1u;
|
||||
size_t weight = {};
|
||||
if (v < 0)
|
||||
if (val < 0)
|
||||
{
|
||||
weight += 1u;
|
||||
v *= -1;
|
||||
val *= -1;
|
||||
}
|
||||
return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1u;
|
||||
return weight + static_cast<size_t>(log10(static_cast<double>(val))) + 1u;
|
||||
}
|
||||
|
||||
case node_type::floating_point:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<double>*>(&node);
|
||||
auto v = n.get();
|
||||
if (v == 0.0)
|
||||
auto val = (*reinterpret_cast<const value<double>*>(&node)).get();
|
||||
if (val == 0.0)
|
||||
return 3u; // "0.0"
|
||||
size_t weight = 2u; // ".0"
|
||||
if (v < 0.0)
|
||||
if (val < 0.0)
|
||||
{
|
||||
weight += 1u;
|
||||
v *= -1.0;
|
||||
val *= -1.0;
|
||||
}
|
||||
return weight + static_cast<size_t>(log10(v)) + 1u;
|
||||
return weight + static_cast<size_t>(log10(val)) + 1u;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -252,9 +252,9 @@ TOML_NAMESPACE_START
|
||||
else
|
||||
{
|
||||
const auto original_indent = base::indent();
|
||||
const auto multiline =
|
||||
forces_multiline(arr,
|
||||
base::indent_columns * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
const auto multiline = forces_multiline(
|
||||
arr,
|
||||
base::indent_columns() * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
impl::print_to_stream(base::stream(), "["sv);
|
||||
if (multiline)
|
||||
{
|
||||
|
@ -19,14 +19,16 @@ TOML_IMPL_NAMESPACE_START
|
||||
format_flags flags_; //
|
||||
int indent_; // these are set in attach()
|
||||
bool naked_newline_; //
|
||||
std::string_view indent_string_;
|
||||
size_t indent_columns_;
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
const parse_result* result_ = {};
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static constexpr size_t indent_columns = 4;
|
||||
static constexpr std::string_view indent_string = " "sv;
|
||||
TOML_API
|
||||
void set_indent_string(std::string_view str) noexcept;
|
||||
|
||||
protected:
|
||||
TOML_PURE_INLINE_GETTER
|
||||
const toml::node& source() const noexcept
|
||||
{
|
||||
@ -60,6 +62,12 @@ TOML_IMPL_NAMESPACE_START
|
||||
indent_--;
|
||||
}
|
||||
|
||||
TOML_PURE_INLINE_GETTER
|
||||
size_t indent_columns() const noexcept
|
||||
{
|
||||
return indent_columns_;
|
||||
}
|
||||
|
||||
TOML_PURE_INLINE_GETTER
|
||||
bool indent_array_elements() const noexcept
|
||||
{
|
||||
@ -148,19 +156,21 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
bool dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS);
|
||||
bool dump_failed_parse_result();
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
formatter(const toml::node& source, format_flags flags) noexcept //
|
||||
formatter(const toml::node& source, format_flags flags, std::string_view indent) noexcept //
|
||||
: source_{ &source },
|
||||
flags_{ flags }
|
||||
{}
|
||||
{
|
||||
set_indent_string(indent);
|
||||
}
|
||||
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
formatter(const parse_result& result, format_flags flags) noexcept;
|
||||
formatter(const parse_result& result, format_flags flags, std::string_view indent) noexcept;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
@ -25,14 +25,25 @@ TOML_IMPL_NAMESPACE_START
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
formatter::formatter(const parse_result& result, format_flags flags) noexcept //
|
||||
formatter::formatter(const parse_result& result, format_flags flags, std::string_view indent) noexcept //
|
||||
: source_{ result ? &result.table() : nullptr },
|
||||
flags_{ flags },
|
||||
result_{ &result }
|
||||
{}
|
||||
{
|
||||
set_indent_string(indent);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::set_indent_string(std::string_view str) noexcept
|
||||
{
|
||||
indent_string_ = str.data() ? str : " "sv;
|
||||
indent_columns_ = {};
|
||||
for (auto c : indent_string_)
|
||||
indent_columns_ += c == '\t' ? 4u : 1u;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::attach(std::ostream & stream) noexcept
|
||||
{
|
||||
@ -62,7 +73,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
for (int i = 0; i < indent_; i++)
|
||||
{
|
||||
print_to_stream(*stream_, indent_string);
|
||||
print_to_stream(*stream_, indent_string_);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
@ -216,7 +227,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool formatter::dump_failed_parse_result() noexcept(false)
|
||||
bool formatter::dump_failed_parse_result()
|
||||
{
|
||||
if (result_ && !(*result_))
|
||||
{
|
||||
@ -230,7 +241,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(const)
|
||||
bool formatter::dump_failed_parse_result() noexcept(true)
|
||||
bool formatter::dump_failed_parse_result()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -333,10 +333,14 @@ TOML_NAMESPACE_START // abi namespace
|
||||
template <typename T>
|
||||
struct TOML_TRIVIAL_ABI inserter
|
||||
{
|
||||
T&& value;
|
||||
static_assert(std::is_reference_v<T>);
|
||||
|
||||
T value;
|
||||
};
|
||||
template <typename T>
|
||||
inserter(T &&) -> inserter<T>;
|
||||
inserter(T &&) -> inserter<T&&>;
|
||||
template <typename T>
|
||||
inserter(T&) -> inserter<T&>;
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
|
@ -72,7 +72,7 @@ TOML_NAMESPACE_START
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
|
||||
@ -103,7 +103,7 @@ TOML_NAMESPACE_START
|
||||
/// \param flags Format option flags.
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
@ -13,45 +13,67 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T && val)
|
||||
auto* make_node_specialized(T && val, [[maybe_unused]] value_flags flags)
|
||||
{
|
||||
using type = unwrap_node<remove_cvref<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
using unwrapped_type = unwrap_node<remove_cvref<T>>;
|
||||
static_assert(!std::is_same_v<unwrapped_type, node>);
|
||||
static_assert(!is_node_view<unwrapped_type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
// arrays + tables - invoke copy/move ctor
|
||||
if constexpr (is_one_of<unwrapped_type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
return new unwrapped_type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref<T>, type>)
|
||||
|
||||
// values
|
||||
else
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
using native_type = native_type_of<unwrapped_type>;
|
||||
using value_type = value<native_type>;
|
||||
|
||||
value_type* out;
|
||||
|
||||
// copy/move ctor
|
||||
if constexpr (std::is_same_v<remove_cvref<T>, value_type>)
|
||||
{
|
||||
out = new value_type{ static_cast<T&&>(val) };
|
||||
|
||||
// only override the flags if the new ones are nonzero
|
||||
// (so the copy/move ctor does the right thing in the general case)
|
||||
if (flags != value_flags::none)
|
||||
out->flags(flags);
|
||||
}
|
||||
|
||||
// creating from raw value
|
||||
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>,
|
||||
static_assert(is_native<unwrapped_type> || is_losslessly_convertible_to_native<unwrapped_type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types");
|
||||
|
||||
using value_type = native_type_of<remove_cvref<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
out = new 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) };
|
||||
out = new value_type{ static_cast<T&&>(val) };
|
||||
|
||||
out->flags(flags);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(T && val)
|
||||
auto* make_node(T && val, value_flags flags = value_flags::none)
|
||||
{
|
||||
using type = unwrap_node<remove_cvref<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
@ -63,19 +85,20 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit(
|
||||
[](auto&& concrete) {
|
||||
return static_cast<toml::node*>(make_node_specialized(static_cast<decltype(concrete)&&>(concrete)));
|
||||
[flags](auto&& concrete) {
|
||||
return static_cast<toml::node*>(
|
||||
make_node_specialized(static_cast<decltype(concrete)&&>(concrete), flags));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
return make_node_specialized(static_cast<T&&>(val), flags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(inserter<T> && val)
|
||||
auto* make_node(inserter<T> && val, value_flags flags = value_flags::none)
|
||||
{
|
||||
return make_node(static_cast<T&&>(val.value));
|
||||
return make_node(static_cast<T&&>(val.value), flags);
|
||||
}
|
||||
|
||||
template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
|
||||
|
@ -2,8 +2,8 @@
|
||||
//# 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "print_to_stream.h"
|
||||
#include "node.h"
|
||||
#include "std_vector.h"
|
||||
@ -746,7 +746,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \cond
|
||||
#if (TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION
|
||||
#include "node_view_extern.inl"
|
||||
#endif
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "node_view.h"
|
||||
#include "header_start.h"
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION
|
||||
#include "node_view_extern.inl"
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
//# 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
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
#include "node_view.h"
|
||||
|
@ -159,46 +159,46 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::string&& k, V&& v) //
|
||||
table_init_pair(std::string&& k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::string_view k, V&& v) //
|
||||
table_init_pair(std::string_view k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ k },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(const char* k, V&& v) //
|
||||
table_init_pair(const char* k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ k },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::wstring&& k, V&& v) //
|
||||
table_init_pair(std::wstring&& k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::wstring_view k, V&& v) //
|
||||
table_init_pair(std::wstring_view k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(const wchar_t* k, V&& v) //
|
||||
table_init_pair(const wchar_t* k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(std::wstring_view{ k }) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
#endif
|
||||
@ -650,6 +650,10 @@ TOML_NAMESPACE_START
|
||||
/// (or a type promotable to one).
|
||||
/// \param key The key at which to insert the new value.
|
||||
/// \param val The new value to insert.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and `val` is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// <ul>
|
||||
@ -665,7 +669,7 @@ TOML_NAMESPACE_START
|
||||
TOML_CONSTRAINED_TEMPLATE((std::is_convertible_v<KeyType&&, std::string_view> || impl::is_wide_string<KeyType>),
|
||||
typename KeyType,
|
||||
typename ValueType)
|
||||
std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val)
|
||||
std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_wide_string<KeyType> || TOML_WINDOWS_COMPAT,
|
||||
@ -680,7 +684,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return insert(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val));
|
||||
return insert(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val), flags);
|
||||
#else
|
||||
static_assert(impl::dependent_false<KeyType>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
@ -692,7 +696,7 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { iterator{ ipos }, false };
|
||||
@ -734,22 +738,26 @@ TOML_NAMESPACE_START
|
||||
/// \tparam Iter An InputIterator to a collection of key-value pairs.
|
||||
/// \param first An iterator to the first value in the input collection.
|
||||
/// \param last An iterator to one-past-the-last value in the input collection.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and a source value is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \remarks This function is morally equivalent to calling `insert(key, value)` for each
|
||||
/// key-value pair covered by the iterator range, so any values with keys already found in the
|
||||
/// table will not be replaced.
|
||||
TOML_CONSTRAINED_TEMPLATE((!std::is_convertible_v<Iter, std::string_view> && !impl::is_wide_string<Iter>),
|
||||
typename Iter)
|
||||
void insert(Iter first, Iter last)
|
||||
void insert(Iter first, Iter last, value_flags flags = value_flags::none)
|
||||
{
|
||||
if (first == last)
|
||||
return;
|
||||
for (auto it = first; it != last; it++)
|
||||
{
|
||||
if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
|
||||
insert(std::move((*it).first), std::move((*it).second));
|
||||
insert(std::move((*it).first), std::move((*it).second), flags);
|
||||
else
|
||||
insert((*it).first, (*it).second);
|
||||
insert((*it).first, (*it).second, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,6 +801,10 @@ TOML_NAMESPACE_START
|
||||
/// (or a type promotable to one).
|
||||
/// \param key The key at which to insert or assign the value.
|
||||
/// \param val The value to insert/assign.
|
||||
/// \param flags Value flags to apply to new values.
|
||||
///
|
||||
/// \note When `flags == value_flags::none` and `val` is a value node or node_view, any existing value
|
||||
/// flags will be copied, _not_ set to none.
|
||||
///
|
||||
/// \returns \conditional_return{Valid input}
|
||||
/// <ul>
|
||||
@ -806,7 +818,9 @@ TOML_NAMESPACE_START
|
||||
/// an empty toml::node_view, because no insertion or assignment can take place.
|
||||
/// This is the only circumstance in which this can occur.
|
||||
template <typename KeyType, typename ValueType>
|
||||
std::pair<iterator, bool> insert_or_assign(KeyType&& key, ValueType&& val)
|
||||
std::pair<iterator, bool> insert_or_assign(KeyType&& key,
|
||||
ValueType&& val,
|
||||
value_flags flags = value_flags::none)
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_wide_string<KeyType> || TOML_WINDOWS_COMPAT,
|
||||
@ -821,7 +835,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return insert_or_assign(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val));
|
||||
return insert_or_assign(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val), flags);
|
||||
#else
|
||||
static_assert(impl::dependent_false<KeyType>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
@ -833,12 +847,12 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val)));
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
|
@ -10,15 +10,13 @@
|
||||
/// \cond
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'\t' || codepoint == U' ';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
// see: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -33,24 +31,21 @@ TOML_IMPL_NAMESPACE_START
|
||||
;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_whitespace(codepoint) || is_non_ascii_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = IncludeCarriageReturn ? U'\r' : U'\f';
|
||||
return (codepoint >= U'\n' && codepoint <= low_range_end);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
// see https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -63,58 +58,50 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_non_ascii_line_break(codepoint);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_string_delimiter(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_letter(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'z') || (codepoint >= U'A' && codepoint <= U'Z');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_binary_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'0' || codepoint == U'1';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_octal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'7');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_decimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'9');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_hexadecimal_digit(char32_t c) noexcept
|
||||
{
|
||||
return U'0' <= c && c <= U'f' && (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr uint_least32_t hex_to_dec(const T codepoint) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<remove_cvref<T>, uint_least32_t>)
|
||||
@ -130,8 +117,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Ll, Lm, Lo, Lt, Lu
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_letter(char32_t c) noexcept
|
||||
{
|
||||
if (U'\xAA' > c || c > U'\U0003134A')
|
||||
@ -484,8 +470,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Nd, Nl
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_number(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0660' > c || c > U'\U0001FBF9')
|
||||
@ -638,8 +623,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
//# Returns true if a codepoint belongs to any of these categories:
|
||||
//# Mn, Mc
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_combining_mark(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0300' > c || c > U'\U000E01EF')
|
||||
@ -849,8 +833,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_bare_key_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_letter(codepoint) || is_decimal_digit(codepoint) || codepoint == U'-' || codepoint == U'_'
|
||||
@ -861,8 +844,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_value_terminator(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break(codepoint) || is_ascii_whitespace(codepoint) || codepoint == U']'
|
||||
@ -870,22 +852,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
|| is_non_ascii_whitespace(codepoint);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u001F' || codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_nontab_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u0008' || (codepoint >= U'\u000A' && codepoint <= U'\u001F') || codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_unicode_surrogate(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 0xD800u && codepoint <= 0xDFFF;
|
||||
@ -917,13 +896,13 @@ TOML_IMPL_NAMESPACE_START
|
||||
36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
|
||||
};
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_PURE_INLINE_GETTER
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{ 12u };
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_PURE_INLINE_GETTER
|
||||
constexpr bool has_code_point() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{};
|
||||
@ -947,6 +926,12 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
state = state_table[state + uint_least32_t{ 256u } + type];
|
||||
}
|
||||
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr void reset() noexcept
|
||||
{
|
||||
state = {};
|
||||
}
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
|
@ -2,8 +2,8 @@
|
||||
//# 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "date_time.h"
|
||||
#include "node.h"
|
||||
#include "print_to_stream.h"
|
||||
@ -1105,7 +1105,7 @@ TOML_NAMESPACE_START
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
/// \cond
|
||||
#if (TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION
|
||||
#include "value_extern.inl"
|
||||
#endif
|
||||
/// \endcond
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "value.h"
|
||||
#include "header_start.h"
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION
|
||||
#include "value_extern.inl"
|
||||
#endif // TOML_EXTERN_TEMPLATES
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
//# 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
|
||||
#pragma once
|
||||
/// \cond
|
||||
|
||||
#include "value.h"
|
||||
|
329
toml.hpp
329
toml.hpp
@ -1197,10 +1197,14 @@ TOML_NAMESPACE_START // abi namespace
|
||||
template <typename T>
|
||||
struct TOML_TRIVIAL_ABI inserter
|
||||
{
|
||||
T&& value;
|
||||
static_assert(std::is_reference_v<T>);
|
||||
|
||||
T value;
|
||||
};
|
||||
template <typename T>
|
||||
inserter(T &&) -> inserter<T>;
|
||||
inserter(T &&) -> inserter<T&&>;
|
||||
template <typename T>
|
||||
inserter(T&) -> inserter<T&>;
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
@ -3302,7 +3306,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
@ -4344,7 +4348,7 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
TOML_NAMESPACE_END;
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && !TOML_IMPLEMENTATION
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
@ -4428,45 +4432,67 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node_specialized(T && val)
|
||||
auto* make_node_specialized(T && val, [[maybe_unused]] value_flags flags)
|
||||
{
|
||||
using type = unwrap_node<remove_cvref<T>>;
|
||||
static_assert(!std::is_same_v<type, node>);
|
||||
static_assert(!is_node_view<type>);
|
||||
using unwrapped_type = unwrap_node<remove_cvref<T>>;
|
||||
static_assert(!std::is_same_v<unwrapped_type, node>);
|
||||
static_assert(!is_node_view<unwrapped_type>);
|
||||
|
||||
if constexpr (is_one_of<type, array, table>)
|
||||
// arrays + tables - invoke copy/move ctor
|
||||
if constexpr (is_one_of<unwrapped_type, array, table>)
|
||||
{
|
||||
return new type{ static_cast<T&&>(val) };
|
||||
return new unwrapped_type{ static_cast<T&&>(val) };
|
||||
}
|
||||
else if constexpr (is_native<type> && !std::is_same_v<remove_cvref<T>, type>)
|
||||
|
||||
// values
|
||||
else
|
||||
{
|
||||
return new value<type>{ static_cast<T&&>(val) };
|
||||
using native_type = native_type_of<unwrapped_type>;
|
||||
using value_type = value<native_type>;
|
||||
|
||||
value_type* out;
|
||||
|
||||
// copy/move ctor
|
||||
if constexpr (std::is_same_v<remove_cvref<T>, value_type>)
|
||||
{
|
||||
out = new value_type{ static_cast<T&&>(val) };
|
||||
|
||||
// only override the flags if the new ones are nonzero
|
||||
// (so the copy/move ctor does the right thing in the general case)
|
||||
if (flags != value_flags::none)
|
||||
out->flags(flags);
|
||||
}
|
||||
|
||||
// creating from raw value
|
||||
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>,
|
||||
static_assert(is_native<unwrapped_type> || is_losslessly_convertible_to_native<unwrapped_type>,
|
||||
"Value initializers must be (or be promotable to) one of the TOML value types");
|
||||
|
||||
using value_type = native_type_of<remove_cvref<T>>;
|
||||
if constexpr (is_wide_string<T>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return new value<value_type>{ narrow(static_cast<T&&>(val)) };
|
||||
out = new 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) };
|
||||
out = new value_type{ static_cast<T&&>(val) };
|
||||
|
||||
out->flags(flags);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(T && val)
|
||||
auto* make_node(T && val, value_flags flags = value_flags::none)
|
||||
{
|
||||
using type = unwrap_node<remove_cvref<T>>;
|
||||
if constexpr (std::is_same_v<type, node> || is_node_view<type>)
|
||||
@ -4478,19 +4504,20 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
return static_cast<T&&>(val).visit(
|
||||
[](auto&& concrete) {
|
||||
return static_cast<toml::node*>(make_node_specialized(static_cast<decltype(concrete)&&>(concrete)));
|
||||
[flags](auto&& concrete) {
|
||||
return static_cast<toml::node*>(
|
||||
make_node_specialized(static_cast<decltype(concrete)&&>(concrete), flags));
|
||||
});
|
||||
}
|
||||
else
|
||||
return make_node_specialized(static_cast<T&&>(val));
|
||||
return make_node_specialized(static_cast<T&&>(val), flags);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
auto* make_node(inserter<T> && val)
|
||||
auto* make_node(inserter<T> && val, value_flags flags = value_flags::none)
|
||||
{
|
||||
return make_node(static_cast<T&&>(val.value));
|
||||
return make_node(static_cast<T&&>(val.value), flags);
|
||||
}
|
||||
|
||||
template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
|
||||
@ -4717,14 +4744,14 @@ TOML_NAMESPACE_START
|
||||
void preinsertion_resize(size_t idx, size_t count);
|
||||
|
||||
template <typename T>
|
||||
void emplace_back_if_not_empty_view(T&& val)
|
||||
void emplace_back_if_not_empty_view(T&& val, value_flags flags)
|
||||
{
|
||||
if constexpr (is_node_view<T>)
|
||||
{
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val)));
|
||||
elements.emplace_back(impl::make_node(static_cast<T&&>(val), flags));
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
@ -4786,10 +4813,10 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1u);
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), value_flags::none);
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals)), ...);
|
||||
(emplace_back_if_not_empty_view(static_cast<ElemTypes&&>(vals), value_flags::none), ...);
|
||||
}
|
||||
|
||||
#if TOML_LIFETIME_HOOKS
|
||||
@ -4964,18 +4991,18 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, ElemType&& val)
|
||||
iterator insert(const_iterator pos, ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
if constexpr (is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val))) };
|
||||
return { elements.emplace(pos.raw_, impl::make_node(static_cast<ElemType&&>(val), flags)) };
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, size_t count, ElemType&& val)
|
||||
iterator insert(const_iterator pos, size_t count, ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
if constexpr (is_node_view<ElemType>)
|
||||
{
|
||||
@ -4985,23 +5012,23 @@ TOML_NAMESPACE_START
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val));
|
||||
case 1: return insert(pos, static_cast<ElemType&&>(val), flags);
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, count);
|
||||
size_t i = start_idx;
|
||||
for (size_t e = start_idx + count - 1u; i < e; i++)
|
||||
elements[i].reset(impl::make_node(val));
|
||||
elements[i].reset(impl::make_node(val, flags));
|
||||
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val)));
|
||||
elements[i].reset(impl::make_node(static_cast<ElemType&&>(val), flags));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iter>
|
||||
iterator insert(const_iterator pos, Iter first, Iter last)
|
||||
iterator insert(const_iterator pos, Iter first, Iter last, value_flags flags = value_flags::none)
|
||||
{
|
||||
const auto distance = std::distance(first, last);
|
||||
if (distance <= 0)
|
||||
@ -5029,18 +5056,20 @@ TOML_NAMESPACE_START
|
||||
continue;
|
||||
}
|
||||
if constexpr (std::is_rvalue_reference_v<deref_type>)
|
||||
elements[i++].reset(impl::make_node(std::move(*it)));
|
||||
elements[i++].reset(impl::make_node(std::move(*it), flags));
|
||||
else
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
elements[i++].reset(impl::make_node(*it, flags));
|
||||
}
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist)
|
||||
iterator insert(const_iterator pos,
|
||||
std::initializer_list<ElemType> ilist,
|
||||
value_flags flags = value_flags::none)
|
||||
{
|
||||
return insert(pos, ilist.begin(), ilist.end());
|
||||
return insert(pos, ilist.begin(), ilist.end(), flags);
|
||||
}
|
||||
|
||||
template <typename ElemType, typename... Args>
|
||||
@ -5084,9 +5113,9 @@ TOML_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
void push_back(ElemType&& val)
|
||||
void push_back(ElemType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val));
|
||||
emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), flags);
|
||||
}
|
||||
|
||||
template <typename ElemType, typename... Args>
|
||||
@ -5374,46 +5403,46 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::string&& k, V&& v) //
|
||||
table_init_pair(std::string&& k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ std::move(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::string_view k, V&& v) //
|
||||
table_init_pair(std::string_view k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ k },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(const char* k, V&& v) //
|
||||
table_init_pair(const char* k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ k },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::wstring&& k, V&& v) //
|
||||
table_init_pair(std::wstring&& k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(std::wstring_view k, V&& v) //
|
||||
table_init_pair(std::wstring_view k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(k) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
template <typename V>
|
||||
TOML_NODISCARD_CTOR
|
||||
table_init_pair(const wchar_t* k, V&& v) //
|
||||
table_init_pair(const wchar_t* k, V&& v, value_flags flags = value_flags::none) //
|
||||
: key{ narrow(std::wstring_view{ k }) },
|
||||
value{ make_node(static_cast<V&&>(v)) }
|
||||
value{ make_node(static_cast<V&&>(v), flags) }
|
||||
{}
|
||||
|
||||
#endif
|
||||
@ -5671,7 +5700,7 @@ TOML_NAMESPACE_START
|
||||
TOML_CONSTRAINED_TEMPLATE((std::is_convertible_v<KeyType&&, std::string_view> || impl::is_wide_string<KeyType>),
|
||||
typename KeyType,
|
||||
typename ValueType)
|
||||
std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val)
|
||||
std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val, value_flags flags = value_flags::none)
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_wide_string<KeyType> || TOML_WINDOWS_COMPAT,
|
||||
@ -5686,7 +5715,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return insert(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val));
|
||||
return insert(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val), flags);
|
||||
#else
|
||||
static_assert(impl::dependent_false<KeyType>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
@ -5698,7 +5727,7 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { iterator{ ipos }, false };
|
||||
@ -5707,21 +5736,23 @@ TOML_NAMESPACE_START
|
||||
|
||||
TOML_CONSTRAINED_TEMPLATE((!std::is_convertible_v<Iter, std::string_view> && !impl::is_wide_string<Iter>),
|
||||
typename Iter)
|
||||
void insert(Iter first, Iter last)
|
||||
void insert(Iter first, Iter last, value_flags flags = value_flags::none)
|
||||
{
|
||||
if (first == last)
|
||||
return;
|
||||
for (auto it = first; it != last; it++)
|
||||
{
|
||||
if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
|
||||
insert(std::move((*it).first), std::move((*it).second));
|
||||
insert(std::move((*it).first), std::move((*it).second), flags);
|
||||
else
|
||||
insert((*it).first, (*it).second);
|
||||
insert((*it).first, (*it).second, flags);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
std::pair<iterator, bool> insert_or_assign(KeyType&& key, ValueType&& val)
|
||||
std::pair<iterator, bool> insert_or_assign(KeyType&& key,
|
||||
ValueType&& val,
|
||||
value_flags flags = value_flags::none)
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_wide_string<KeyType> || TOML_WINDOWS_COMPAT,
|
||||
@ -5736,7 +5767,7 @@ TOML_NAMESPACE_START
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
return insert_or_assign(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val));
|
||||
return insert_or_assign(impl::narrow(std::forward<KeyType>(key)), std::forward<ValueType>(val), flags);
|
||||
#else
|
||||
static_assert(impl::dependent_false<KeyType>, "Evaluated unreachable branch!");
|
||||
#endif
|
||||
@ -5748,12 +5779,12 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
ipos = map_.emplace_hint(ipos,
|
||||
std::forward<KeyType>(key),
|
||||
impl::make_node(std::forward<ValueType>(val)));
|
||||
impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val)));
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val), flags));
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
@ -5966,15 +5997,13 @@ TOML_DISABLE_SWITCH_WARNINGS;
|
||||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'\t' || codepoint == U' ';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
// see: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -5989,24 +6018,21 @@ TOML_IMPL_NAMESPACE_START
|
||||
;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_whitespace(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_whitespace(codepoint) || is_non_ascii_whitespace(codepoint);
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
constexpr auto low_range_end = IncludeCarriageReturn ? U'\r' : U'\f';
|
||||
return (codepoint >= U'\n' && codepoint <= low_range_end);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
// see https://en.wikipedia.org/wiki/Whitespace_character#Unicode
|
||||
@ -6019,58 +6045,50 @@ TOML_IMPL_NAMESPACE_START
|
||||
}
|
||||
|
||||
template <bool IncludeCarriageReturn = true>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_line_break(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break<IncludeCarriageReturn>(codepoint) || is_non_ascii_line_break(codepoint);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_string_delimiter(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'"' || codepoint == U'\'';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_ascii_letter(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'a' && codepoint <= U'z') || (codepoint >= U'A' && codepoint <= U'Z');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_binary_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint == U'0' || codepoint == U'1';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_octal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'7');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_decimal_digit(char32_t codepoint) noexcept
|
||||
{
|
||||
return (codepoint >= U'0' && codepoint <= U'9');
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_hexadecimal_digit(char32_t c) noexcept
|
||||
{
|
||||
return U'0' <= c && c <= U'f' && (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr uint_least32_t hex_to_dec(const T codepoint) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<remove_cvref<T>, uint_least32_t>)
|
||||
@ -6084,8 +6102,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#if TOML_LANG_UNRELEASED // toml/issues/687 (unicode bare keys)
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_letter(char32_t c) noexcept
|
||||
{
|
||||
if (U'\xAA' > c || c > U'\U0003134A')
|
||||
@ -6436,8 +6453,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_non_ascii_number(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0660' > c || c > U'\U0001FBF9')
|
||||
@ -6588,8 +6604,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
TOML_UNREACHABLE;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_combining_mark(char32_t c) noexcept
|
||||
{
|
||||
if (U'\u0300' > c || c > U'\U000E01EF')
|
||||
@ -6799,8 +6814,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
#endif // TOML_LANG_UNRELEASED
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_bare_key_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_letter(codepoint) || is_decimal_digit(codepoint) || codepoint == U'-' || codepoint == U'_'
|
||||
@ -6811,8 +6825,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
;
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_value_terminator(char32_t codepoint) noexcept
|
||||
{
|
||||
return is_ascii_line_break(codepoint) || is_ascii_whitespace(codepoint) || codepoint == U']'
|
||||
@ -6820,22 +6833,19 @@ TOML_IMPL_NAMESPACE_START
|
||||
|| is_non_ascii_whitespace(codepoint);
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u001F' || codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_nontab_control_character(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint <= U'\u0008' || (codepoint >= U'\u000A' && codepoint <= U'\u001F') || codepoint == U'\u007F';
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_ATTR(const)
|
||||
TOML_CONST_GETTER
|
||||
constexpr bool is_unicode_surrogate(char32_t codepoint) noexcept
|
||||
{
|
||||
return codepoint >= 0xD800u && codepoint <= 0xDFFF;
|
||||
@ -6866,13 +6876,13 @@ TOML_IMPL_NAMESPACE_START
|
||||
36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
|
||||
};
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_PURE_INLINE_GETTER
|
||||
constexpr bool error() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{ 12u };
|
||||
}
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_PURE_INLINE_GETTER
|
||||
constexpr bool has_code_point() const noexcept
|
||||
{
|
||||
return state == uint_least32_t{};
|
||||
@ -6896,6 +6906,12 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
state = state_table[state + uint_least32_t{ 256u } + type];
|
||||
}
|
||||
|
||||
TOML_ALWAYS_INLINE
|
||||
constexpr void reset() noexcept
|
||||
{
|
||||
state = {};
|
||||
}
|
||||
};
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END;
|
||||
@ -7412,14 +7428,16 @@ TOML_IMPL_NAMESPACE_START
|
||||
format_flags flags_; //
|
||||
int indent_; // these are set in attach()
|
||||
bool naked_newline_; //
|
||||
std::string_view indent_string_;
|
||||
size_t indent_columns_;
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
const parse_result* result_ = {};
|
||||
#endif
|
||||
|
||||
protected:
|
||||
static constexpr size_t indent_columns = 4;
|
||||
static constexpr std::string_view indent_string = " "sv;
|
||||
TOML_API
|
||||
void set_indent_string(std::string_view str) noexcept;
|
||||
|
||||
protected:
|
||||
TOML_PURE_INLINE_GETTER
|
||||
const toml::node& source() const noexcept
|
||||
{
|
||||
@ -7453,6 +7471,12 @@ TOML_IMPL_NAMESPACE_START
|
||||
indent_--;
|
||||
}
|
||||
|
||||
TOML_PURE_INLINE_GETTER
|
||||
size_t indent_columns() const noexcept
|
||||
{
|
||||
return indent_columns_;
|
||||
}
|
||||
|
||||
TOML_PURE_INLINE_GETTER
|
||||
bool indent_array_elements() const noexcept
|
||||
{
|
||||
@ -7541,19 +7565,21 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_API
|
||||
bool dump_failed_parse_result() noexcept(!TOML_PARSER || TOML_EXCEPTIONS);
|
||||
bool dump_failed_parse_result();
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
formatter(const toml::node& source, format_flags flags) noexcept //
|
||||
formatter(const toml::node& source, format_flags flags, std::string_view indent) noexcept //
|
||||
: source_{ &source },
|
||||
flags_{ flags }
|
||||
{}
|
||||
{
|
||||
set_indent_string(indent);
|
||||
}
|
||||
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
TOML_API
|
||||
formatter(const parse_result& result, format_flags flags) noexcept;
|
||||
formatter(const parse_result& result, format_flags flags, std::string_view indent) noexcept;
|
||||
|
||||
#endif
|
||||
};
|
||||
@ -7625,14 +7651,14 @@ TOML_NAMESPACE_START
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit default_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#endif
|
||||
@ -7690,14 +7716,14 @@ TOML_NAMESPACE_START
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ source, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#if defined(DOXYGEN) || (TOML_PARSER && !TOML_EXCEPTIONS)
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags }
|
||||
: base{ result, (flags | mandatory_flags) & ~ignored_flags, " "sv }
|
||||
{}
|
||||
|
||||
#endif
|
||||
@ -8316,7 +8342,7 @@ TOML_PUSH_WARNINGS;
|
||||
TOML_DISABLE_SPAM_WARNINGS;
|
||||
TOML_DISABLE_SWITCH_WARNINGS;
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
@ -8390,7 +8416,7 @@ TOML_PUSH_WARNINGS;
|
||||
TOML_DISABLE_SPAM_WARNINGS;
|
||||
TOML_DISABLE_SWITCH_WARNINGS;
|
||||
|
||||
#if (TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION) || TOML_INTELLISENSE
|
||||
#if TOML_EXTERN_TEMPLATES && TOML_IMPLEMENTATION
|
||||
|
||||
TOML_NAMESPACE_START
|
||||
{
|
||||
@ -12498,14 +12524,25 @@ TOML_IMPL_NAMESPACE_START
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
formatter::formatter(const parse_result& result, format_flags flags) noexcept //
|
||||
formatter::formatter(const parse_result& result, format_flags flags, std::string_view indent) noexcept //
|
||||
: source_{ result ? &result.table() : nullptr },
|
||||
flags_{ flags },
|
||||
result_{ &result }
|
||||
{}
|
||||
{
|
||||
set_indent_string(indent);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::set_indent_string(std::string_view str) noexcept
|
||||
{
|
||||
indent_string_ = str.data() ? str : " "sv;
|
||||
indent_columns_ = {};
|
||||
for (auto c : indent_string_)
|
||||
indent_columns_ += c == '\t' ? 4u : 1u;
|
||||
}
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
void formatter::attach(std::ostream & stream) noexcept
|
||||
{
|
||||
@ -12535,7 +12572,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
for (int i = 0; i < indent_; i++)
|
||||
{
|
||||
print_to_stream(*stream_, indent_string);
|
||||
print_to_stream(*stream_, indent_string_);
|
||||
naked_newline_ = false;
|
||||
}
|
||||
}
|
||||
@ -12689,7 +12726,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
#if TOML_PARSER && !TOML_EXCEPTIONS
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
bool formatter::dump_failed_parse_result() noexcept(false)
|
||||
bool formatter::dump_failed_parse_result()
|
||||
{
|
||||
if (result_ && !(*result_))
|
||||
{
|
||||
@ -12703,7 +12740,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
TOML_EXTERNAL_LINKAGE
|
||||
TOML_ATTR(const)
|
||||
bool formatter::dump_failed_parse_result() noexcept(true)
|
||||
bool formatter::dump_failed_parse_result()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -12774,11 +12811,11 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
case node_type::table:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const table*>(&node);
|
||||
if (n.empty())
|
||||
auto& tbl = *reinterpret_cast<const table*>(&node);
|
||||
if (tbl.empty())
|
||||
return 2u; // "{}"
|
||||
size_t weight = 3u; // "{ }"
|
||||
for (auto&& [k, v] : n)
|
||||
for (auto&& [k, v] : tbl)
|
||||
{
|
||||
weight += k.length() + count_inline_columns(v) + 2u; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
@ -12789,11 +12826,11 @@ TOML_NAMESPACE_START
|
||||
|
||||
case node_type::array:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const array*>(&node);
|
||||
if (n.empty())
|
||||
auto& arr = *reinterpret_cast<const array*>(&node);
|
||||
if (arr.empty())
|
||||
return 2u; // "[]"
|
||||
size_t weight = 3u; // "[ ]"
|
||||
for (auto& elem : n)
|
||||
for (auto& elem : arr)
|
||||
{
|
||||
weight += count_inline_columns(elem) + 2u; // + ", "
|
||||
if (weight >= line_wrap_cols)
|
||||
@ -12804,38 +12841,38 @@ TOML_NAMESPACE_START
|
||||
|
||||
case node_type::string:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<std::string>*>(&node);
|
||||
return n.get().length() + 2u; // + ""
|
||||
// todo: proper utf8 decoding?
|
||||
// todo: tab awareness?
|
||||
auto& str = (*reinterpret_cast<const value<std::string>*>(&node)).get();
|
||||
return str.length() + 2u; // + ""
|
||||
}
|
||||
|
||||
case node_type::integer:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<int64_t>*>(&node);
|
||||
auto v = n.get();
|
||||
if (!v)
|
||||
auto val = (*reinterpret_cast<const value<int64_t>*>(&node)).get();
|
||||
if (!val)
|
||||
return 1u;
|
||||
size_t weight = {};
|
||||
if (v < 0)
|
||||
if (val < 0)
|
||||
{
|
||||
weight += 1u;
|
||||
v *= -1;
|
||||
val *= -1;
|
||||
}
|
||||
return weight + static_cast<size_t>(log10(static_cast<double>(v))) + 1u;
|
||||
return weight + static_cast<size_t>(log10(static_cast<double>(val))) + 1u;
|
||||
}
|
||||
|
||||
case node_type::floating_point:
|
||||
{
|
||||
auto& n = *reinterpret_cast<const value<double>*>(&node);
|
||||
auto v = n.get();
|
||||
if (v == 0.0)
|
||||
auto val = (*reinterpret_cast<const value<double>*>(&node)).get();
|
||||
if (val == 0.0)
|
||||
return 3u; // "0.0"
|
||||
size_t weight = 2u; // ".0"
|
||||
if (v < 0.0)
|
||||
if (val < 0.0)
|
||||
{
|
||||
weight += 1u;
|
||||
v *= -1.0;
|
||||
val *= -1.0;
|
||||
}
|
||||
return weight + static_cast<size_t>(log10(v)) + 1u;
|
||||
return weight + static_cast<size_t>(log10(val)) + 1u;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -12953,9 +12990,9 @@ TOML_NAMESPACE_START
|
||||
else
|
||||
{
|
||||
const auto original_indent = base::indent();
|
||||
const auto multiline =
|
||||
forces_multiline(arr,
|
||||
base::indent_columns * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
const auto multiline = forces_multiline(
|
||||
arr,
|
||||
base::indent_columns() * static_cast<size_t>(original_indent < 0 ? 0 : original_indent));
|
||||
impl::print_to_stream(base::stream(), "["sv);
|
||||
if (multiline)
|
||||
{
|
||||
|
@ -16,15 +16,10 @@ from io import StringIO
|
||||
class Preprocessor:
|
||||
|
||||
__re_includes = re.compile(r'^\s*#\s*include\s+"(.+?)".*?$', re.I | re.M)
|
||||
__multiples_allowed = [
|
||||
r'impl/header_start.h',
|
||||
r'impl/header_end.h',
|
||||
r'impl/value_extern.inl',
|
||||
r'impl/node_view_extern.inl',
|
||||
]
|
||||
__re_pragma_once = re.compile(r'^\s*#\s*pragma\s+once\s*$', re.M)
|
||||
|
||||
def __init__(self, file):
|
||||
self.__processed_includes = set()
|
||||
self.__once_only = set()
|
||||
self.__current_level = 0
|
||||
self.__directory_stack = [ Path.cwd() ]
|
||||
self.__entry_root = ''
|
||||
@ -38,27 +33,30 @@ class Preprocessor:
|
||||
incl = Path(incl.strip().replace('\\',r'/'))
|
||||
if not incl.is_absolute():
|
||||
incl = Path(self.__directory_stack[-1], incl).resolve()
|
||||
if self.__current_level == 0 and self.__entry_root == '':
|
||||
self.__entry_root = str(incl.parent).replace('\\',r'/')
|
||||
|
||||
relative_path = str(incl).replace('\\',r'/')
|
||||
if relative_path.startswith(self.__entry_root):
|
||||
relative_path = relative_path[len(self.__entry_root):].strip('/')
|
||||
|
||||
if incl in self.__processed_includes and relative_path not in self.__multiples_allowed:
|
||||
if incl in self.__once_only:
|
||||
return ''
|
||||
|
||||
self.__processed_includes.add(incl)
|
||||
self.__directory_stack.append(incl.parent)
|
||||
|
||||
text = utils.read_all_text_from_file(incl, logger=True).strip() + '\n'
|
||||
text = text.replace('\r\n', '\n') # convert windows newlines
|
||||
|
||||
self.__directory_stack.append(incl.parent)
|
||||
if self.__re_pragma_once.search(text):
|
||||
self.__once_only.add(incl)
|
||||
if self.__current_level == 0 and self.__entry_root == '':
|
||||
self.__entry_root = str(incl.parent).replace('\\',r'/')
|
||||
if self.__current_level > 0:
|
||||
text = self.__re_pragma_once.sub('', text)
|
||||
|
||||
self.__current_level += 1
|
||||
text = self.__re_includes.sub(lambda m : self.__preprocess(m), text, 0)
|
||||
self.__current_level -= 1
|
||||
|
||||
if self.__current_level == 1:
|
||||
header = utils.make_divider(relative_path, 10, pattern = r'*')
|
||||
header = str(incl).replace('\\',r'/')
|
||||
if header.startswith(self.__entry_root):
|
||||
header = header[len(self.__entry_root):].strip('/')
|
||||
header = utils.make_divider(header, 10, pattern = r'*')
|
||||
text = f'\n\n{header}\n\n{text}'
|
||||
|
||||
self.__directory_stack.pop()
|
||||
@ -80,8 +78,6 @@ def main():
|
||||
|
||||
# strip various things:
|
||||
if 1:
|
||||
# 'pragma once'
|
||||
toml_h = re.sub(r'^\s*#\s*pragma\s+once\s*$', '', toml_h, 0, re.I | re.M)
|
||||
# trailing whitespace
|
||||
toml_h = re.sub('([^ \t])[ \t]+\n', r'\1\n', toml_h)
|
||||
# explicit 'strip this' blocks
|
||||
|
Loading…
Reference in New Issue
Block a user