2020-03-12 15:23:25 +00:00
|
|
|
//# 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.
|
2020-04-10 16:46:00 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-03-12 15:23:25 +00:00
|
|
|
|
2020-01-04 14:21:38 +00:00
|
|
|
#pragma once
|
2020-01-22 21:29:46 +00:00
|
|
|
#include "toml_value.h"
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-04-08 13:33:57 +00:00
|
|
|
TOML_PUSH_WARNINGS
|
2020-07-18 12:10:19 +00:00
|
|
|
TOML_DISABLE_MISC_WARNINGS
|
2020-04-08 13:33:57 +00:00
|
|
|
|
2020-07-25 17:37:30 +00:00
|
|
|
TOML_IMPL_NAMESPACE_START
|
2020-01-07 15:52:50 +00:00
|
|
|
{
|
2020-04-02 21:39:21 +00:00
|
|
|
template <bool IsConst>
|
2020-07-05 15:08:28 +00:00
|
|
|
class TOML_TRIVIAL_ABI array_iterator final
|
2020-01-07 15:52:50 +00:00
|
|
|
{
|
|
|
|
private:
|
2020-05-23 14:35:47 +00:00
|
|
|
friend class ::toml::array;
|
2020-01-07 15:52:50 +00:00
|
|
|
|
2020-05-23 14:35:47 +00:00
|
|
|
using raw_mutable_iterator = std::vector<std::unique_ptr<node>>::iterator;
|
|
|
|
using raw_const_iterator = std::vector<std::unique_ptr<node>>::const_iterator;
|
|
|
|
using raw_iterator = std::conditional_t<IsConst, raw_const_iterator, raw_mutable_iterator>;
|
2020-07-18 12:10:19 +00:00
|
|
|
|
2020-01-07 15:52:50 +00:00
|
|
|
mutable raw_iterator raw_;
|
|
|
|
|
2020-05-23 14:35:47 +00:00
|
|
|
array_iterator(raw_mutable_iterator raw) noexcept
|
2020-01-07 15:52:50 +00:00
|
|
|
: raw_{ raw }
|
|
|
|
{}
|
|
|
|
|
2020-05-23 14:35:47 +00:00
|
|
|
template <bool C = IsConst, typename = std::enable_if_t<C>>
|
|
|
|
TOML_NODISCARD_CTOR
|
|
|
|
array_iterator(raw_const_iterator raw) noexcept
|
|
|
|
: raw_{ raw }
|
2020-01-07 15:52:50 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2020-04-02 21:39:21 +00:00
|
|
|
using value_type = std::conditional_t<IsConst, const node, node>;
|
2020-02-03 09:12:43 +00:00
|
|
|
using reference = value_type&;
|
|
|
|
using pointer = value_type*;
|
|
|
|
using difference_type = ptrdiff_t;
|
2020-01-07 15:52:50 +00:00
|
|
|
|
2020-01-11 21:15:24 +00:00
|
|
|
array_iterator() noexcept = default;
|
2020-05-23 14:35:47 +00:00
|
|
|
array_iterator(const array_iterator&) noexcept = default;
|
|
|
|
array_iterator& operator = (const array_iterator&) noexcept = default;
|
2020-01-11 21:15:24 +00:00
|
|
|
|
2020-01-07 15:52:50 +00:00
|
|
|
array_iterator& operator++() noexcept // ++pre
|
|
|
|
{
|
|
|
|
++raw_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
array_iterator operator++(int) noexcept // post++
|
|
|
|
{
|
|
|
|
array_iterator out{ raw_ };
|
|
|
|
++raw_;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
array_iterator& operator--() noexcept // --pre
|
|
|
|
{
|
|
|
|
--raw_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
array_iterator operator--(int) noexcept // post--
|
|
|
|
{
|
|
|
|
array_iterator out{ raw_ };
|
|
|
|
--raw_;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
2020-02-03 09:12:43 +00:00
|
|
|
reference operator * () const noexcept
|
2020-01-07 15:52:50 +00:00
|
|
|
{
|
|
|
|
return *raw_->get();
|
|
|
|
}
|
|
|
|
|
2020-02-03 09:12:43 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
pointer operator -> () const noexcept
|
|
|
|
{
|
|
|
|
return raw_->get();
|
|
|
|
}
|
|
|
|
|
|
|
|
array_iterator& operator += (ptrdiff_t rhs) noexcept
|
|
|
|
{
|
|
|
|
raw_ += rhs;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
array_iterator& operator -= (ptrdiff_t rhs) noexcept
|
|
|
|
{
|
|
|
|
raw_ -= rhs;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr array_iterator operator + (const array_iterator& lhs, ptrdiff_t rhs) noexcept
|
|
|
|
{
|
|
|
|
return { lhs.raw_ + rhs };
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr array_iterator operator + (ptrdiff_t lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return { rhs.raw_ + lhs };
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr array_iterator operator - (const array_iterator& lhs, ptrdiff_t rhs) noexcept
|
|
|
|
{
|
|
|
|
return { lhs.raw_ - rhs };
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr ptrdiff_t operator - (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ - rhs.raw_;
|
|
|
|
}
|
|
|
|
|
2020-01-07 15:52:50 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator == (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ == rhs.raw_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator != (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ != rhs.raw_;
|
|
|
|
}
|
2020-02-03 09:12:43 +00:00
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator < (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ < rhs.raw_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator <= (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ <= rhs.raw_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator > (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ > rhs.raw_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
friend constexpr bool operator >= (const array_iterator& lhs, const array_iterator& rhs) noexcept
|
|
|
|
{
|
|
|
|
return lhs.raw_ >= rhs.raw_;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]]
|
|
|
|
reference operator[] (ptrdiff_t idx) const noexcept
|
|
|
|
{
|
|
|
|
return *(raw_ + idx)->get();
|
|
|
|
}
|
2020-05-23 14:35:47 +00:00
|
|
|
|
2020-07-18 12:10:19 +00:00
|
|
|
TOML_PUSH_WARNINGS
|
|
|
|
TOML_DISABLE_ALL_WARNINGS
|
|
|
|
|
2020-05-23 14:35:47 +00:00
|
|
|
template <bool C = IsConst, typename = std::enable_if_t<!C>>
|
|
|
|
[[nodiscard]]
|
|
|
|
operator array_iterator<true>() const noexcept
|
|
|
|
{
|
|
|
|
return array_iterator<true>{ raw_ };
|
|
|
|
}
|
2020-07-18 12:10:19 +00:00
|
|
|
|
|
|
|
TOML_POP_WARNINGS
|
2020-01-07 15:52:50 +00:00
|
|
|
};
|
2020-02-03 09:12:43 +00:00
|
|
|
|
|
|
|
template <typename T>
|
2020-04-09 08:13:12 +00:00
|
|
|
[[nodiscard]]
|
2020-07-05 15:08:28 +00:00
|
|
|
TOML_ATTR(returns_nonnull)
|
2020-07-27 10:38:01 +00:00
|
|
|
auto* make_node_specialized(T&& val) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-17 13:33:56 +00:00
|
|
|
using type = unwrap_node<remove_cvref_t<T>>;
|
2020-07-27 10:38:01 +00:00
|
|
|
static_assert(!std::is_same_v<type, node>);
|
|
|
|
|
2020-02-03 09:12:43 +00:00
|
|
|
if constexpr (is_one_of<type, array, table>)
|
|
|
|
{
|
|
|
|
return new type{ std::forward<T>(val) };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-13 18:18:04 +00:00
|
|
|
static_assert(
|
|
|
|
!is_wide_string<T> || TOML_WINDOWS_COMPAT,
|
2020-07-18 12:10:19 +00:00
|
|
|
"Instantiating values from wide-character strings is only "
|
|
|
|
"supported on Windows with TOML_WINDOWS_COMPAT enabled."
|
2020-07-13 18:18:04 +00:00
|
|
|
);
|
2020-02-03 09:12:43 +00:00
|
|
|
static_assert(
|
2020-07-17 13:33:56 +00:00
|
|
|
is_native<type> || is_losslessly_convertible_to_native<type>,
|
2020-02-03 09:12:43 +00:00
|
|
|
"Value initializers must be (or be promotable to) one of the TOML value types"
|
|
|
|
);
|
2020-07-13 18:18:04 +00:00
|
|
|
if constexpr (is_wide_string<T>)
|
2020-07-17 13:33:56 +00:00
|
|
|
{
|
|
|
|
#if TOML_WINDOWS_COMPAT
|
2020-07-13 18:18:04 +00:00
|
|
|
return new value{ narrow(std::forward<T>(val)) };
|
2020-07-17 13:33:56 +00:00
|
|
|
#else
|
|
|
|
static_assert(dependent_false<T>, "Evaluated unreachable branch!");
|
|
|
|
#endif
|
|
|
|
}
|
2020-07-13 18:18:04 +00:00
|
|
|
else
|
|
|
|
return new value{ std::forward<T>(val) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-26 18:01:27 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
[[nodiscard]]
|
2020-07-05 15:08:28 +00:00
|
|
|
TOML_ATTR(returns_nonnull)
|
2020-07-27 10:38:01 +00:00
|
|
|
auto* make_node(T&& val) noexcept
|
|
|
|
{
|
|
|
|
using type = unwrap_node<remove_cvref_t<T>>;
|
|
|
|
if constexpr (std::is_same_v<type, node>)
|
|
|
|
{
|
|
|
|
return std::forward<T>(val).visit([](auto&& concrete) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<toml::node*>(make_node_specialized(std::forward<decltype(concrete)>(concrete)));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return make_node_specialized(std::forward<T>(val));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
[[nodiscard]]
|
|
|
|
TOML_ATTR(returns_nonnull)
|
2020-07-05 15:08:28 +00:00
|
|
|
auto* make_node(inserter<T>&& val) noexcept
|
2020-06-26 18:01:27 +00:00
|
|
|
{
|
|
|
|
return make_node(std::move(val.value));
|
|
|
|
}
|
2020-01-07 15:52:50 +00:00
|
|
|
}
|
2020-07-25 17:37:30 +00:00
|
|
|
TOML_IMPL_NAMESPACE_END
|
2020-01-07 15:52:50 +00:00
|
|
|
|
2020-07-25 17:37:30 +00:00
|
|
|
TOML_NAMESPACE_START
|
2020-01-04 14:21:38 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief A RandomAccessIterator for iterating over elements in a toml::array.
|
2020-04-03 13:33:02 +00:00
|
|
|
using array_iterator = impl::array_iterator<false>;
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
|
2020-04-03 13:33:02 +00:00
|
|
|
using const_array_iterator = impl::array_iterator<true>;
|
|
|
|
|
2020-01-12 15:37:02 +00:00
|
|
|
/// \brief A TOML array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-02-20 21:08:20 +00:00
|
|
|
/// \detail The interface of this type is modeled after std::vector, with some
|
2020-02-03 09:12:43 +00:00
|
|
|
/// additional considerations made for the heterogeneous nature of a
|
2020-07-26 12:03:33 +00:00
|
|
|
/// TOML array.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \godbolt{sjK4da}
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \cpp
|
|
|
|
///
|
|
|
|
/// toml::table tbl = toml::parse(R"(
|
|
|
|
/// arr = [1, 2, 3, 4, 'five']
|
|
|
|
/// )"sv);
|
|
|
|
///
|
|
|
|
/// // get the element as an array
|
|
|
|
/// toml::array& arr = *tbl.get_as<toml::array>("arr");
|
|
|
|
/// std::cout << arr << "\n";
|
|
|
|
///
|
|
|
|
/// // increment each element with visit()
|
|
|
|
/// for (auto&& elem : arr)
|
2020-01-12 15:37:02 +00:00
|
|
|
/// {
|
2020-07-26 12:03:33 +00:00
|
|
|
/// elem.visit([](auto&& el) noexcept
|
|
|
|
/// {
|
|
|
|
/// if constexpr (toml::is_number<decltype(el)>)
|
|
|
|
/// (*el)++;
|
|
|
|
/// else if constexpr (toml::is_string<decltype(el)>)
|
|
|
|
/// el = "six"sv;
|
|
|
|
/// });
|
2020-01-12 15:37:02 +00:00
|
|
|
/// }
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// // add and remove elements
|
2020-02-03 09:12:43 +00:00
|
|
|
/// arr.push_back(7);
|
|
|
|
/// arr.push_back(8.0f);
|
|
|
|
/// arr.push_back("nine"sv);
|
|
|
|
/// arr.erase(arr.cbegin());
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// // emplace elements
|
|
|
|
/// arr.emplace_back<std::string>("ten");
|
|
|
|
/// arr.emplace_back<toml::array>(11, 12.0);
|
|
|
|
/// std::cout << arr << "\n";
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
2020-02-18 21:29:59 +00:00
|
|
|
///
|
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, 3, 4, 'five' ]
|
|
|
|
/// [ 2, 3, 4, 5, 'six' ]
|
|
|
|
/// [ 3, 4, 5, 'six', 7, 8.0, 'nine' ]
|
|
|
|
/// [ 3, 4, 5, 'six', 7, 8.0, 'nine', 'ten', [ 11, 12.0 ] ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
2020-03-01 14:56:40 +00:00
|
|
|
class TOML_API array final
|
2020-01-04 14:21:38 +00:00
|
|
|
: public node
|
|
|
|
{
|
|
|
|
private:
|
2020-03-28 16:56:59 +00:00
|
|
|
friend class TOML_PARSER_TYPENAME;
|
2020-07-26 12:03:33 +00:00
|
|
|
std::vector<std::unique_ptr<node>> elements;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-03-01 14:56:40 +00:00
|
|
|
void preinsertion_resize(size_t idx, size_t count) noexcept;
|
2020-02-03 09:12:43 +00:00
|
|
|
|
2020-01-04 14:21:38 +00:00
|
|
|
public:
|
|
|
|
|
2020-01-12 15:37:02 +00:00
|
|
|
using value_type = node;
|
|
|
|
using size_type = size_t;
|
|
|
|
using difference_type = ptrdiff_t;
|
|
|
|
using reference = node&;
|
|
|
|
using const_reference = const node&;
|
2020-02-03 09:12:43 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief A RandomAccessIterator for iterating over elements in a toml::array.
|
2020-04-03 13:33:02 +00:00
|
|
|
using iterator = array_iterator;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
|
2020-04-03 13:33:02 +00:00
|
|
|
using const_iterator = const_array_iterator;
|
2020-01-07 15:52:50 +00:00
|
|
|
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \brief Default constructor.
|
2020-01-04 14:21:38 +00:00
|
|
|
TOML_NODISCARD_CTOR
|
2020-03-01 14:56:40 +00:00
|
|
|
array() noexcept;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-07-27 10:38:01 +00:00
|
|
|
/// \brief Copy constructor.
|
|
|
|
TOML_NODISCARD_CTOR
|
|
|
|
array(const array&) noexcept;
|
|
|
|
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \brief Move constructor.
|
2020-01-04 14:21:38 +00:00
|
|
|
TOML_NODISCARD_CTOR
|
2020-03-01 14:56:40 +00:00
|
|
|
array(array&& other) noexcept;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-07-27 10:38:01 +00:00
|
|
|
/// \brief Copy-assignment operator.
|
|
|
|
array& operator= (const array&) noexcept;
|
|
|
|
|
|
|
|
/// \brief Move-assignment operator.
|
|
|
|
array& operator= (array&& rhs) noexcept;
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Constructs an array with one or more initial elements.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2.0, "three"sv, toml::array{ 4, 5 } };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
2020-02-18 21:29:59 +00:00
|
|
|
///
|
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2.0, 'three', [ 4, 5 ] ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
2020-06-26 18:01:27 +00:00
|
|
|
///
|
|
|
|
/// \remark \parblock If you need to construct an array with one child array element, the array's move constructor
|
|
|
|
/// will take precedence and perform a move-construction instead. You can use toml::inserter to
|
|
|
|
/// suppress this behaviour: \cpp
|
|
|
|
/// // desired result: [ [ 42 ] ]
|
|
|
|
/// auto bad = toml::array{ toml::array{ 42 } }
|
|
|
|
/// auto good = toml::array{ toml::inserter{ toml::array{ 42 } } }
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << "bad: " << bad << "\n";
|
|
|
|
/// std::cout << "good:" << good << "\n";
|
2020-06-26 18:01:27 +00:00
|
|
|
/// \ecpp
|
|
|
|
///
|
|
|
|
/// \out
|
|
|
|
/// bad: [ 42 ]
|
|
|
|
/// good: [ [ 42 ] ]
|
|
|
|
/// \eout
|
|
|
|
///
|
|
|
|
/// \endparblock
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
|
|
|
/// \tparam ElemTypes One of the TOML node or value types (or a type promotable to one).
|
|
|
|
/// \param val The node or value used to initialize element 0.
|
|
|
|
/// \param vals The nodes or values used to initialize elements 1...N.
|
2020-07-27 10:38:01 +00:00
|
|
|
template <typename ElemType, typename... ElemTypes, typename = std::enable_if_t<
|
|
|
|
(sizeof...(ElemTypes) > 0_sz)
|
|
|
|
|| !std::is_same_v<impl::remove_cvref_t<ElemType>, array>
|
|
|
|
>>
|
2020-02-03 09:12:43 +00:00
|
|
|
TOML_NODISCARD_CTOR
|
2020-07-26 12:03:33 +00:00
|
|
|
explicit array(ElemType&& val, ElemTypes&&... vals)
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
elements.reserve(sizeof...(ElemTypes) + 1_sz);
|
|
|
|
elements.emplace_back(impl::make_node(std::forward<ElemType>(val)));
|
|
|
|
if constexpr (sizeof...(ElemTypes) > 0)
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
|
|
|
(
|
2020-07-26 12:03:33 +00:00
|
|
|
elements.emplace_back(impl::make_node(std::forward<ElemTypes>(vals))),
|
2020-02-03 09:12:43 +00:00
|
|
|
...
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 21:08:20 +00:00
|
|
|
|
2020-02-16 13:11:57 +00:00
|
|
|
/// \brief Always returns node_type::array for array nodes.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] node_type type() const noexcept override;
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \brief Always returns `false` for array nodes.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] bool is_table() const noexcept override;
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \brief Always returns `true` for array nodes.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] bool is_array() const noexcept override;
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \brief Always returns `false` for array nodes.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] bool is_value() const noexcept override;
|
|
|
|
[[nodiscard]] array* as_array() noexcept override;
|
|
|
|
[[nodiscard]] const array* as_array() const noexcept override;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Checks if the array contains elements of only one type.
|
2020-07-18 12:10:19 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
|
|
|
/// auto arr = toml::array{ 1, 2, 3 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << "homogenous: "sv << arr.is_homogeneous(toml::node_type::none) << "\n";
|
|
|
|
/// std::cout << "all floats: "sv << arr.is_homogeneous(toml::node_type::floating_point) << "\n";
|
|
|
|
/// std::cout << "all arrays: "sv << arr.is_homogeneous(toml::node_type::array) << "\n";
|
|
|
|
/// std::cout << "all ints: "sv << arr.is_homogeneous(toml::node_type::integer) << "\n";
|
2020-07-18 12:10:19 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
|
|
|
/// \out
|
|
|
|
/// homogeneous: true
|
2020-07-26 12:03:33 +00:00
|
|
|
/// all floats: false
|
2020-07-18 12:10:19 +00:00
|
|
|
/// all arrays: false
|
2020-07-26 12:03:33 +00:00
|
|
|
/// all ints: true
|
2020-07-18 12:10:19 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
|
|
|
/// \param type A TOML node type. <br>
|
2020-07-26 12:03:33 +00:00
|
|
|
/// <strong><em>toml::node_type::none: </em></strong> "is every node the same type?" <br>
|
|
|
|
/// <strong><em>Anything else:</em></strong> "is every node one of these?"
|
2020-07-18 12:10:19 +00:00
|
|
|
///
|
|
|
|
/// \returns True if the array was homogeneous.
|
|
|
|
///
|
|
|
|
/// \remarks Always returns `false` for empty arrays.
|
|
|
|
[[nodiscard]] bool is_homogeneous(node_type type) const noexcept;
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Checks if the array contains elements of only one type.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2, 3 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << "homogenous: "sv << arr.is_homogeneous() << "\n";
|
|
|
|
/// std::cout << "all doubles: "sv << arr.is_homogeneous<double>() << "\n";
|
|
|
|
/// std::cout << "all arrays: "sv << arr.is_homogeneous<toml::array>() << "\n";
|
|
|
|
/// std::cout << "all integers: "sv << arr.is_homogeneous<int64_t>() << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// homogeneous: true
|
|
|
|
/// all doubles: false
|
|
|
|
/// all arrays: false
|
2020-02-18 21:29:59 +00:00
|
|
|
/// all integers: true
|
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType A TOML node or value type. <br>
|
|
|
|
/// <strong><em>Left as `void`:</em></strong> "is every node the same type?" <br>
|
|
|
|
/// <strong><em>Explicitly specified:</em></strong> "is every node a T?"
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
|
|
|
/// \returns True if the array was homogeneous.
|
|
|
|
///
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \remarks Always returns `false` for empty arrays.
|
2020-07-26 12:03:33 +00:00
|
|
|
template <typename ElemType = void>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
bool is_homogeneous() const noexcept
|
2020-01-04 14:21:38 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
using type = impl::unwrap_node<ElemType>;
|
2020-07-18 12:10:19 +00:00
|
|
|
static_assert(
|
|
|
|
std::is_void_v<type>
|
|
|
|
|| ((impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>),
|
2020-07-20 14:13:52 +00:00
|
|
|
"The template type argument of array::is_homogeneous() must be void or one of:"
|
|
|
|
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
2020-07-18 12:10:19 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if constexpr (std::is_void_v<type>)
|
|
|
|
return is_homogeneous(node_type::none);
|
2020-01-07 15:52:50 +00:00
|
|
|
else
|
2020-07-18 12:10:19 +00:00
|
|
|
return is_homogeneous(impl::node_type_of<type>);
|
2020-01-04 14:21:38 +00:00
|
|
|
}
|
|
|
|
|
2020-01-12 15:37:02 +00:00
|
|
|
/// \brief Returns true if this array contains only tables.
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]] bool is_array_of_tables() const noexcept override;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets a reference to the element at a specific index.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] node& operator[] (size_t index) noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets a reference to the element at a specific index.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const node& operator[] (size_t index) const noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns a reference to the first element in the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] node& front() noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns a reference to the first element in the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const node& front() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns a reference to the last element in the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] node& back() noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns a reference to the last element in the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const node& back() const noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to the first element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] iterator begin() noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to the first element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const_iterator begin() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to the first element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const_iterator cbegin() const noexcept;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to one-past-the-last element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] iterator end() noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to one-past-the-last element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const_iterator end() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns an iterator to one-past-the-last element.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const_iterator cend() const noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
|
|
|
/// \brief Returns true if the array is empty.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] bool empty() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns the number of elements in the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] size_t size() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Reserves internal storage capacity up to a pre-determined number of elements.
|
2020-03-28 16:56:59 +00:00
|
|
|
void reserve(size_t new_capacity);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Removes all elements from the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
void clear() noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns the maximum number of elements that can be stored in an array on the current platform.
|
2020-05-23 14:35:47 +00:00
|
|
|
[[nodiscard]] size_t max_size() const noexcept;
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Returns the current max number of elements that may be held in the array's internal storage.
|
2020-05-23 14:35:47 +00:00
|
|
|
[[nodiscard]] size_t capacity() const noexcept;
|
|
|
|
/// \brief Requests the removal of any unused internal storage capacity.
|
|
|
|
void shrink_to_fit();
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Inserts a new element at a specific position in the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 3 };
|
2020-02-03 09:12:43 +00:00
|
|
|
/// arr.insert(arr.cbegin() + 1, "two");
|
|
|
|
/// arr.insert(arr.cend(), toml::array{ 4, 5 });
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 'two', 3, [ 4, 5 ] ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
|
|
|
/// \param pos The insertion position.
|
|
|
|
/// \param val The node or value being inserted.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An iterator to the newly-inserted element.
|
|
|
|
template <typename ElemType>
|
|
|
|
iterator insert(const_iterator pos, ElemType&& val) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
return { elements.emplace(pos.raw_, impl::make_node(std::forward<ElemType>(val))) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Repeatedly inserts a new element starting at a specific position in the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
|
|
|
/// auto arr = toml::array{
|
|
|
|
/// "with an evil twinkle in its eye the goose said",
|
|
|
|
/// "and immediately we knew peace was never an option."
|
|
|
|
/// };
|
|
|
|
/// arr.insert(arr.cbegin() + 1, 3, "honk");
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
|
|
|
/// [
|
2020-07-26 12:03:33 +00:00
|
|
|
/// 'with an evil twinkle in its eye the goose said',
|
|
|
|
/// 'honk',
|
|
|
|
/// 'honk',
|
|
|
|
/// 'honk',
|
|
|
|
/// 'and immediately we knew peace was never an option.'
|
2020-02-18 21:29:59 +00:00
|
|
|
/// ]
|
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (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.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if count was 0).
|
|
|
|
template <typename ElemType>
|
|
|
|
iterator insert(const_iterator pos, size_t count, ElemType&& val) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
|
|
|
switch (count)
|
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
|
|
|
case 1: return insert(pos, std::forward<ElemType>(val));
|
2020-02-03 09:12:43 +00:00
|
|
|
default:
|
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
2020-02-03 09:12:43 +00:00
|
|
|
preinsertion_resize(start_idx, count);
|
|
|
|
size_t i = start_idx;
|
|
|
|
for (size_t e = start_idx + count - 1_sz; i < e; i++)
|
2020-07-26 12:03:33 +00:00
|
|
|
elements[i].reset(impl::make_node(val));
|
2020-02-03 09:12:43 +00:00
|
|
|
|
|
|
|
//# potentially move the initial value into the last element
|
2020-07-26 12:03:33 +00:00
|
|
|
elements[i].reset(impl::make_node(std::forward<ElemType>(val)));
|
|
|
|
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Inserts a range of elements into the array at a specific position.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-04-02 21:39:21 +00:00
|
|
|
/// \tparam Iter An iterator type. Must satisfy ForwardIterator.
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \param pos The insertion position.
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \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.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if `first` >= `last`).
|
2020-04-02 21:39:21 +00:00
|
|
|
template <typename Iter>
|
|
|
|
iterator insert(const_iterator pos, Iter first, Iter last) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
|
|
|
const auto count = std::distance(first, last);
|
2020-07-26 12:03:33 +00:00
|
|
|
if (count <= 0)
|
|
|
|
return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
|
|
|
else if (count == 1)
|
|
|
|
return insert(pos, *first);
|
|
|
|
else
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
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));
|
|
|
|
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Inserts a range of elements into the array at a specific position.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
|
|
|
/// \param pos The insertion position.
|
|
|
|
/// \param ilist An initializer list containing the values to be inserted.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An iterator to the first newly-inserted element (or a copy of `pos` if `ilist` was empty).
|
|
|
|
template <typename ElemType>
|
|
|
|
iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
|
|
|
switch (ilist.size())
|
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
case 0: return { elements.begin() + (pos.raw_ - elements.cbegin()) };
|
2020-02-03 09:12:43 +00:00
|
|
|
case 1: return insert(pos, *ilist.begin());
|
|
|
|
default:
|
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
const auto start_idx = static_cast<size_t>(pos.raw_ - elements.cbegin());
|
2020-02-03 09:12:43 +00:00
|
|
|
preinsertion_resize(start_idx, ilist.size());
|
|
|
|
size_t i = start_idx;
|
|
|
|
for (auto& val : ilist)
|
2020-07-26 12:03:33 +00:00
|
|
|
elements[i++].reset(impl::make_node(val));
|
|
|
|
return { elements.begin() + static_cast<ptrdiff_t>(start_idx) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Emplaces a new element at a specific position in the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2 };
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// //add a string using std::string's substring constructor
|
|
|
|
/// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 'drill', 2 ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types.
|
|
|
|
/// \tparam Args Value constructor argument types.
|
|
|
|
/// \param pos The insertion position.
|
|
|
|
/// \param args Arguments to forward to the value's constructor.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An iterator to the inserted element.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \remarks There is no difference between insert() and emplace()
|
2020-02-16 13:11:57 +00:00
|
|
|
/// for trivial value types (floats, ints, bools).
|
2020-07-26 12:03:33 +00:00
|
|
|
template <typename ElemType, typename... Args>
|
|
|
|
iterator emplace(const_iterator pos, Args&&... args) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
using type = impl::unwrap_node<ElemType>;
|
2020-02-03 09:12:43 +00:00
|
|
|
static_assert(
|
2020-07-18 12:10:19 +00:00
|
|
|
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
2020-07-20 14:13:52 +00:00
|
|
|
"Emplacement type parameter must be one of:"
|
|
|
|
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
2020-02-03 09:12:43 +00:00
|
|
|
);
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
return { elements.emplace(pos.raw_, new impl::wrap_node<type>{ std::forward<Args>(args)...} ) };
|
2020-02-03 09:12:43 +00:00
|
|
|
}
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Removes the specified element from the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2, 3 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// arr.erase(arr.cbegin() + 1);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, 3 ]
|
|
|
|
/// [ 1, 3 ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \param pos Iterator to the element being erased.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns Iterator to the first element immediately following the removed element.
|
2020-03-01 14:56:40 +00:00
|
|
|
iterator erase(const_iterator pos) noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Removes the elements in the range [first, last) from the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, "bad", "karma" 2 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 'bad', 'karma', 3 ]
|
|
|
|
/// [ 1, 3 ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \param first Iterator to the first element being erased.
|
|
|
|
/// \param last Iterator to the one-past-the-last element being erased.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns Iterator to the first element immediately following the last removed element.
|
2020-03-01 14:56:40 +00:00
|
|
|
iterator erase(const_iterator first, const_iterator last) noexcept;
|
2020-01-04 14:21:38 +00:00
|
|
|
|
2020-05-23 14:35:47 +00:00
|
|
|
/// \brief Resizes the array.
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \detail \godbolt{W5zqx3}
|
|
|
|
///
|
|
|
|
/// \cpp
|
2020-05-23 14:35:47 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2, 3 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// arr.resize(6, 42);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// arr.resize(2, 0);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, 3 ]
|
|
|
|
/// [ 1, 2, 3, 42, 42, 42 ]
|
|
|
|
/// [ 1, 2 ]
|
2020-05-23 14:35:47 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \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
|
2020-05-23 14:35:47 +00:00
|
|
|
{
|
|
|
|
if (!new_size)
|
2020-07-26 12:03:33 +00:00
|
|
|
elements.clear();
|
|
|
|
else if (new_size < elements.size())
|
|
|
|
elements.resize(new_size);
|
|
|
|
else if (new_size > elements.size())
|
|
|
|
insert(cend(), new_size - elements.size(), std::forward<ElemType>(default_init_val));
|
2020-05-23 14:35:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Shrinks the array to the given size.
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \detail \godbolt{rxEzK5}
|
|
|
|
///
|
|
|
|
/// \cpp
|
2020-05-23 14:35:47 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2, 3 };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// arr.truncate(5); // no-op
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// arr.truncate(1);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-05-23 14:35:47 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, 3 ]
|
|
|
|
/// [ 1, 2, 3 ]
|
|
|
|
/// [ 1]
|
2020-05-23 14:35:47 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
|
|
|
/// \remarks Does nothing if the requested size is larger than or equal to the current size.
|
|
|
|
void truncate(size_t new_size);
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Appends a new element to the end of the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2 };
|
2020-02-03 09:12:43 +00:00
|
|
|
/// arr.push_back(3);
|
|
|
|
/// arr.push_back(4.0);
|
2020-02-18 21:29:59 +00:00
|
|
|
/// arr.push_back(toml::array{ 5, "six"sv });
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, 3, 4.0, [ 5, 'six' ] ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types (or a type promotable to one).
|
|
|
|
/// \param val The node or value being added.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A reference to the newly-constructed element.
|
|
|
|
template <typename ElemType>
|
|
|
|
decltype(auto) push_back(ElemType&& val) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
auto nde = impl::make_node(std::forward<ElemType>(val));
|
|
|
|
elements.emplace_back(nde);
|
2020-02-03 09:12:43 +00:00
|
|
|
return *nde;
|
|
|
|
}
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Emplaces a new element at the end of the array.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 1, 2 };
|
2020-02-18 21:29:59 +00:00
|
|
|
/// arr.emplace_back<toml::array>(3, "four"sv);
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, [ 3, 'four' ] ]
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType One of the TOML node or value types.
|
|
|
|
/// \tparam Args Value constructor argument types.
|
|
|
|
/// \param args Arguments to forward to the value's constructor.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A reference to the newly-constructed element.
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \remarks There is no difference between push_back() and emplace_back()
|
2020-02-03 09:12:43 +00:00
|
|
|
/// For trivial value types (floats, ints, bools).
|
2020-07-26 12:03:33 +00:00
|
|
|
template <typename ElemType, typename... Args>
|
|
|
|
decltype(auto) emplace_back(Args&&... args) noexcept
|
2020-02-03 09:12:43 +00:00
|
|
|
{
|
2020-07-26 12:03:33 +00:00
|
|
|
using type = impl::unwrap_node<ElemType>;
|
2020-02-03 09:12:43 +00:00
|
|
|
static_assert(
|
2020-07-18 12:10:19 +00:00
|
|
|
(impl::is_native<type> || impl::is_one_of<type, table, array>) && !impl::is_cvref<type>,
|
2020-07-20 14:13:52 +00:00
|
|
|
"Emplacement type parameter must be one of:"
|
|
|
|
TOML_SA_UNWRAPPED_NODE_TYPE_LIST
|
2020-02-03 09:12:43 +00:00
|
|
|
);
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
auto nde = new impl::wrap_node<type>{ std::forward<Args>(args)... };
|
|
|
|
elements.emplace_back(nde);
|
2020-02-03 09:12:43 +00:00
|
|
|
return *nde;
|
|
|
|
}
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Removes the last element from the array.
|
2020-03-01 14:56:40 +00:00
|
|
|
void pop_back() noexcept;
|
2020-01-12 15:37:02 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets the element at a specific index.
|
2020-02-16 13:11:57 +00:00
|
|
|
///
|
|
|
|
/// \detail \cpp
|
|
|
|
/// auto arr = toml::array{ 99, "bottles of beer on the wall" };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << "element [0] exists: "sv << !!arr.get(0) << "\n";
|
|
|
|
/// std::cout << "element [1] exists: "sv << !!arr.get(1) << "\n";
|
|
|
|
/// std::cout << "element [2] exists: "sv << !!arr.get(2) << "\n";
|
|
|
|
/// if (toml::node* val = arr.get(0))
|
|
|
|
/// std::cout << "element [0] is an "sv << val->type() << "\n";
|
2020-02-16 13:11:57 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// element [0] exists: true
|
|
|
|
/// element [1] exists: true
|
|
|
|
/// element [2] exists: false
|
|
|
|
/// element [0] is an integer
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \param index The element's index.
|
2020-02-16 13:11:57 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] node* get(size_t index) noexcept;
|
2020-02-16 13:11:57 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets the element at a specific index (const overload).
|
2020-02-16 13:11:57 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \param index The element's index.
|
2020-02-16 13:11:57 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A pointer to the element at the specified index if one existed, or nullptr.
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] const node* get(size_t index) const noexcept;
|
2020-02-16 13:11:57 +00:00
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets the element at a specific index if it is a particular type.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-02-03 09:12:43 +00:00
|
|
|
/// \detail \cpp
|
2020-02-16 13:11:57 +00:00
|
|
|
/// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// if (toml::value<int64_t>* val = arr.get_as<int64_t>(0))
|
|
|
|
/// std::cout << "element [0] is an integer with value "sv << *val << "\n";
|
2020-02-03 09:12:43 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// element [0] is an integer with value 42
|
2020-02-18 21:29:59 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType The element's type.
|
|
|
|
/// \param index The element's index.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
|
|
|
|
template <typename ElemType>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
2020-07-26 12:03:33 +00:00
|
|
|
impl::wrap_node<ElemType>* get_as(size_t index) noexcept
|
2020-01-04 14:21:38 +00:00
|
|
|
{
|
2020-02-16 13:11:57 +00:00
|
|
|
if (auto val = get(index))
|
2020-07-26 12:03:33 +00:00
|
|
|
return val->as<ElemType>();
|
2020-02-16 13:11:57 +00:00
|
|
|
return nullptr;
|
2020-01-04 14:21:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \brief Gets the element at a specific index if it is a particular type (const overload).
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \tparam ElemType The element's type.
|
|
|
|
/// \param index The element's index.
|
2020-01-12 15:37:02 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A pointer to the selected element if it existed and was of the specified type, or nullptr.
|
|
|
|
template <typename ElemType>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
2020-07-26 12:03:33 +00:00
|
|
|
const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
|
2020-01-04 14:21:38 +00:00
|
|
|
{
|
2020-02-16 13:11:57 +00:00
|
|
|
if (auto val = get(index))
|
2020-07-26 12:03:33 +00:00
|
|
|
return val->as<ElemType>();
|
2020-02-16 13:11:57 +00:00
|
|
|
return nullptr;
|
2020-01-04 14:21:38 +00:00
|
|
|
}
|
2020-01-07 15:52:50 +00:00
|
|
|
|
2020-01-22 21:29:46 +00:00
|
|
|
/// \brief Equality operator.
|
|
|
|
///
|
|
|
|
/// \param lhs The LHS array.
|
|
|
|
/// \param rhs The RHS array.
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns True if the arrays contained the same elements.
|
2020-03-01 14:56:40 +00:00
|
|
|
friend bool operator == (const array& lhs, const array& rhs) noexcept;
|
2020-01-22 21:29:46 +00:00
|
|
|
|
|
|
|
/// \brief Inequality operator.
|
|
|
|
///
|
|
|
|
/// \param lhs The LHS array.
|
|
|
|
/// \param rhs The RHS array.
|
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns True if the arrays did not contain the same elements.
|
2020-03-01 14:56:40 +00:00
|
|
|
friend bool operator != (const array& lhs, const array& rhs) noexcept;
|
2020-01-22 21:29:46 +00:00
|
|
|
|
2020-02-03 09:12:43 +00:00
|
|
|
private:
|
|
|
|
|
2020-02-20 21:08:20 +00:00
|
|
|
template <typename T>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
static bool container_equality(const array& lhs, const T& rhs) noexcept
|
2020-02-20 21:08:20 +00:00
|
|
|
{
|
2020-07-17 13:33:56 +00:00
|
|
|
using element_type = std::remove_const_t<typename T::value_type>;
|
2020-02-20 21:08:20 +00:00
|
|
|
static_assert(
|
2020-07-17 13:33:56 +00:00
|
|
|
impl::is_native<element_type> || impl::is_losslessly_convertible_to_native<element_type>,
|
2020-02-20 21:08:20 +00:00
|
|
|
"Container element type must be (or be promotable to) one of the TOML value types"
|
|
|
|
);
|
|
|
|
|
|
|
|
if (lhs.size() != rhs.size())
|
|
|
|
return false;
|
|
|
|
if (rhs.size() == 0_sz)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
size_t i{};
|
|
|
|
for (auto& list_elem : rhs)
|
|
|
|
{
|
2020-07-17 13:33:56 +00:00
|
|
|
const auto elem = lhs.get_as<impl::native_type_of<element_type>>(i++);
|
2020-02-20 21:08:20 +00:00
|
|
|
if (!elem || *elem != list_elem)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-03-01 14:56:40 +00:00
|
|
|
[[nodiscard]] size_t total_leaf_count() const noexcept;
|
2020-02-03 09:12:43 +00:00
|
|
|
|
2020-03-01 14:56:40 +00:00
|
|
|
void flatten_child(array&& child, size_t& dest_index) noexcept;
|
2020-02-03 09:12:43 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
2020-02-20 21:08:20 +00:00
|
|
|
/// \brief Initializer list equality operator.
|
|
|
|
template <typename T>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
friend bool operator == (const array& lhs, const std::initializer_list<T>& rhs) noexcept
|
2020-02-20 21:08:20 +00:00
|
|
|
{
|
|
|
|
return container_equality(lhs, rhs);
|
|
|
|
}
|
2020-04-10 16:46:00 +00:00
|
|
|
TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::initializer_list<T>&, template <typename T>)
|
2020-02-20 21:08:20 +00:00
|
|
|
|
|
|
|
/// \brief Vector equality operator.
|
|
|
|
template <typename T>
|
2020-07-18 12:10:19 +00:00
|
|
|
[[nodiscard]]
|
|
|
|
friend bool operator == (const array& lhs, const std::vector<T>& rhs) noexcept
|
2020-02-20 21:08:20 +00:00
|
|
|
{
|
|
|
|
return container_equality(lhs, rhs);
|
|
|
|
}
|
2020-04-10 16:46:00 +00:00
|
|
|
TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::vector<T>&, template <typename T>)
|
2020-02-20 21:08:20 +00:00
|
|
|
|
2020-03-02 10:14:54 +00:00
|
|
|
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself.
|
|
|
|
///
|
|
|
|
/// \detail \cpp
|
|
|
|
///
|
|
|
|
/// auto arr = toml::array{ 1, 2, toml::array{ 3, 4, toml::array{ 5 } }, 6, toml::array{} };
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-03-02 10:14:54 +00:00
|
|
|
///
|
|
|
|
/// arr.flatten();
|
2020-07-26 12:03:33 +00:00
|
|
|
/// std::cout << arr << "\n";
|
2020-03-02 10:14:54 +00:00
|
|
|
///
|
|
|
|
/// \ecpp
|
|
|
|
///
|
|
|
|
/// \out
|
2020-07-26 12:03:33 +00:00
|
|
|
/// [ 1, 2, [ 3, 4, [ 5 ] ], 6, [] ]
|
|
|
|
/// [ 1, 2, 3, 4, 5, 6 ]
|
2020-03-02 10:14:54 +00:00
|
|
|
/// \eout
|
|
|
|
///
|
|
|
|
/// \remarks Arrays inside child tables are not flattened.
|
2020-06-28 12:26:18 +00:00
|
|
|
///
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns A reference to the array.
|
2020-06-28 12:26:18 +00:00
|
|
|
array& flatten() &;
|
|
|
|
|
|
|
|
/// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
|
2020-07-26 12:03:33 +00:00
|
|
|
/// \returns An rvalue reference to the array.
|
2020-07-18 12:10:19 +00:00
|
|
|
array&& flatten() &&
|
2020-06-28 12:26:18 +00:00
|
|
|
{
|
|
|
|
return static_cast<toml::array&&>(static_cast<toml::array&>(*this).flatten());
|
|
|
|
}
|
2020-02-03 09:12:43 +00:00
|
|
|
|
2020-07-13 18:18:04 +00:00
|
|
|
/// \brief Prints the array out to a stream as formatted TOML.
|
2020-04-02 21:39:21 +00:00
|
|
|
template <typename Char>
|
|
|
|
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>&, const array&);
|
2020-01-04 14:21:38 +00:00
|
|
|
};
|
|
|
|
}
|
2020-07-25 17:37:30 +00:00
|
|
|
TOML_NAMESPACE_END
|
2020-04-08 13:33:57 +00:00
|
|
|
|
2020-07-18 12:10:19 +00:00
|
|
|
TOML_POP_WARNINGS //TOML_DISABLE_MISC_WARNINGS
|