added insert, emplace, push_back etc. compatibility with node_views
In service of satisfying #49.
This commit is contained in:
parent
17d1876529
commit
2efb15bf9e
@ -350,7 +350,6 @@ PREDEFINED = \
|
||||
"TOML_TRIVIAL_ABI=" \
|
||||
"TOML_EMPTY_BASES=" \
|
||||
"TOML_INTERFACE" \
|
||||
"TOML_SIMPLE_STATIC_ASSERT_MESSAGES=1" \
|
||||
"TOML_INTERNAL_LINKAGE=static"
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
|
@ -47,7 +47,7 @@ article div > section > section
|
||||
|
||||
pre, code, .tpp-enable-if > a
|
||||
{
|
||||
font-family: 'Consolas', 'Source Code Pro', monospace, monospace, monospace;
|
||||
font-family: 'Consolas', 'Source Code Pro', monospace;
|
||||
}
|
||||
|
||||
a.tpp-external
|
||||
@ -142,6 +142,7 @@ pre.m-code + pre.m-console span
|
||||
.m-doc-details div table.m-table.m-fullwidth.m-flat tbody tr td strong em
|
||||
{
|
||||
color: #a5c9ea;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* comments */
|
||||
@ -316,9 +317,10 @@ pre > p.godbolt
|
||||
{
|
||||
float: right;
|
||||
}
|
||||
@media only screen and ((max-width: 575px) or ((hover: none) and (pointer: coarse)))
|
||||
@media only screen and ((max-width: 575px) or (hover: none) or (pointer: coarse) or (pointer: none))
|
||||
{
|
||||
.godbolt {
|
||||
.godbolt
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,10 @@ int main(int argc, char** argv)
|
||||
toml::node* new_node{};
|
||||
|
||||
if (auto arr = tree.back()->as_array())
|
||||
new_node = &arr->push_back(std::forward<decltype(obj)>(obj));
|
||||
{
|
||||
arr->push_back(std::forward<decltype(obj)>(obj));
|
||||
new_node = &arr->back();
|
||||
}
|
||||
else
|
||||
new_node = &(*tree.back()->ref<toml::table>().insert_or_assign(
|
||||
rand_string(rand<size_t>(1u, 4u), '-'),
|
||||
|
@ -15,7 +15,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
class TOML_TRIVIAL_ABI array_iterator final
|
||||
{
|
||||
private:
|
||||
friend class ::toml::array;
|
||||
friend class TOML_NAMESPACE::array;
|
||||
|
||||
using raw_mutable_iterator = std::vector<std::unique_ptr<node>>::iterator;
|
||||
using raw_const_iterator = std::vector<std::unique_ptr<node>>::const_iterator;
|
||||
@ -180,6 +180,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
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>)
|
||||
{
|
||||
@ -211,12 +212,17 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node>)
|
||||
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 std::forward<T>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(std::forward<decltype(concrete)>(concrete)));
|
||||
@ -228,7 +234,6 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(std::move(val.value));
|
||||
@ -304,6 +309,17 @@ TOML_NAMESPACE_START
|
||||
|
||||
void preinsertion_resize(size_t idx, size_t count) noexcept;
|
||||
|
||||
template <typename T>
|
||||
void emplace_back_if_not_empty_view(T&& val) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<T>)
|
||||
{
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(std::forward<T>(val)));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using value_type = node;
|
||||
@ -376,11 +392,11 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1_sz);
|
||||
elements.emplace_back(impl::make_node(std::forward<ElemType>(val)));
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(
|
||||
elements.emplace_back(impl::make_node(std::forward<ElemTypes>(vals))),
|
||||
emplace_back_if_not_empty_view(std::forward<ElemTypes>(vals)),
|
||||
...
|
||||
);
|
||||
}
|
||||
@ -529,14 +545,27 @@ TOML_NAMESPACE_START
|
||||
/// [ 1, 'two', 3, [ 4, 5 ] ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam ElemType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param val The node or value being inserted.
|
||||
///
|
||||
/// \returns An iterator to the newly-inserted element.
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// An iterator to the newly-inserted element.
|
||||
/// <br><br>
|
||||
/// <strong><em>`val` is an empty toml::node_view:</em></strong><br>
|
||||
/// end()
|
||||
///
|
||||
/// \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) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(std::forward<ElemType>(val))) };
|
||||
}
|
||||
|
||||
@ -562,15 +591,31 @@ TOML_NAMESPACE_START
|
||||
/// ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam ElemType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// (or a type promotable to one).
|
||||
/// \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.
|
||||
///
|
||||
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if count was 0).
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// An iterator to the newly-inserted element.
|
||||
/// <br><br>
|
||||
/// <strong><em>`count == 0`:</em></strong><br>
|
||||
/// A copy of pos
|
||||
/// <br><br>
|
||||
/// <strong><em>`val` is an empty toml::node_view:</em></strong><br>
|
||||
/// end()
|
||||
///
|
||||
/// \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) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
@ -597,50 +642,70 @@ TOML_NAMESPACE_START
|
||||
/// \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.
|
||||
///
|
||||
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if `first` >= `last`).
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// An iterator to the first newly-inserted element.
|
||||
/// <br><br>
|
||||
/// <strong><em>`first >= last`:</em></strong><br>
|
||||
/// A copy of pos
|
||||
/// <br><br>
|
||||
/// <strong><em>All objects in the range were empty toml::node_views:</em></strong><br>
|
||||
/// A copy of pos
|
||||
template <typename Iter>
|
||||
iterator insert(const_iterator pos, Iter first, Iter last) noexcept
|
||||
{
|
||||
const auto count = std::distance(first, last);
|
||||
if (count <= 0)
|
||||
const auto distance = std::distance(first, last);
|
||||
if (distance <= 0)
|
||||
return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
else if (count == 1)
|
||||
return insert(pos, *first);
|
||||
else
|
||||
{
|
||||
auto count = distance;
|
||||
using deref_type = decltype(*first);
|
||||
if constexpr (impl::is_node_view<deref_type>)
|
||||
{
|
||||
for (auto it = first; it != last; it++)
|
||||
if (!(*it))
|
||||
count--;
|
||||
if (!count)
|
||||
return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
}
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, static_cast<size_t>(count));
|
||||
size_t i = start_idx;
|
||||
for (auto it = first; it != last; it++)
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
{
|
||||
if constexpr (impl::is_node_view<deref_type>)
|
||||
{
|
||||
if (!(*it))
|
||||
continue;
|
||||
}
|
||||
if constexpr (std::is_rvalue_reference_v<deref_type>)
|
||||
elements[i++].reset(impl::make_node(std::move(*it)));
|
||||
else
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
}
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Inserts a range of elements into the array at a specific position.
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam ElemType toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// (or a type promotable to one).
|
||||
/// \param pos The insertion position.
|
||||
/// \param ilist An initializer list containing the values to be inserted.
|
||||
///
|
||||
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if `ilist` was empty).
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// An iterator to the first newly-inserted element.
|
||||
/// <br><br>
|
||||
/// <strong><em>`ilist.size() == 0`:</em></strong><br>
|
||||
/// A copy of pos
|
||||
/// <br><br>
|
||||
/// <strong><em>All objects in the list were empty toml::node_views:</em></strong><br>
|
||||
/// A copy of pos
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist) noexcept
|
||||
{
|
||||
switch (ilist.size())
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, *ilist.begin());
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, ilist.size());
|
||||
size_t i = start_idx;
|
||||
for (auto& val : ilist)
|
||||
elements[i++].reset(impl::make_node(val));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
return insert(pos, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new element at a specific position in the array.
|
||||
@ -658,7 +723,7 @@ TOML_NAMESPACE_START
|
||||
/// [ 1, 'drill', 2 ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types.
|
||||
/// \tparam ElemType toml::table, toml::array, or any native TOML value type.
|
||||
/// \tparam Args Value constructor argument types.
|
||||
/// \param pos The insertion position.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
@ -745,13 +810,19 @@ TOML_NAMESPACE_START
|
||||
/// [ 1, 2 ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam ElemType toml::node, toml::table, toml::array, or a native TOML value type
|
||||
/// (or a type promotable to one).
|
||||
///
|
||||
/// \param new_size The number of elements the array will have after resizing.
|
||||
/// \param default_init_val The node or value used to initialize new elements if the array needs to grow.
|
||||
template <typename ElemType>
|
||||
void resize(size_t new_size, ElemType&& default_init_val) noexcept
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_node_view<ElemType>,
|
||||
"The default element type argument to toml::array::resize may not be toml::node_view."
|
||||
);
|
||||
|
||||
if (!new_size)
|
||||
elements.clear();
|
||||
else if (new_size < elements.size())
|
||||
@ -800,16 +871,15 @@ TOML_NAMESPACE_START
|
||||
/// [ 1, 2, 3, 4.0, [ 5, 'six' ] ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \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.
|
||||
///
|
||||
/// \returns A reference to the newly-constructed element.
|
||||
/// \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>
|
||||
decltype(auto) push_back(ElemType&& val) noexcept
|
||||
void push_back(ElemType&& val) noexcept
|
||||
{
|
||||
auto nde = impl::make_node(std::forward<ElemType>(val));
|
||||
elements.emplace_back(nde);
|
||||
return *nde;
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
}
|
||||
|
||||
/// \brief Emplaces a new element at the end of the array.
|
||||
@ -825,7 +895,7 @@ TOML_NAMESPACE_START
|
||||
/// [ 1, 2, [ 3, 'four' ] ]
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType One of the TOML node or value types.
|
||||
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
|
||||
/// \tparam Args Value constructor argument types.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
///
|
||||
@ -895,7 +965,7 @@ TOML_NAMESPACE_START
|
||||
/// element [0] is an integer with value 42
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ElemType The element's type.
|
||||
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
|
||||
/// \param index The element's index.
|
||||
///
|
||||
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
|
||||
@ -910,7 +980,7 @@ TOML_NAMESPACE_START
|
||||
|
||||
/// \brief Gets the element at a specific index if it is a particular type (const overload).
|
||||
///
|
||||
/// \tparam ElemType The element's type.
|
||||
/// \tparam ElemType toml::table, toml::array, or a native TOML value type
|
||||
/// \param index The element's index.
|
||||
///
|
||||
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
|
||||
|
@ -549,6 +549,9 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <> struct node_type_getter<array> { static constexpr auto value = node_type::array; };
|
||||
template <typename T>
|
||||
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref_t<T>>>::value;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_node_view = is_one_of<impl::remove_cvref_t<T>, node_view<node>, node_view<const node>>;
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
|
@ -10,7 +10,7 @@ TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_DISABLE_MISC_WARNINGS
|
||||
|
||||
#if TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#if defined(doxygen) || TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
|
||||
#define TOML_SA_NEWLINE " "
|
||||
#define TOML_SA_LIST_SEP ", "
|
||||
|
@ -63,8 +63,8 @@ TOML_NAMESPACE_START
|
||||
using viewed_type = ViewedType;
|
||||
|
||||
private:
|
||||
friend class toml::table;
|
||||
template <typename T> friend class toml::node_view;
|
||||
friend class TOML_NAMESPACE::table;
|
||||
template <typename T> friend class TOML_NAMESPACE::node_view;
|
||||
|
||||
mutable viewed_type* node_ = nullptr;
|
||||
|
||||
@ -83,6 +83,19 @@ TOML_NAMESPACE_START
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view() noexcept = default;
|
||||
|
||||
///// \brief Copy constructor.
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view(const node_view&) noexcept = default;
|
||||
|
||||
///// \brief Copy-assignment operator.
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view& operator= (const node_view&) noexcept = default;
|
||||
|
||||
///// \brief Move constructor.
|
||||
node_view(node_view&&) noexcept = default;
|
||||
|
||||
node_view& operator= (node_view&&) noexcept = delete;
|
||||
|
||||
/// \brief Returns true if the view references a node.
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return node_ != nullptr; }
|
||||
/// \brief Returns the node that's being referenced by the view.
|
||||
|
@ -25,7 +25,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
class table_iterator final
|
||||
{
|
||||
private:
|
||||
friend class ::toml::table;
|
||||
friend class TOML_NAMESPACE::table;
|
||||
|
||||
using proxy_type = table_proxy_pair<IsConst>;
|
||||
using raw_mutable_iterator = string_map<std::unique_ptr<node>>::iterator;
|
||||
@ -278,7 +278,6 @@ TOML_NAMESPACE_START
|
||||
: table{ arr, N }
|
||||
{}
|
||||
|
||||
|
||||
/// \brief Always returns `node_type::table` for table nodes.
|
||||
[[nodiscard]] node_type type() const noexcept override;
|
||||
/// \brief Always returns `true` for table nodes.
|
||||
@ -453,13 +452,22 @@ TOML_NAMESPACE_START
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam KeyType std::string (or a type convertible to it).
|
||||
/// \tparam ValueType One of the TOML ndoe or value types (or a type promotable to one).
|
||||
/// \tparam ValueType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// (or a type promotable to one).
|
||||
/// \param key The key at which to insert the new value.
|
||||
/// \param val The new value to insert.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// - An iterator to the insertion position (or the position of the value that prevented insertion)
|
||||
/// - A boolean indicating if the insertion was successful.
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// <ul>
|
||||
/// <li>An iterator to the insertion position (or the position of the value that prevented insertion)
|
||||
/// <li>A boolean indicating if the insertion was successful.
|
||||
/// </ul>
|
||||
/// <strong><em>`val` is an empty toml::node_view:</em></strong><br>
|
||||
/// `{ end(), false }`
|
||||
///
|
||||
/// \attention The return value will always be `{ end(), false }` 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 KeyType, typename ValueType, typename = std::enable_if_t<
|
||||
std::is_convertible_v<KeyType&&, std::string_view>
|
||||
|| impl::is_wide_string<KeyType>
|
||||
@ -471,6 +479,12 @@ TOML_NAMESPACE_START
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (impl::is_node_view<ValueType>)
|
||||
{
|
||||
if (!val)
|
||||
return { end(), false };
|
||||
}
|
||||
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -485,9 +499,9 @@ TOML_NAMESPACE_START
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos, std::forward<KeyType>(key), impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,13 +597,22 @@ TOML_NAMESPACE_START
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam KeyType std::string (or a type convertible to it).
|
||||
/// \tparam ValueType One of the TOML node or value types (or a type promotable to one).
|
||||
/// \tparam ValueType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
|
||||
/// (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.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// - An iterator to the value's position
|
||||
/// - A boolean containing `true` if the value was inserted, `false` if it was assigned.
|
||||
/// \returns <strong><em>Valid input:</em></strong><br>
|
||||
/// <ul>
|
||||
/// <li>An iterator to the value's position
|
||||
/// <li>`true` if the value was inserted, `false` if it was assigned.
|
||||
/// </ul>
|
||||
/// <strong><em>`val` is an empty toml::node_view:</em></strong><br>
|
||||
/// `{ end(), false }`
|
||||
///
|
||||
/// \attention The return value will always be `{ end(), false }` if the input value was
|
||||
/// 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) noexcept
|
||||
{
|
||||
@ -598,6 +621,12 @@ TOML_NAMESPACE_START
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (impl::is_node_view<ValueType>)
|
||||
{
|
||||
if (!val)
|
||||
return { end(), false };
|
||||
}
|
||||
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -612,12 +641,12 @@ TOML_NAMESPACE_START
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos, std::forward<KeyType>(key), impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -649,13 +678,13 @@ TOML_NAMESPACE_START
|
||||
/// { a = 1, b = 2, c = 3, d = "drill" }
|
||||
/// \eout
|
||||
///
|
||||
/// \tparam ValueType One of the TOML node or value types.
|
||||
/// \tparam ValueType toml::table, toml::array, or any native TOML value type.
|
||||
/// \tparam KeyType std::string (or a type convertible to it).
|
||||
/// \tparam ValueArgs Value constructor argument types.
|
||||
/// \param key The key at which to emplace the new value.
|
||||
/// \param args Arguments to forward to the value's constructor.
|
||||
///
|
||||
/// \returns A std::pair containing:
|
||||
/// \returns A std::pair containing: <br>
|
||||
/// - An iterator to the emplacement position (or the position of the value that prevented emplacement)
|
||||
/// - A boolean indicating if the emplacement was successful.
|
||||
///
|
||||
@ -694,9 +723,9 @@ TOML_NAMESPACE_START
|
||||
std::forward<KeyType>(key),
|
||||
new impl::wrap_node<type>{ std::forward<ValueArgs>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,8 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (!pairs[i].value) // empty node_views
|
||||
continue;
|
||||
map.insert_or_assign(
|
||||
std::move(pairs[i].key),
|
||||
std::move(pairs[i].value)
|
||||
|
@ -120,6 +120,7 @@ def main():
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -256,7 +256,8 @@ TEST_CASE("arrays - insertion and erasure")
|
||||
|
||||
// push_back(ElemType&& val) noexcept
|
||||
{
|
||||
decltype(auto) val = arr.push_back("test"sv);
|
||||
arr.push_back("test"sv);
|
||||
auto& val = *arr.back().as_string();
|
||||
CHECK(arr.size() == 6_sz);
|
||||
REQUIRE(arr.get_as<std::string>(5_sz));
|
||||
CHECK(*arr.get_as<std::string>(5_sz) == "test"sv);
|
||||
|
@ -21,6 +21,7 @@ test_sources = [
|
||||
'manipulating_values.cpp',
|
||||
'unicode.cpp',
|
||||
'unicode_generated.cpp',
|
||||
'user_feedback.cpp',
|
||||
'windows_compat.cpp'
|
||||
]
|
||||
|
||||
@ -300,12 +301,6 @@ foreach cpp20 : cpp20_modes
|
||||
name = name + '_tlopt'
|
||||
endif
|
||||
|
||||
if compiler_supports_float16
|
||||
if compiler.get_id() == 'gcc'
|
||||
args += '-mfp16-format=ieee'
|
||||
endif
|
||||
endif
|
||||
|
||||
executables += [[
|
||||
name,
|
||||
executable(
|
||||
|
@ -84,12 +84,12 @@
|
||||
#ifndef SHOULD_HAVE_FLOAT16
|
||||
#define SHOULD_HAVE_FLOAT16 0
|
||||
#endif
|
||||
#ifndef SHOULD_HAVE_INT128
|
||||
#define SHOULD_HAVE_INT128 0
|
||||
#endif
|
||||
#ifndef SHOULD_HAVE_FLOAT128
|
||||
#define SHOULD_HAVE_FLOAT128 0
|
||||
#endif
|
||||
#ifndef SHOULD_HAVE_INT128
|
||||
#define SHOULD_HAVE_INT128 0
|
||||
#endif
|
||||
#ifndef SHOULD_HAVE_EXCEPTIONS
|
||||
#define SHOULD_HAVE_EXCEPTIONS 1
|
||||
#endif
|
||||
|
88
tests/user_feedback.cpp
Normal file
88
tests/user_feedback.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
// 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 "tests.h"
|
||||
|
||||
// this file is about testing user misc. repros submitted via github issues, et cetera.
|
||||
|
||||
TEST_CASE("feedback - github/issues/49")
|
||||
{
|
||||
// see: https://github.com/marzer/tomlplusplus/issues/49#issuecomment-664428571
|
||||
{
|
||||
toml::table t1;
|
||||
t1.insert_or_assign("bar1", toml::array{ 1, 2, 3 });
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } }
|
||||
}});
|
||||
|
||||
t1.insert_or_assign("foo1", *t1.get("bar1"));
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3 } }
|
||||
}});
|
||||
|
||||
//t1["foo1"] = t1["bar1"]; // does nothing, should this fail to compile?
|
||||
// - yes -
|
||||
|
||||
//*t1["foo1"].node() = *t1["bar1"].node(); // compile failure; copying node_view would be a bad thing
|
||||
// - correct; copying toml::node directly like that is impossible b.c. it's an abstract base class-
|
||||
|
||||
toml::array* array1 = t1["foo1"].node()->as_array();
|
||||
array1->push_back(4);
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
|
||||
t1.insert_or_assign("foo3", t1["foo1"]);
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
|
||||
t1.insert_or_assign("foo2", *t1["foo1"].node());
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo2"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
|
||||
toml::array* array2 = t1["foo2"].node()->as_array();
|
||||
array2->push_back("wrench");
|
||||
CHECK(t1 == toml::table{{
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
|
||||
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
|
||||
toml::table t2 = t1;
|
||||
CHECK(t2 == t1);
|
||||
CHECK(&t2 != &t1);
|
||||
|
||||
//t2.emplace("bar", toml::array{6, 7}); // fails to compile? not sure what I did wrong
|
||||
// - it should be this: -
|
||||
t2.emplace<toml::array>("bar", 6, 7);
|
||||
CHECK(t2 == toml::table{{
|
||||
{ "bar"sv, toml::array{ 6, 7 } },
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
|
||||
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
|
||||
t2.insert_or_assign("bar2", toml::array{ 6, 7 });
|
||||
CHECK(t2 == toml::table{{
|
||||
{ "bar"sv, toml::array{ 6, 7 } },
|
||||
{ "bar1"sv, toml::array{ 1, 2, 3 } },
|
||||
{ "bar2"sv, toml::array{ 6, 7 } },
|
||||
{ "foo1"sv, toml::array{ 1, 2, 3, 4 } },
|
||||
{ "foo2"sv, toml::array{ 1, 2, 3, 4, "wrench" } },
|
||||
{ "foo3"sv, toml::array{ 1, 2, 3, 4 } }
|
||||
}});
|
||||
}
|
||||
}
|
139
toml.hpp
139
toml.hpp
@ -1067,6 +1067,9 @@ TOML_IMPL_NAMESPACE_START
|
||||
template <> struct node_type_getter<array> { static constexpr auto value = node_type::array; };
|
||||
template <typename T>
|
||||
inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref_t<T>>>::value;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_node_view = is_one_of<impl::remove_cvref_t<T>, node_view<node>, node_view<const node>>;
|
||||
}
|
||||
TOML_IMPL_NAMESPACE_END
|
||||
|
||||
@ -2026,7 +2029,7 @@ TOML_PUSH_WARNINGS
|
||||
TOML_DISABLE_PADDING_WARNINGS
|
||||
TOML_DISABLE_MISC_WARNINGS
|
||||
|
||||
#if TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
#if defined(doxygen) || TOML_SIMPLE_STATIC_ASSERT_MESSAGES
|
||||
|
||||
#define TOML_SA_NEWLINE " "
|
||||
#define TOML_SA_LIST_SEP ", "
|
||||
@ -3235,7 +3238,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
class TOML_TRIVIAL_ABI array_iterator final
|
||||
{
|
||||
private:
|
||||
friend class ::toml::array;
|
||||
friend class TOML_NAMESPACE::array;
|
||||
|
||||
using raw_mutable_iterator = std::vector<std::unique_ptr<node>>::iterator;
|
||||
using raw_const_iterator = std::vector<std::unique_ptr<node>>::const_iterator;
|
||||
@ -3400,6 +3403,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
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>)
|
||||
{
|
||||
@ -3431,12 +3435,17 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node(T&& val) noexcept
|
||||
{
|
||||
using type = unwrap_node<remove_cvref_t<T>>;
|
||||
if constexpr (std::is_same_v<type, node>)
|
||||
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 std::forward<T>(val).visit([](auto&& concrete) noexcept
|
||||
{
|
||||
return static_cast<toml::node*>(make_node_specialized(std::forward<decltype(concrete)>(concrete)));
|
||||
@ -3448,7 +3457,6 @@ TOML_IMPL_NAMESPACE_START
|
||||
|
||||
template <typename T>
|
||||
[[nodiscard]]
|
||||
TOML_ATTR(returns_nonnull)
|
||||
auto* make_node(inserter<T>&& val) noexcept
|
||||
{
|
||||
return make_node(std::move(val.value));
|
||||
@ -3470,6 +3478,17 @@ TOML_NAMESPACE_START
|
||||
|
||||
void preinsertion_resize(size_t idx, size_t count) noexcept;
|
||||
|
||||
template <typename T>
|
||||
void emplace_back_if_not_empty_view(T&& val) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<T>)
|
||||
{
|
||||
if (!val)
|
||||
return;
|
||||
}
|
||||
elements.emplace_back(impl::make_node(std::forward<T>(val)));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using value_type = node;
|
||||
@ -3499,11 +3518,11 @@ TOML_NAMESPACE_START
|
||||
explicit array(ElemType&& val, ElemTypes&&... vals)
|
||||
{
|
||||
elements.reserve(sizeof...(ElemTypes) + 1_sz);
|
||||
elements.emplace_back(impl::make_node(std::forward<ElemType>(val)));
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
if constexpr (sizeof...(ElemTypes) > 0)
|
||||
{
|
||||
(
|
||||
elements.emplace_back(impl::make_node(std::forward<ElemTypes>(vals))),
|
||||
emplace_back_if_not_empty_view(std::forward<ElemTypes>(vals)),
|
||||
...
|
||||
);
|
||||
}
|
||||
@ -3560,12 +3579,22 @@ TOML_NAMESPACE_START
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, ElemType&& val) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
return { elements.emplace(pos.raw_, impl::make_node(std::forward<ElemType>(val))) };
|
||||
}
|
||||
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, size_t count, ElemType&& val) noexcept
|
||||
{
|
||||
if constexpr (impl::is_node_view<ElemType>)
|
||||
{
|
||||
if (!val)
|
||||
return end();
|
||||
}
|
||||
switch (count)
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
@ -3587,18 +3616,36 @@ TOML_NAMESPACE_START
|
||||
template <typename Iter>
|
||||
iterator insert(const_iterator pos, Iter first, Iter last) noexcept
|
||||
{
|
||||
const auto count = std::distance(first, last);
|
||||
if (count <= 0)
|
||||
const auto distance = std::distance(first, last);
|
||||
if (distance <= 0)
|
||||
return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
else if (count == 1)
|
||||
return insert(pos, *first);
|
||||
else
|
||||
{
|
||||
auto count = distance;
|
||||
using deref_type = decltype(*first);
|
||||
if constexpr (impl::is_node_view<deref_type>)
|
||||
{
|
||||
for (auto it = first; it != last; it++)
|
||||
if (!(*it))
|
||||
count--;
|
||||
if (!count)
|
||||
return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
}
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, static_cast<size_t>(count));
|
||||
size_t i = start_idx;
|
||||
for (auto it = first; it != last; it++)
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
{
|
||||
if constexpr (impl::is_node_view<deref_type>)
|
||||
{
|
||||
if (!(*it))
|
||||
continue;
|
||||
}
|
||||
if constexpr (std::is_rvalue_reference_v<deref_type>)
|
||||
elements[i++].reset(impl::make_node(std::move(*it)));
|
||||
else
|
||||
elements[i++].reset(impl::make_node(*it));
|
||||
}
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
@ -3606,20 +3653,7 @@ TOML_NAMESPACE_START
|
||||
template <typename ElemType>
|
||||
iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist) noexcept
|
||||
{
|
||||
switch (ilist.size())
|
||||
{
|
||||
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
||||
case 1: return insert(pos, *ilist.begin());
|
||||
default:
|
||||
{
|
||||
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
||||
preinsertion_resize(start_idx, ilist.size());
|
||||
size_t i = start_idx;
|
||||
for (auto& val : ilist)
|
||||
elements[i++].reset(impl::make_node(val));
|
||||
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
||||
}
|
||||
}
|
||||
return insert(pos, ilist.begin(), ilist.end());
|
||||
}
|
||||
|
||||
template <typename ElemType, typename... Args>
|
||||
@ -3641,6 +3675,11 @@ TOML_NAMESPACE_START
|
||||
template <typename ElemType>
|
||||
void resize(size_t new_size, ElemType&& default_init_val) noexcept
|
||||
{
|
||||
static_assert(
|
||||
!impl::is_node_view<ElemType>,
|
||||
"The default element type argument to toml::array::resize may not be toml::node_view."
|
||||
);
|
||||
|
||||
if (!new_size)
|
||||
elements.clear();
|
||||
else if (new_size < elements.size())
|
||||
@ -3652,11 +3691,9 @@ TOML_NAMESPACE_START
|
||||
void truncate(size_t new_size);
|
||||
|
||||
template <typename ElemType>
|
||||
decltype(auto) push_back(ElemType&& val) noexcept
|
||||
void push_back(ElemType&& val) noexcept
|
||||
{
|
||||
auto nde = impl::make_node(std::forward<ElemType>(val));
|
||||
elements.emplace_back(nde);
|
||||
return *nde;
|
||||
emplace_back_if_not_empty_view(std::forward<ElemType>(val));
|
||||
}
|
||||
|
||||
template <typename ElemType, typename... Args>
|
||||
@ -3786,7 +3823,7 @@ TOML_IMPL_NAMESPACE_START
|
||||
class table_iterator final
|
||||
{
|
||||
private:
|
||||
friend class ::toml::table;
|
||||
friend class TOML_NAMESPACE::table;
|
||||
|
||||
using proxy_type = table_proxy_pair<IsConst>;
|
||||
using raw_mutable_iterator = string_map<std::unique_ptr<node>>::iterator;
|
||||
@ -4031,6 +4068,12 @@ TOML_NAMESPACE_START
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (impl::is_node_view<ValueType>)
|
||||
{
|
||||
if (!val)
|
||||
return { end(), false };
|
||||
}
|
||||
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -4045,9 +4088,9 @@ TOML_NAMESPACE_START
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos, std::forward<KeyType>(key), impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
|
||||
@ -4076,6 +4119,12 @@ TOML_NAMESPACE_START
|
||||
"Insertion using wide-character keys is only supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
||||
);
|
||||
|
||||
if constexpr (impl::is_node_view<ValueType>)
|
||||
{
|
||||
if (!val)
|
||||
return { end(), false };
|
||||
}
|
||||
|
||||
if constexpr (impl::is_wide_string<KeyType>)
|
||||
{
|
||||
#if TOML_WINDOWS_COMPAT
|
||||
@ -4090,12 +4139,12 @@ TOML_NAMESPACE_START
|
||||
if (ipos == map.end() || ipos->first != key)
|
||||
{
|
||||
ipos = map.emplace_hint(ipos, std::forward<KeyType>(key), impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ipos).second.reset(impl::make_node(std::forward<ValueType>(val)));
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4134,9 +4183,9 @@ TOML_NAMESPACE_START
|
||||
std::forward<KeyType>(key),
|
||||
new impl::wrap_node<type>{ std::forward<ValueArgs>(args)... }
|
||||
);
|
||||
return { ipos, true };
|
||||
return { iterator{ ipos }, true };
|
||||
}
|
||||
return { ipos, false };
|
||||
return { iterator{ ipos }, false };
|
||||
}
|
||||
}
|
||||
|
||||
@ -4274,8 +4323,8 @@ TOML_NAMESPACE_START
|
||||
using viewed_type = ViewedType;
|
||||
|
||||
private:
|
||||
friend class toml::table;
|
||||
template <typename T> friend class toml::node_view;
|
||||
friend class TOML_NAMESPACE::table;
|
||||
template <typename T> friend class TOML_NAMESPACE::node_view;
|
||||
|
||||
mutable viewed_type* node_ = nullptr;
|
||||
|
||||
@ -4292,6 +4341,16 @@ TOML_NAMESPACE_START
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view() noexcept = default;
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view(const node_view&) noexcept = default;
|
||||
|
||||
TOML_NODISCARD_CTOR
|
||||
node_view& operator= (const node_view&) noexcept = default;
|
||||
|
||||
node_view(node_view&&) noexcept = default;
|
||||
|
||||
node_view& operator= (node_view&&) noexcept = delete;
|
||||
[[nodiscard]] explicit operator bool() const noexcept { return node_ != nullptr; }
|
||||
[[nodiscard]] viewed_type* node() const noexcept { return node_; }
|
||||
|
||||
@ -7654,6 +7713,8 @@ TOML_NAMESPACE_START
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (!pairs[i].value) // empty node_views
|
||||
continue;
|
||||
map.insert_or_assign(
|
||||
std::move(pairs[i].key),
|
||||
std::move(pairs[i].value)
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -77,6 +77,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\tests\unicode.cpp" />
|
||||
<ClCompile Include="..\..\tests\unicode_generated.cpp" />
|
||||
<ClCompile Include="..\..\tests\user_feedback.cpp" />
|
||||
<ClCompile Include="..\..\tests\windows_compat.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user