summaryrefslogtreecommitdiffhomepage
path: root/vendor/toml++
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/toml++')
-rw-r--r--vendor/toml++/impl/array.hpp3261
-rw-r--r--vendor/toml++/impl/at_path.hpp152
-rw-r--r--vendor/toml++/impl/date_time.hpp868
-rw-r--r--vendor/toml++/impl/formatter.hpp323
-rw-r--r--vendor/toml++/impl/forward_declarations.hpp1786
-rw-r--r--vendor/toml++/impl/header_end.hpp4
-rw-r--r--vendor/toml++/impl/header_start.hpp4
-rw-r--r--vendor/toml++/impl/json_formatter.hpp243
-rw-r--r--vendor/toml++/impl/key.hpp563
-rw-r--r--vendor/toml++/impl/make_node.hpp305
-rw-r--r--vendor/toml++/impl/node.hpp2096
-rw-r--r--vendor/toml++/impl/node_view.hpp1482
-rw-r--r--vendor/toml++/impl/parse_error.hpp195
-rw-r--r--vendor/toml++/impl/parse_result.hpp878
-rw-r--r--vendor/toml++/impl/parser.hpp696
-rw-r--r--vendor/toml++/impl/path.hpp1399
-rw-r--r--vendor/toml++/impl/preprocessor.hpp758
-rw-r--r--vendor/toml++/impl/print_to_stream.hpp176
-rw-r--r--vendor/toml++/impl/simd.hpp14
-rw-r--r--vendor/toml++/impl/source_region.hpp407
-rw-r--r--vendor/toml++/impl/std_except.hpp8
-rw-r--r--vendor/toml++/impl/std_initializer_list.hpp8
-rw-r--r--vendor/toml++/impl/std_map.hpp10
-rw-r--r--vendor/toml++/impl/std_new.hpp11
-rw-r--r--vendor/toml++/impl/std_optional.hpp27
-rw-r--r--vendor/toml++/impl/std_string.hpp46
-rw-r--r--vendor/toml++/impl/std_utility.hpp8
-rw-r--r--vendor/toml++/impl/std_variant.hpp8
-rw-r--r--vendor/toml++/impl/std_vector.hpp10
-rw-r--r--vendor/toml++/impl/table.hpp3591
-rw-r--r--vendor/toml++/impl/toml_formatter.hpp266
-rw-r--r--vendor/toml++/impl/unicode.hpp341
-rw-r--r--vendor/toml++/impl/unicode_autogenerated.hpp317
-rw-r--r--vendor/toml++/impl/value.hpp1964
-rw-r--r--vendor/toml++/impl/version.hpp8
-rw-r--r--vendor/toml++/impl/yaml_formatter.hpp237
-rw-r--r--vendor/toml++/toml.hpp70
37 files changed, 10545 insertions, 11995 deletions
diff --git a/vendor/toml++/impl/array.hpp b/vendor/toml++/impl/array.hpp
index ad79379..c276637 100644
--- a/vendor/toml++/impl/array.hpp
+++ b/vendor/toml++/impl/array.hpp
@@ -1,15 +1,15 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
+#include "header_start.hpp"
+#include "make_node.hpp"
+#include "std_initializer_list.hpp"
#include "std_utility.hpp"
#include "std_vector.hpp"
-#include "std_initializer_list.hpp"
#include "value.hpp"
-#include "make_node.hpp"
-#include "header_start.hpp"
#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
#if TOML_GCC && TOML_GCC <= 7
@@ -19,1771 +19,1530 @@
#endif
#endif
-#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN && !defined(TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED)
-#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE \
- "If you're seeing this error it's because you're using one of toml++'s for_each() functions on a compiler with " \
- "known bugs in that area (e.g. GCC 7). On these compilers returning a bool (or bool-convertible) value from the " \
- "for_each() callable causes spurious compilation failures, while returning nothing (void) works fine. " \
- "If you believe this message is incorrect for your compiler, you can try your luck by #defining " \
- "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN as 0 and recompiling - if it works, great! Let me know at " \
- "https://github.com/marzer/tomlplusplus/issues. Alternatively, if you don't have any need for early-exiting from " \
- "for_each(), you can suppress this error by #defining TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED " \
- "and moving on with your life."
+#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN && \
+ !defined(TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED)
+#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE \
+ "If you're seeing this error it's because you're using one of toml++'s for_each() functions on " \
+ "a compiler with " \
+ "known bugs in that area (e.g. GCC 7). On these compilers returning a bool (or " \
+ "bool-convertible) value from the " \
+ "for_each() callable causes spurious compilation failures, while returning nothing (void) " \
+ "works fine. " \
+ "If you believe this message is incorrect for your compiler, you can try your luck by " \
+ "#defining " \
+ "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN as 0 and recompiling - if it works, great! Let me know " \
+ "at " \
+ "https://github.com/marzer/tomlplusplus/issues. Alternatively, if you don't have any need for " \
+ "early-exiting from " \
+ "for_each(), you can suppress this error by #defining " \
+ "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED " \
+ "and moving on with your life."
#endif
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <bool IsConst>
- class TOML_TRIVIAL_ABI array_iterator
- {
- private:
- template <bool>
- friend class array_iterator;
-
- using mutable_vector_iterator = std::vector<node_ptr>::iterator;
- using const_vector_iterator = std::vector<node_ptr>::const_iterator;
- using vector_iterator = std::conditional_t<IsConst, const_vector_iterator, mutable_vector_iterator>;
-
- mutable vector_iterator iter_;
-
- public:
- using value_type = std::conditional_t<IsConst, const node, node>;
- using reference = value_type&;
- using pointer = value_type*;
- using difference_type = ptrdiff_t;
- using iterator_category = typename std::iterator_traits<vector_iterator>::iterator_category;
-
- TOML_NODISCARD_CTOR
- array_iterator() noexcept = default;
-
- TOML_NODISCARD_CTOR
- explicit array_iterator(mutable_vector_iterator iter) noexcept //
- : iter_{ iter }
- {}
-
- TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
- TOML_NODISCARD_CTOR
- explicit array_iterator(const_vector_iterator iter) noexcept //
- : iter_{ iter }
- {}
-
- TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
- TOML_NODISCARD_CTOR
- array_iterator(const array_iterator<false>& other) noexcept //
- : iter_{ other.iter_ }
- {}
-
- TOML_NODISCARD_CTOR
- array_iterator(const array_iterator&) noexcept = default;
-
- array_iterator& operator=(const array_iterator&) noexcept = default;
-
- array_iterator& operator++() noexcept // ++pre
- {
- ++iter_;
- return *this;
- }
-
- array_iterator operator++(int) noexcept // post++
- {
- array_iterator out{ iter_ };
- ++iter_;
- return out;
- }
-
- array_iterator& operator--() noexcept // --pre
- {
- --iter_;
- return *this;
- }
-
- array_iterator operator--(int) noexcept // post--
- {
- array_iterator out{ iter_ };
- --iter_;
- return out;
- }
-
- TOML_PURE_INLINE_GETTER
- reference operator*() const noexcept
- {
- return *iter_->get();
- }
-
- TOML_PURE_INLINE_GETTER
- pointer operator->() const noexcept
- {
- return iter_->get();
- }
-
- TOML_PURE_INLINE_GETTER
- explicit operator const vector_iterator&() const noexcept
- {
- return iter_;
- }
-
- TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
- TOML_PURE_INLINE_GETTER
- explicit operator const const_vector_iterator() const noexcept
- {
- return iter_;
- }
-
- array_iterator& operator+=(ptrdiff_t rhs) noexcept
- {
- iter_ += rhs;
- return *this;
- }
-
- array_iterator& operator-=(ptrdiff_t rhs) noexcept
- {
- iter_ -= rhs;
- return *this;
- }
-
- TOML_NODISCARD
- friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept
- {
- return array_iterator{ lhs.iter_ + rhs };
- }
-
- TOML_NODISCARD
- friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept
- {
- return array_iterator{ rhs.iter_ + lhs };
- }
-
- TOML_NODISCARD
- friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept
- {
- return array_iterator{ lhs.iter_ - rhs };
- }
-
- TOML_PURE_INLINE_GETTER
- friend ptrdiff_t operator-(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ - rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ == rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ != rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator<(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ < rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator<=(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ <= rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator>(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ > rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator>=(const array_iterator& lhs, const array_iterator& rhs) noexcept
- {
- return lhs.iter_ >= rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- reference operator[](ptrdiff_t idx) const noexcept
- {
- return *(iter_ + idx)->get();
- }
- };
-
- struct array_init_elem
- {
- mutable node_ptr value;
-
- template <typename T>
- TOML_NODISCARD_CTOR
- array_init_elem(T&& val, value_flags flags = preserve_source_value_flags) //
- : value{ make_node(static_cast<T&&>(val), flags) }
- {}
- };
+TOML_IMPL_NAMESPACE_START {
+ template <bool IsConst>
+ class TOML_TRIVIAL_ABI array_iterator {
+ private:
+ template <bool>
+ friend class array_iterator;
+
+ using mutable_vector_iterator = std::vector<node_ptr>::iterator;
+ using const_vector_iterator = std::vector<node_ptr>::const_iterator;
+ using vector_iterator =
+ std::conditional_t<IsConst, const_vector_iterator, mutable_vector_iterator>;
+
+ mutable vector_iterator iter_;
+
+ public:
+ using value_type = std::conditional_t<IsConst, const node, node>;
+ using reference = value_type&;
+ using pointer = value_type*;
+ using difference_type = ptrdiff_t;
+ using iterator_category = typename std::iterator_traits<vector_iterator>::iterator_category;
+
+ TOML_NODISCARD_CTOR
+ array_iterator() noexcept = default;
+
+ TOML_NODISCARD_CTOR
+ explicit array_iterator(mutable_vector_iterator iter) noexcept //
+ : iter_{iter} {}
+
+ TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
+ TOML_NODISCARD_CTOR
+ explicit array_iterator(const_vector_iterator iter) noexcept //
+ : iter_{iter} {}
+
+ TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
+ TOML_NODISCARD_CTOR
+ array_iterator(const array_iterator<false>& other) noexcept //
+ : iter_{other.iter_} {}
+
+ TOML_NODISCARD_CTOR
+ array_iterator(const array_iterator&) noexcept = default;
+
+ array_iterator& operator=(const array_iterator&) noexcept = default;
+
+ array_iterator& operator++() noexcept // ++pre
+ {
+ ++iter_;
+ return *this;
+ }
+
+ array_iterator operator++(int) noexcept // post++
+ {
+ array_iterator out{iter_};
+ ++iter_;
+ return out;
+ }
+
+ array_iterator& operator--() noexcept // --pre
+ {
+ --iter_;
+ return *this;
+ }
+
+ array_iterator operator--(int) noexcept // post--
+ {
+ array_iterator out{iter_};
+ --iter_;
+ return out;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ reference operator*() const noexcept { return *iter_->get(); }
+
+ TOML_PURE_INLINE_GETTER
+ pointer operator->() const noexcept { return iter_->get(); }
+
+ TOML_PURE_INLINE_GETTER
+ explicit operator const vector_iterator&() const noexcept { return iter_; }
+
+ TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
+ TOML_PURE_INLINE_GETTER
+ explicit operator const const_vector_iterator() const noexcept { return iter_; }
+
+ array_iterator& operator+=(ptrdiff_t rhs) noexcept {
+ iter_ += rhs;
+ return *this;
+ }
+
+ array_iterator& operator-=(ptrdiff_t rhs) noexcept {
+ iter_ -= rhs;
+ return *this;
+ }
+
+ TOML_NODISCARD
+ friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept {
+ return array_iterator{lhs.iter_ + rhs};
+ }
+
+ TOML_NODISCARD
+ friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept {
+ return array_iterator{rhs.iter_ + lhs};
+ }
+
+ TOML_NODISCARD
+ friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept {
+ return array_iterator{lhs.iter_ - rhs};
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend ptrdiff_t operator-(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ - rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ == rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ != rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ < rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ <= rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ > rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
+ return lhs.iter_ >= rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ reference operator[](ptrdiff_t idx) const noexcept { return *(iter_ + idx)->get(); }
+ };
+
+ struct array_init_elem {
+ mutable node_ptr value;
+
+ template <typename T>
+ TOML_NODISCARD_CTOR array_init_elem(T&& val,
+ value_flags flags = preserve_source_value_flags) //
+ : value{make_node(static_cast<T&&>(val), flags)} {}
+ };
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief A RandomAccessIterator for iterating over elements in a toml::array.
- using array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<false>);
-
- /// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
- using const_array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<true>);
-
- /// \brief A TOML array.
- ///
- /// \detail The interface of this type is modeled after std::vector, with some
- /// additional considerations made for the heterogeneous nature of a
- /// TOML array.
- ///
- /// \godbolt{sjK4da}
- ///
- /// \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)
- /// {
- /// elem.visit([](auto&& el) noexcept
- /// {
- /// if constexpr (toml::is_number<decltype(el)>)
- /// (*el)++;
- /// else if constexpr (toml::is_string<decltype(el)>)
- /// el = "six"sv;
- /// });
- /// }
- /// std::cout << arr << "\n";
- ///
- /// // add and remove elements
- /// arr.push_back(7);
- /// arr.push_back(8.0f);
- /// arr.push_back("nine"sv);
- /// arr.erase(arr.cbegin());
- /// std::cout << arr << "\n";
- ///
- /// // emplace elements
- /// arr.emplace_back("ten");
- /// arr.emplace_back<toml::array>(11, 12.0);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 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 ] ]
- /// \eout
- class TOML_EXPORTED_CLASS array : public node
- {
- private:
- /// \cond
-
- using vector_type = std::vector<impl::node_ptr>;
- using vector_iterator = typename vector_type::iterator;
- using const_vector_iterator = typename vector_type::const_iterator;
- vector_type elems_;
-
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- array(const impl::array_init_elem*, const impl::array_init_elem*);
-
- TOML_NODISCARD_CTOR
- array(std::false_type, std::initializer_list<impl::array_init_elem> elems) //
- : array{ elems.begin(), elems.end() }
- {}
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void preinsertion_resize(size_t idx, size_t count);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void insert_at_back(impl::node_ptr&&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- vector_iterator insert_at(const_vector_iterator, impl::node_ptr&&);
-
- template <typename T>
- void emplace_back_if_not_empty_view(T&& val, value_flags flags)
- {
- if constexpr (is_node_view<T>)
- {
- if (!val)
- return;
- }
- insert_at_back(impl::make_node(static_cast<T&&>(val), flags));
- }
-
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- size_t total_leaf_count() const noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void flatten_child(array&& child, size_t& dest_index) noexcept;
-
- /// \endcond
-
- public:
- using value_type = node;
- using size_type = size_t;
- using difference_type = ptrdiff_t;
- using reference = node&;
- using const_reference = const node&;
-
- /// \brief Default constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- array() noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- ~array() noexcept;
-
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- array(const array&);
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- array(array&& other) noexcept;
-
- /// \brief Constructs an array with one or more initial elements.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2.0, "three"sv, toml::array{ 4, 5 } };
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2.0, 'three', [ 4, 5 ] ]
- /// \eout
- ///
- /// \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 } } }
- /// std::cout << "bad: " << bad << "\n";
- /// std::cout << "good:" << good << "\n";
- /// \ecpp
- ///
- /// \out
- /// bad: [ 42 ]
- /// good: [ [ 42 ] ]
- /// \eout
- ///
- /// \endparblock
- ///
- /// \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.
- TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0 || !std::is_same_v<impl::remove_cvref<ElemType>, array>),
- typename ElemType,
- typename... ElemTypes)
- TOML_NODISCARD_CTOR
- explicit array(ElemType&& val, ElemTypes&&... vals)
- : array{ std::false_type{},
- std::initializer_list<impl::array_init_elem>{ static_cast<ElemType&&>(val),
- static_cast<ElemTypes&&>(vals)... } }
- {}
-
- /// \brief Copy-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- array& operator=(const array&);
-
- /// \brief Move-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- array& operator=(array&& rhs) noexcept;
-
- /// \name Type checks
- /// @{
-
- /// \brief Returns #toml::node_type::array.
- TOML_CONST_INLINE_GETTER
- node_type type() const noexcept final
- {
- return node_type::array;
- }
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype) const noexcept final;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
-
- /// \cond
- template <typename ElemType = void>
- TOML_PURE_GETTER
- bool is_homogeneous() const noexcept
- {
- using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
- static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
- "The template type argument of array::is_homogeneous() must be void or one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- return is_homogeneous(impl::node_type_of<type>);
- }
- /// \endcond
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_table() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `true`.
- TOML_CONST_INLINE_GETTER
- bool is_array() const noexcept final
- {
- return true;
- }
-
- /// \brief Returns `true` if the array contains only tables.
- TOML_PURE_GETTER
- bool is_array_of_tables() const noexcept final
- {
- return is_homogeneous(node_type::table);
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_value() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_string() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_integer() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_floating_point() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_number() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_boolean() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_date() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_time() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_date_time() const noexcept final
- {
- return false;
- }
-
- /// @}
-
- /// \name Type casts
- /// @{
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- table* as_table() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns a pointer to the array.
- TOML_CONST_INLINE_GETTER
- array* as_array() noexcept final
- {
- return this;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<std::string>* as_string() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<int64_t>* as_integer() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<double>* as_floating_point() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<bool>* as_boolean() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<date>* as_date() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<time>* as_time() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<date_time>* as_date_time() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const table* as_table() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns a const-qualified pointer to the array.
- TOML_CONST_INLINE_GETTER
- const array* as_array() const noexcept final
- {
- return this;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<std::string>* as_string() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<int64_t>* as_integer() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<double>* as_floating_point() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<bool>* as_boolean() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<date>* as_date() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<time>* as_time() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<date_time>* as_date_time() const noexcept final
- {
- return nullptr;
- }
-
- /// @}
-
- /// \name Value retrieval
- /// @{
-
- /// \brief Gets a pointer to the element at a specific index.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 99, "bottles of beer on the wall" };
- /// 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";
- /// \ecpp
- ///
- /// \out
- /// element [0] exists: true
- /// element [1] exists: true
- /// element [2] exists: false
- /// element [0] is an integer
- /// \eout
- ///
- /// \param index The element's index.
- ///
- /// \returns A pointer to the element at the specified index if one existed, or nullptr.
- TOML_PURE_INLINE_GETTER
- node* get(size_t index) noexcept
- {
- return index < elems_.size() ? elems_[index].get() : nullptr;
- }
-
- /// \brief Gets a pointer to the element at a specific index (const overload).
- ///
- /// \param index The element's index.
- ///
- /// \returns A pointer to the element at the specified index if one existed, or nullptr.
- TOML_PURE_INLINE_GETTER
- const node* get(size_t index) const noexcept
- {
- return const_cast<array&>(*this).get(index);
- }
-
- /// \brief Gets a pointer to the element at a specific index if it is a particular type.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
- /// if (toml::value<int64_t>* val = arr.get_as<int64_t>(0))
- /// std::cout << "element [0] is an integer with value "sv << *val << "\n";
- /// \ecpp
- ///
- /// \out
- /// element [0] is an integer with value 42
- /// \eout
- ///
- /// \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.
- template <typename ElemType>
- TOML_NODISCARD
- impl::wrap_node<ElemType>* get_as(size_t index) noexcept
- {
- if (auto val = get(index))
- return val->template as<ElemType>();
- return nullptr;
- }
-
- /// \brief Gets a pointer to the element at a specific index if it is a particular type (const overload).
- ///
- /// \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.
- template <typename ElemType>
- TOML_NODISCARD
- const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept
- {
- return const_cast<array&>(*this).template get_as<ElemType>(index);
- }
-
- /// \cond
- using node::operator[]; // inherit operator[toml::path]
- /// \endcond
-
- /// \brief Gets a reference to the element at a specific index.
- TOML_NODISCARD
- node& operator[](size_t index) noexcept
- {
- return *elems_[index];
- }
-
- /// \brief Gets a reference to the element at a specific index.
- TOML_NODISCARD
- const node& operator[](size_t index) const noexcept
- {
- return *elems_[index];
- }
-
- /// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if none existed.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node& at(size_t index);
-
- /// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if none existed.
- TOML_NODISCARD
- const node& at(size_t index) const
- {
- return const_cast<array&>(*this).at(index);
- }
-
- /// \brief Returns a reference to the first element in the array.
- TOML_NODISCARD
- node& front() noexcept
- {
- return *elems_.front();
- }
-
- /// \brief Returns a reference to the first element in the array.
- TOML_NODISCARD
- const node& front() const noexcept
- {
- return *elems_.front();
- }
-
- /// \brief Returns a reference to the last element in the array.
- TOML_NODISCARD
- node& back() noexcept
- {
- return *elems_.back();
- }
-
- /// \brief Returns a reference to the last element in the array.
- TOML_NODISCARD
- const node& back() const noexcept
- {
- return *elems_.back();
- }
-
- /// @}
-
- /// \name Iteration
- /// @{
-
- /// \brief A RandomAccessIterator for iterating over elements in a toml::array.
- using iterator = array_iterator;
-
- /// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
- using const_iterator = const_array_iterator;
-
- /// \brief Returns an iterator to the first element.
- TOML_NODISCARD
- iterator begin() noexcept
- {
- return iterator{ elems_.begin() };
- }
-
- /// \brief Returns an iterator to the first element.
- TOML_NODISCARD
- const_iterator begin() const noexcept
- {
- return const_iterator{ elems_.cbegin() };
- }
-
- /// \brief Returns an iterator to the first element.
- TOML_NODISCARD
- const_iterator cbegin() const noexcept
- {
- return const_iterator{ elems_.cbegin() };
- }
-
- /// \brief Returns an iterator to one-past-the-last element.
- TOML_NODISCARD
- iterator end() noexcept
- {
- return iterator{ elems_.end() };
- }
-
- /// \brief Returns an iterator to one-past-the-last element.
- TOML_NODISCARD
- const_iterator end() const noexcept
- {
- return const_iterator{ elems_.cend() };
- }
-
- /// \brief Returns an iterator to one-past-the-last element.
- TOML_NODISCARD
- const_iterator cend() const noexcept
- {
- return const_iterator{ elems_.cend() };
- }
-
- private:
- /// \cond
-
- template <typename T, typename Array>
- using for_each_elem_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
-
- template <typename Func, typename Array, typename T>
- using can_for_each = std::disjunction<std::is_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
- std::is_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
- std::is_invocable<Func, for_each_elem_ref<T, Array>>>;
-
- template <typename Func, typename Array, typename T>
- using can_for_each_nothrow = std::conditional_t<
- // first form
- std::is_invocable_v<Func, for_each_elem_ref<T, Array>, size_t>,
- std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
- std::conditional_t<
- // second form
- std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>>,
- std::is_nothrow_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
- std::conditional_t<
- // third form
- std::is_invocable_v<Func, for_each_elem_ref<T, Array>>,
- std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>>,
- std::false_type>>>;
-
- template <typename Func, typename Array>
- using can_for_each_any = std::disjunction<can_for_each<Func, Array, table>,
- can_for_each<Func, Array, array>,
- can_for_each<Func, Array, std::string>,
- can_for_each<Func, Array, int64_t>,
- can_for_each<Func, Array, double>,
- can_for_each<Func, Array, bool>,
- can_for_each<Func, Array, date>,
- can_for_each<Func, Array, time>,
- can_for_each<Func, Array, date_time>>;
-
- template <typename Func, typename Array, typename T>
- using for_each_is_nothrow_one = std::disjunction<std::negation<can_for_each<Func, Array, T>>, //
- can_for_each_nothrow<Func, Array, T>>;
-
- template <typename Func, typename Array>
- using for_each_is_nothrow = std::conjunction<for_each_is_nothrow_one<Func, Array, table>,
- for_each_is_nothrow_one<Func, Array, array>,
- for_each_is_nothrow_one<Func, Array, std::string>,
- for_each_is_nothrow_one<Func, Array, int64_t>,
- for_each_is_nothrow_one<Func, Array, double>,
- for_each_is_nothrow_one<Func, Array, bool>,
- for_each_is_nothrow_one<Func, Array, date>,
- for_each_is_nothrow_one<Func, Array, time>,
- for_each_is_nothrow_one<Func, Array, date_time>>;
-
- template <typename Func, typename Array>
- static void do_for_each(Func&& visitor, Array&& arr) //
- noexcept(for_each_is_nothrow<Func&&, Array&&>::value)
- {
- static_assert(can_for_each_any<Func&&, Array&&>::value,
- "TOML array for_each visitors must be invocable for at least one of the toml::node "
- "specializations:" TOML_SA_NODE_TYPE_LIST);
-
- for (size_t i = 0; i < arr.size(); i++)
- {
- using node_ref = impl::copy_cvref<toml::node, Array&&>;
- static_assert(std::is_reference_v<node_ref>);
+TOML_NAMESPACE_START {
+ /// \brief A RandomAccessIterator for iterating over elements in a toml::array.
+ using array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<false>);
+
+ /// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
+ using const_array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<true>);
+
+ /// \brief A TOML array.
+ ///
+ /// \detail The interface of this type is modeled after std::vector, with some
+ /// additional considerations made for the heterogeneous nature of a
+ /// TOML array.
+ ///
+ /// \godbolt{sjK4da}
+ ///
+ /// \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)
+ /// {
+ /// elem.visit([](auto&& el) noexcept
+ /// {
+ /// if constexpr (toml::is_number<decltype(el)>)
+ /// (*el)++;
+ /// else if constexpr (toml::is_string<decltype(el)>)
+ /// el = "six"sv;
+ /// });
+ /// }
+ /// std::cout << arr << "\n";
+ ///
+ /// // add and remove elements
+ /// arr.push_back(7);
+ /// arr.push_back(8.0f);
+ /// arr.push_back("nine"sv);
+ /// arr.erase(arr.cbegin());
+ /// std::cout << arr << "\n";
+ ///
+ /// // emplace elements
+ /// arr.emplace_back("ten");
+ /// arr.emplace_back<toml::array>(11, 12.0);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 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 ] ]
+ /// \eout
+ class TOML_EXPORTED_CLASS array : public node {
+ private:
+ /// \cond
+
+ using vector_type = std::vector<impl::node_ptr>;
+ using vector_iterator = typename vector_type::iterator;
+ using const_vector_iterator = typename vector_type::const_iterator;
+ vector_type elems_;
+
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array(const impl::array_init_elem*, const impl::array_init_elem*);
+
+ TOML_NODISCARD_CTOR
+ array(std::false_type, std::initializer_list<impl::array_init_elem> elems) //
+ : array{elems.begin(), elems.end()} {}
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void preinsertion_resize(size_t idx, size_t count);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void insert_at_back(impl::node_ptr&&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ vector_iterator insert_at(const_vector_iterator, impl::node_ptr&&);
+
+ template <typename T>
+ void emplace_back_if_not_empty_view(T&& val, value_flags flags) {
+ if constexpr (is_node_view<T>) {
+ if (!val) return;
+ }
+ insert_at_back(impl::make_node(static_cast<T&&>(val), flags));
+ }
+
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ size_t total_leaf_count() const noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void flatten_child(array&& child, size_t& dest_index) noexcept;
+
+ /// \endcond
+
+ public:
+ using value_type = node;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using reference = node&;
+ using const_reference = const node&;
+
+ /// \brief Default constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array() noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ ~array() noexcept;
+
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array(const array&);
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array(array&& other) noexcept;
+
+ /// \brief Constructs an array with one or more initial elements.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2.0, "three"sv, toml::array{ 4, 5 } };
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2.0, 'three', [ 4, 5 ] ]
+ /// \eout
+ ///
+ /// \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 } } }
+ /// std::cout << "bad: " << bad << "\n";
+ /// std::cout << "good:" << good << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// bad: [ 42 ]
+ /// good: [ [ 42 ] ]
+ /// \eout
+ ///
+ /// \endparblock
+ ///
+ /// \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.
+ TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0 ||
+ !std::is_same_v<impl::remove_cvref<ElemType>, array>),
+ typename ElemType, typename... ElemTypes)
+ TOML_NODISCARD_CTOR
+ explicit array(ElemType&& val, ElemTypes&&... vals)
+ : array{std::false_type{},
+ std::initializer_list<impl::array_init_elem>{static_cast<ElemType&&>(val),
+ static_cast<ElemTypes&&>(vals)...}} {}
+
+ /// \brief Copy-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array& operator=(const array&);
+
+ /// \brief Move-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array& operator=(array&& rhs) noexcept;
+
+ /// \name Type checks
+ /// @{
+
+ /// \brief Returns #toml::node_type::array.
+ TOML_CONST_INLINE_GETTER
+ node_type type() const noexcept final { return node_type::array; }
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype) const noexcept final;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
+
+ /// \cond
+ template <typename ElemType = void>
+ TOML_PURE_GETTER bool is_homogeneous() const noexcept {
+ using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
+ static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
+ "The template type argument of array::is_homogeneous() must be void or one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ return is_homogeneous(impl::node_type_of<type>);
+ }
+ /// \endcond
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_table() const noexcept final { return false; }
+
+ /// \brief Returns `true`.
+ TOML_CONST_INLINE_GETTER
+ bool is_array() const noexcept final { return true; }
+
+ /// \brief Returns `true` if the array contains only tables.
+ TOML_PURE_GETTER
+ bool is_array_of_tables() const noexcept final { return is_homogeneous(node_type::table); }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_value() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_string() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_integer() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_floating_point() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_number() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_boolean() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_date() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_time() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_date_time() const noexcept final { return false; }
+
+ /// @}
+
+ /// \name Type casts
+ /// @{
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ table* as_table() noexcept final { return nullptr; }
+
+ /// \brief Returns a pointer to the array.
+ TOML_CONST_INLINE_GETTER
+ array* as_array() noexcept final { return this; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<std::string>* as_string() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<int64_t>* as_integer() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<double>* as_floating_point() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<bool>* as_boolean() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<date>* as_date() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<time>* as_time() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<date_time>* as_date_time() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const table* as_table() const noexcept final { return nullptr; }
+
+ /// \brief Returns a const-qualified pointer to the array.
+ TOML_CONST_INLINE_GETTER
+ const array* as_array() const noexcept final { return this; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<std::string>* as_string() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<int64_t>* as_integer() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<double>* as_floating_point() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<bool>* as_boolean() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<date>* as_date() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<time>* as_time() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<date_time>* as_date_time() const noexcept final { return nullptr; }
+
+ /// @}
+
+ /// \name Value retrieval
+ /// @{
+
+ /// \brief Gets a pointer to the element at a specific index.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 99, "bottles of beer on the wall" };
+ /// 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";
+ /// \ecpp
+ ///
+ /// \out
+ /// element [0] exists: true
+ /// element [1] exists: true
+ /// element [2] exists: false
+ /// element [0] is an integer
+ /// \eout
+ ///
+ /// \param index The element's index.
+ ///
+ /// \returns A pointer to the element at the specified index if one existed, or nullptr.
+ TOML_PURE_INLINE_GETTER
+ node* get(size_t index) noexcept {
+ return index < elems_.size() ? elems_[index].get() : nullptr;
+ }
+
+ /// \brief Gets a pointer to the element at a specific index (const overload).
+ ///
+ /// \param index The element's index.
+ ///
+ /// \returns A pointer to the element at the specified index if one existed, or nullptr.
+ TOML_PURE_INLINE_GETTER
+ const node* get(size_t index) const noexcept { return const_cast<array&>(*this).get(index); }
+
+ /// \brief Gets a pointer to the element at a specific index if it is a particular type.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 42, "is the meaning of life, apparently."sv };
+ /// if (toml::value<int64_t>* val = arr.get_as<int64_t>(0))
+ /// std::cout << "element [0] is an integer with value "sv << *val << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// element [0] is an integer with value 42
+ /// \eout
+ ///
+ /// \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.
+ template <typename ElemType>
+ TOML_NODISCARD impl::wrap_node<ElemType>* get_as(size_t index) noexcept {
+ if (auto val = get(index)) return val->template as<ElemType>();
+ return nullptr;
+ }
+
+ /// \brief Gets a pointer to the element at a specific index if it is a particular type (const
+ /// overload).
+ ///
+ /// \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.
+ template <typename ElemType>
+ TOML_NODISCARD const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept {
+ return const_cast<array&>(*this).template get_as<ElemType>(index);
+ }
+
+ /// \cond
+ using node::operator[]; // inherit operator[toml::path]
+ /// \endcond
+
+ /// \brief Gets a reference to the element at a specific index.
+ TOML_NODISCARD
+ node& operator[](size_t index) noexcept { return *elems_[index]; }
+
+ /// \brief Gets a reference to the element at a specific index.
+ TOML_NODISCARD
+ const node& operator[](size_t index) const noexcept { return *elems_[index]; }
+
+ /// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if
+ /// none existed.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node& at(size_t index);
+
+ /// \brief Gets a reference to the element at a specific index, throwing `std::out_of_range` if
+ /// none existed.
+ TOML_NODISCARD
+ const node& at(size_t index) const { return const_cast<array&>(*this).at(index); }
+
+ /// \brief Returns a reference to the first element in the array.
+ TOML_NODISCARD
+ node& front() noexcept { return *elems_.front(); }
+
+ /// \brief Returns a reference to the first element in the array.
+ TOML_NODISCARD
+ const node& front() const noexcept { return *elems_.front(); }
+
+ /// \brief Returns a reference to the last element in the array.
+ TOML_NODISCARD
+ node& back() noexcept { return *elems_.back(); }
+
+ /// \brief Returns a reference to the last element in the array.
+ TOML_NODISCARD
+ const node& back() const noexcept { return *elems_.back(); }
+
+ /// @}
+
+ /// \name Iteration
+ /// @{
+
+ /// \brief A RandomAccessIterator for iterating over elements in a toml::array.
+ using iterator = array_iterator;
+
+ /// \brief A RandomAccessIterator for iterating over const elements in a toml::array.
+ using const_iterator = const_array_iterator;
+
+ /// \brief Returns an iterator to the first element.
+ TOML_NODISCARD
+ iterator begin() noexcept { return iterator{elems_.begin()}; }
+
+ /// \brief Returns an iterator to the first element.
+ TOML_NODISCARD
+ const_iterator begin() const noexcept { return const_iterator{elems_.cbegin()}; }
+
+ /// \brief Returns an iterator to the first element.
+ TOML_NODISCARD
+ const_iterator cbegin() const noexcept { return const_iterator{elems_.cbegin()}; }
+
+ /// \brief Returns an iterator to one-past-the-last element.
+ TOML_NODISCARD
+ iterator end() noexcept { return iterator{elems_.end()}; }
+
+ /// \brief Returns an iterator to one-past-the-last element.
+ TOML_NODISCARD
+ const_iterator end() const noexcept { return const_iterator{elems_.cend()}; }
+
+ /// \brief Returns an iterator to one-past-the-last element.
+ TOML_NODISCARD
+ const_iterator cend() const noexcept { return const_iterator{elems_.cend()}; }
+
+ private:
+ /// \cond
+
+ template <typename T, typename Array>
+ using for_each_elem_ref =
+ impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
+
+ template <typename Func, typename Array, typename T>
+ using can_for_each =
+ std::disjunction<std::is_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
+ std::is_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
+ std::is_invocable<Func, for_each_elem_ref<T, Array>>>;
+
+ template <typename Func, typename Array, typename T>
+ using can_for_each_nothrow = std::conditional_t<
+ // first form
+ std::is_invocable_v<Func, for_each_elem_ref<T, Array>, size_t>,
+ std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
+ std::conditional_t<
+ // second form
+ std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>>,
+ std::is_nothrow_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
+ std::conditional_t<
+ // third form
+ std::is_invocable_v<Func, for_each_elem_ref<T, Array>>,
+ std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>>, std::false_type>>>;
+
+ template <typename Func, typename Array>
+ using can_for_each_any =
+ std::disjunction<can_for_each<Func, Array, table>, can_for_each<Func, Array, array>,
+ can_for_each<Func, Array, std::string>, can_for_each<Func, Array, int64_t>,
+ can_for_each<Func, Array, double>, can_for_each<Func, Array, bool>,
+ can_for_each<Func, Array, date>, can_for_each<Func, Array, time>,
+ can_for_each<Func, Array, date_time>>;
+
+ template <typename Func, typename Array, typename T>
+ using for_each_is_nothrow_one =
+ std::disjunction<std::negation<can_for_each<Func, Array, T>>, //
+ can_for_each_nothrow<Func, Array, T>>;
+
+ template <typename Func, typename Array>
+ using for_each_is_nothrow = std::conjunction<
+ for_each_is_nothrow_one<Func, Array, table>, for_each_is_nothrow_one<Func, Array, array>,
+ for_each_is_nothrow_one<Func, Array, std::string>,
+ for_each_is_nothrow_one<Func, Array, int64_t>, for_each_is_nothrow_one<Func, Array, double>,
+ for_each_is_nothrow_one<Func, Array, bool>, for_each_is_nothrow_one<Func, Array, date>,
+ for_each_is_nothrow_one<Func, Array, time>,
+ for_each_is_nothrow_one<Func, Array, date_time>>;
+
+ template <typename Func, typename Array>
+ static void do_for_each(Func&& visitor, Array&& arr) //
+ noexcept(for_each_is_nothrow<Func&&, Array&&>::value) {
+ static_assert(
+ can_for_each_any<Func&&, Array&&>::value,
+ "TOML array for_each visitors must be invocable for at least one of the toml::node "
+ "specializations:" TOML_SA_NODE_TYPE_LIST);
+
+ for (size_t i = 0; i < arr.size(); i++) {
+ using node_ref = impl::copy_cvref<toml::node, Array&&>;
+ static_assert(std::is_reference_v<node_ref>);
#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
- static_assert(impl::always_false<Func, Array, node_ref>, //
- TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
+ static_assert(impl::always_false<Func, Array, node_ref>, //
+ TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
#endif
- static_cast<node_ref>(static_cast<Array&&>(arr)[i])
- .visit(
- [&]([[maybe_unused]] auto&& elem) //
- noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value)
- {
- using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
- static_assert(std::is_reference_v<elem_ref>);
-
- // func(elem, i)
- if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
- {
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
- }
-
- // func(i, elem)
- else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
- {
- static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
- }
-
- // func(elem)
- else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
- {
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
- }
- });
+ static_cast<node_ref>(static_cast<Array&&>(arr)[i])
+ .visit([&]([[maybe_unused]] auto&& elem) //
+ noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value) {
+ using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
+ static_assert(std::is_reference_v<elem_ref>);
+
+ // func(elem, i)
+ if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>) {
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
+ }
+
+ // func(i, elem)
+ else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>) {
+ static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
+ }
+
+ // func(elem)
+ else if constexpr (std::is_invocable_v<Func&&, elem_ref>) {
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
+ }
+ });
#else
- const auto keep_going =
- static_cast<node_ref>(static_cast<Array&&>(arr)[i])
- .visit(
- [&]([[maybe_unused]] auto&& elem) //
- noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value)
- {
- using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
- static_assert(std::is_reference_v<elem_ref>);
-
- // func(elem, i)
- if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>)
- {
- using return_type =
- decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
-
- if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
- {
- return static_cast<bool>(
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
- }
- else
- {
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
- return true;
- }
- }
-
- // func(i, elem)
- else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>)
- {
- using return_type =
- decltype(static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
-
- if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
- {
- return static_cast<bool>(
- static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
- }
- else
- {
- static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
- return true;
- }
- }
-
- // func(elem)
- else if constexpr (std::is_invocable_v<Func&&, elem_ref>)
- {
- using return_type =
- decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
-
- if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
- {
- return static_cast<bool>(
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
- }
- else
- {
- static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
- return true;
- }
- }
-
- // visitor not compatible with this particular type
- else
- return true;
- });
-
- if (!keep_going)
- return;
+ const auto keep_going =
+ static_cast<node_ref>(static_cast<Array&&>(arr)[i])
+ .visit(
+ [&]([[maybe_unused]] auto&& elem) //
+ noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value) {
+ using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
+ static_assert(std::is_reference_v<elem_ref>);
+
+ // func(elem, i)
+ if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>) {
+ using return_type =
+ decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
+
+ if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
+ return static_cast<bool>(
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
+ } else {
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
+ return true;
+ }
+ }
+
+ // func(i, elem)
+ else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>) {
+ using return_type =
+ decltype(static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
+
+ if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
+ return static_cast<bool>(
+ static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
+ } else {
+ static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
+ return true;
+ }
+ }
+
+ // func(elem)
+ else if constexpr (std::is_invocable_v<Func&&, elem_ref>) {
+ using return_type =
+ decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
+
+ if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
+ return static_cast<bool>(
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
+ } else {
+ static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
+ return true;
+ }
+ }
+
+ // visitor not compatible with this particular type
+ else
+ return true;
+ });
+
+ if (!keep_going) return;
#endif
- }
- }
-
- /// \endcond
-
- public:
- /// \brief Invokes a visitor on each element in the array.
- ///
- /// \tparam Func A callable type invocable with one of the following signatures:
- /// <ul>
- /// <li> `func(elem, index)`
- /// <li> `func(elem)`
- /// <li> `func(index, elem)`
- /// </ul>
- /// Where:
- /// <ul>
- /// <li> `elem` will recieve the element as it's concrete type with cvref-qualifications matching the array
- /// <li> `index` will recieve a `size_t` indicating the element's index
- /// </ul>
- /// Visitors returning `bool` (or something convertible to `bool`) will cause iteration to
- /// stop if they return `false`.
- ///
- /// \param visitor The visitor object.
- ///
- /// \returns A reference to the array.
- ///
- /// \details \cpp
- /// toml::array arr{ 0, 1, 2, 3.0, "four", "five", 6 };
- ///
- /// // select only the integers using a strongly-typed visitor
- /// arr.for_each([](toml::value<int64_t>& elem)
- /// {
- /// std::cout << elem << ", ";
- /// });
- /// std::cout << "\n";
- ///
- /// // select all the numeric values using a generic visitor + is_number<> metafunction
- /// arr.for_each([](auto&& elem)
- /// {
- /// if constexpr (toml::is_number<decltype(elem)>)
- /// std::cout << elem << ", ";
- /// });
- /// std::cout << "\n";
- ///
- /// // select all the numeric values until we encounter something non-numeric
- /// arr.for_each([](auto&& elem)
- /// {
- /// if constexpr (toml::is_number<decltype(elem)>)
- /// {
- /// std::cout << elem << ", ";
- /// return true; // "keep going"
- /// }
- /// else
- /// return false; // "stop!"
- ///
- /// });
- /// std::cout << "\n";
- ///
- /// \ecpp
- /// \out
- /// 0, 1, 2, 6,
- /// 0, 1, 2, 3.0, 6,
- /// 0, 1, 2, 3.0,
- /// \eout
- ///
- /// \see node::visit()
- template <typename Func>
- array& for_each(Func&& visitor) & //
- noexcept(for_each_is_nothrow<Func&&, array&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), *this);
- return *this;
- }
-
- /// \brief Invokes a visitor on each element in the array (rvalue overload).
- template <typename Func>
- array&& for_each(Func&& visitor) && //
- noexcept(for_each_is_nothrow<Func&&, array&&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), static_cast<array&&>(*this));
- return static_cast<array&&>(*this);
- }
-
- /// \brief Invokes a visitor on each element in the array (const lvalue overload).
- template <typename Func>
- const array& for_each(Func&& visitor) const& //
- noexcept(for_each_is_nothrow<Func&&, const array&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), *this);
- return *this;
- }
-
- /// \brief Invokes a visitor on each element in the array (const rvalue overload).
- template <typename Func>
- const array&& for_each(Func&& visitor) const&& //
- noexcept(for_each_is_nothrow<Func&&, const array&&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), static_cast<const array&&>(*this));
- return static_cast<const array&&>(*this);
- }
-
- /// @}
-
- /// \name Size and Capacity
- /// @{
-
- /// \brief Returns true if the array is empty.
- TOML_NODISCARD
- bool empty() const noexcept
- {
- return elems_.empty();
- }
-
- /// \brief Returns the number of elements in the array.
- TOML_NODISCARD
- size_t size() const noexcept
- {
- return elems_.size();
- }
-
- /// \brief Returns the maximum number of elements that can be stored in an array on the current platform.
- TOML_NODISCARD
- size_t max_size() const noexcept
- {
- return elems_.max_size();
- }
-
- /// \brief Returns the current max number of elements that may be held in the array's internal storage.
- TOML_NODISCARD
- size_t capacity() const noexcept
- {
- return elems_.capacity();
- }
-
- /// \brief Reserves internal storage capacity up to a pre-determined number of elements.
- TOML_EXPORTED_MEMBER_FUNCTION
- void reserve(size_t new_capacity);
-
- /// \brief Requests the removal of any unused internal storage capacity.
- TOML_EXPORTED_MEMBER_FUNCTION
- void shrink_to_fit();
-
- /// \brief Shrinks the array to the given size.
- ///
- /// \detail \godbolt{rxEzK5}
- ///
- /// \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// std::cout << arr << "\n";
- ///
- /// arr.truncate(5); // no-op
- /// std::cout << arr << "\n";
- ///
- /// arr.truncate(1);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, 3 ]
- /// [ 1, 2, 3 ]
- /// [ 1]
- /// \eout
- ///
- /// \remarks Does nothing if the requested size is larger than or equal to the current size.
- TOML_EXPORTED_MEMBER_FUNCTION
- void truncate(size_t new_size);
-
- /// \brief Resizes the array.
- ///
- /// \detail \godbolt{W5zqx3}
- ///
- /// \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// std::cout << arr << "\n";
- ///
- /// arr.resize(6, 42);
- /// std::cout << arr << "\n";
- ///
- /// arr.resize(2, 0);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, 3 ]
- /// [ 1, 2, 3, 42, 42, 42 ]
- /// [ 1, 2 ]
- /// \eout
- ///
- /// \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.
- /// \param default_init_flags Value flags to apply to new values created if new elements are created by growing.
- template <typename ElemType>
- void resize(size_t new_size,
- ElemType&& default_init_val,
- value_flags default_init_flags = preserve_source_value_flags)
- {
- static_assert(!is_node_view<ElemType>,
- "The default element type argument to toml::array::resize may not be toml::node_view.");
-
- if (!new_size)
- clear();
- else if (new_size > elems_.size())
- insert(cend(), new_size - elems_.size(), static_cast<ElemType&&>(default_init_val), default_init_flags);
- else
- truncate(new_size);
- }
-
- /// @}
-
- /// \name Erasure
- /// @{
-
- /// \brief Removes the specified element from the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// std::cout << arr << "\n";
- ///
- /// arr.erase(arr.cbegin() + 1);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, 3 ]
- /// [ 1, 3 ]
- /// \eout
- ///
- /// \param pos Iterator to the element being erased.
- ///
- /// \returns Iterator to the first element immediately following the removed element.
- TOML_EXPORTED_MEMBER_FUNCTION
- iterator erase(const_iterator pos) noexcept;
-
- /// \brief Removes the elements in the range [first, last) from the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, "bad", "karma" 2 };
- /// std::cout << arr << "\n";
- ///
- /// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 'bad', 'karma', 3 ]
- /// [ 1, 3 ]
- /// \eout
- ///
- /// \param first Iterator to the first element being erased.
- /// \param last Iterator to the one-past-the-last element being erased.
- ///
- /// \returns Iterator to the first element immediately following the last removed element.
- TOML_EXPORTED_MEMBER_FUNCTION
- iterator erase(const_iterator first, const_iterator last) noexcept;
-
- /// \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{} };
- /// std::cout << arr << "\n";
- ///
- /// arr.flatten();
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, [ 3, 4, [ 5 ] ], 6, [] ]
- /// [ 1, 2, 3, 4, 5, 6 ]
- /// \eout
- ///
- /// \remarks Arrays inside child tables are not flattened.
- ///
- /// \returns A reference to the array.
- TOML_EXPORTED_MEMBER_FUNCTION
- array& flatten() &;
-
- /// \brief Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overload).
- array&& flatten() &&
- {
- return static_cast<toml::array&&>(this->flatten());
- }
-
- /// \brief Removes empty child arrays and tables.
- ///
- /// \detail \cpp
- ///
- /// auto arr = toml::array{ 1, 2, toml::array{ }, toml::array{ 3, toml::array{ } }, 4 };
- /// std::cout << arr << "\n";
- ///
- /// arr.prune(true);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, [], [ 3, [] ], 4 ]
- /// [ 1, 2, [ 3 ], 4 ]
- /// \eout
- ///
- /// \param recursive Should child arrays and tables themselves be pruned?
- ///
- /// \returns A reference to the array.
- TOML_EXPORTED_MEMBER_FUNCTION
- array& prune(bool recursive = true) & noexcept;
-
- /// \brief Removes empty child arrays and tables (rvalue overload).
- ///
- /// \param recursive Should child arrays and tables themselves be pruned?
- ///
- /// \returns An rvalue reference to the array.
- array&& prune(bool recursive = true) && noexcept
- {
- return static_cast<toml::array&&>(this->prune(recursive));
- }
-
- /// \brief Removes the last element from the array.
- TOML_EXPORTED_MEMBER_FUNCTION
- void pop_back() noexcept;
-
- /// \brief Removes all elements from the array.
- TOML_EXPORTED_MEMBER_FUNCTION
- void clear() noexcept;
-
- /// @}
-
- /// \name Insertion and Emplacement
- /// @{
-
- /// \brief Inserts a new element at a specific position in the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 3 };
- /// arr.insert(arr.cbegin() + 1, "two");
- /// arr.insert(arr.cend(), toml::array{ 4, 5 });
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 'two', 3, [ 4, 5 ] ]
- /// \eout
- ///
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// An iterator to the newly-inserted element.
- /// \conditional_return{Input is a null toml::node_view}
- /// end()
- ///
- /// \attention The return value will always be `end()` if the input value was a null 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, value_flags flags = preserve_source_value_flags)
- {
- if constexpr (is_node_view<ElemType>)
- {
- if (!val)
- return end();
- }
- return iterator{ insert_at(const_vector_iterator{ pos },
- impl::make_node(static_cast<ElemType&&>(val), flags)) };
- }
-
- /// \brief Repeatedly inserts a new element starting at a specific position in the array.
- ///
- /// \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");
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [
- /// 'with an evil twinkle in its eye the goose said',
- /// 'honk',
- /// 'honk',
- /// 'honk',
- /// 'and immediately we knew peace was never an option.'
- /// ]
- /// \eout
- ///
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// An iterator to the newly-inserted element.
- /// \conditional_return{count == 0}
- /// A copy of pos
- /// \conditional_return{Input is a null toml::node_view}
- /// end()
- ///
- /// \attention The return value will always be `end()` if the input value was a null 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,
- value_flags flags = preserve_source_value_flags)
- {
- if constexpr (is_node_view<ElemType>)
- {
- if (!val)
- return end();
- }
- switch (count)
- {
- case 0: return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
- case 1: return insert(pos, static_cast<ElemType&&>(val), flags);
- default:
- {
- const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
- preinsertion_resize(start_idx, count);
- size_t i = start_idx;
- for (size_t e = start_idx + count - 1u; i < e; i++)
- elems_[i] = impl::make_node(val, flags);
-
- //# potentially move the initial value into the last element
- elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags);
- return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
- }
- }
- }
-
- /// \brief Inserts a range of elements into the array at a specific position.
- ///
- /// \tparam Iter An iterator type. Must satisfy ForwardIterator.
- /// \param pos The insertion position.
- /// \param first Iterator to the first node or value being inserted.
- /// \param last Iterator to the one-past-the-last node or value being inserted.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// An iterator to the first newly-inserted element.
- /// \conditional_return{first >= last}
- /// A copy of pos
- /// \conditional_return{All objects in the range were null toml::node_views}
- /// A copy of pos
- template <typename Iter>
- iterator insert(const_iterator pos, Iter first, Iter last, value_flags flags = preserve_source_value_flags)
- {
- const auto distance = std::distance(first, last);
- if (distance <= 0)
- return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
- else
- {
- auto count = distance;
- using deref_type = decltype(*first);
- if constexpr (is_node_view<deref_type>)
- {
- for (auto it = first; it != last; it++)
- if (!(*it))
- count--;
- if (!count)
- return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
- }
- const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
- preinsertion_resize(start_idx, static_cast<size_t>(count));
- size_t i = start_idx;
- for (auto it = first; it != last; it++)
- {
- if constexpr (is_node_view<deref_type>)
- {
- if (!(*it))
- continue;
- }
- if constexpr (std::is_rvalue_reference_v<deref_type>)
- elems_[i++] = impl::make_node(std::move(*it), flags);
- else
- elems_[i++] = impl::make_node(*it, flags);
- }
- return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
- }
- }
-
- /// \brief Inserts a range of elements into the array at a specific position.
- ///
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// An iterator to the first newly-inserted element.
- /// \conditional_return{Input list is empty}
- /// A copy of pos
- /// \conditional_return{All objects in the list were null toml::node_views}
- /// A copy of pos
- template <typename ElemType>
- iterator insert(const_iterator pos,
- std::initializer_list<ElemType> ilist,
- value_flags flags = preserve_source_value_flags)
- {
- return insert(pos, ilist.begin(), ilist.end(), flags);
- }
-
- /// \brief Emplaces a new element at a specific position in the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2 };
- ///
- /// //add a string using std::string's substring constructor
- /// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 'drill', 2 ]
- /// \eout
- ///
- /// \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.
- ///
- /// \returns An iterator to the inserted element.
- ///
- /// \remarks There is no difference between insert() and emplace()
- /// for trivial value types (floats, ints, bools).
- template <typename ElemType = void, typename... Args>
- iterator emplace(const_iterator pos, Args&&... args)
- {
- using raw_elem_type = impl::remove_cvref<ElemType>;
- using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
- impl::emplaced_type_of<Args&&...>,
- raw_elem_type>;
-
- using type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
- static_assert(impl::is_native<type> || impl::is_one_of<type, table, array>,
- "Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- return iterator{ insert_at(const_vector_iterator{ pos },
- impl::node_ptr{ new impl::wrap_node<type>{ static_cast<Args&&>(args)... } }) };
- }
-
- /// \brief Replaces the element at a specific position in the array with a different value.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// std::cout << arr << "\n";
- /// arr.replace(arr.cbegin() + 1, "two");
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, 3 ]
- /// [ 1, 'two', 3 ]
- /// \eout
- ///
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// An iterator to the replaced element.
- /// \conditional_return{Input is a null toml::node_view}
- /// end()
- ///
- /// \attention The return value will always be `end()` if the input value was a null toml::node_view,
- /// because no replacement can take place. This is the only circumstance in which this can occur.
- template <typename ElemType>
- iterator replace(const_iterator pos, ElemType&& val, value_flags flags = preserve_source_value_flags)
- {
- TOML_ASSERT(pos >= cbegin() && pos < cend());
-
- if constexpr (is_node_view<ElemType>)
- {
- if (!val)
- return end();
- }
-
- const auto it = elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin());
- *it = impl::make_node(static_cast<ElemType&&>(val), flags);
- return iterator{ it };
- }
-
- /// \brief Appends a new element to the end of the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2 };
- /// arr.push_back(3);
- /// arr.push_back(4.0);
- /// arr.push_back(toml::array{ 5, "six"sv });
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, 3, 4.0, [ 5, 'six' ] ]
- /// \eout
- ///
- /// \tparam ElemType toml::node, toml::node_view, toml::table, toml::array, or a native TOML value type
- /// \param val The node or value being added.
- /// \param flags Value flags to apply to new values.
- ///
- /// \attention No insertion takes place if the input value is a null toml::node_view.
- /// This is the only circumstance in which this can occur.
- template <typename ElemType>
- void push_back(ElemType&& val, value_flags flags = preserve_source_value_flags)
- {
- emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), flags);
- }
-
- /// \brief Emplaces a new element at the end of the array.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2 };
- /// arr.emplace_back<toml::array>(3, "four"sv);
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// [ 1, 2, [ 3, 'four' ] ]
- /// \eout
- ///
- /// \tparam ElemType toml::table, toml::array, or a native TOML value type
- /// \tparam Args Element constructor argument types.
- /// \param args Arguments to forward to the elements's constructor.
- ///
- /// \returns A reference to the newly-constructed element.
- ///
- /// \remarks There is no difference between push_back() and emplace_back()
- /// For trivial value types (floats, ints, bools).
- template <typename ElemType = void, typename... Args>
- decltype(auto) emplace_back(Args&&... args)
- {
- using raw_elem_type = impl::remove_cvref<ElemType>;
- using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
- impl::emplaced_type_of<Args&&...>,
- raw_elem_type>;
-
- static constexpr auto moving_node_ptr = std::is_same_v<elem_type, impl::node_ptr> //
- && sizeof...(Args) == 1u //
- && impl::first_is_same<impl::node_ptr&&, Args&&...>;
-
- using unwrapped_type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
-
- static_assert(
- moving_node_ptr //
- || impl::is_native<unwrapped_type> //
- || impl::is_one_of<unwrapped_type, table, array>, //
- "ElemType argument of array::emplace_back() must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- if constexpr (moving_node_ptr)
- {
- insert_at_back(static_cast<Args&&>(args)...);
- return *elems_.back();
- }
- else
- {
- auto ptr = new impl::wrap_node<unwrapped_type>{ static_cast<Args&&>(args)... };
- insert_at_back(impl::node_ptr{ ptr });
- return *ptr;
- }
- }
-
- /// @}
-
- private:
- /// \cond
-
- TOML_NODISCARD
- TOML_EXPORTED_STATIC_FUNCTION
- static bool TOML_CALLCONV equal(const array&, const array&) noexcept;
-
- template <typename T>
- TOML_NODISCARD
- static bool equal_to_container(const array& lhs, const T& rhs) noexcept
- {
- using element_type = std::remove_const_t<typename T::value_type>;
- static_assert(impl::is_losslessly_convertible_to_native<element_type>,
- "Container element type must be losslessly convertible one of the native TOML value types");
-
- if (lhs.size() != rhs.size())
- return false;
- if (rhs.size() == 0u)
- return true;
-
- size_t i{};
- for (auto& list_elem : rhs)
- {
- const auto elem = lhs.get_as<impl::native_type_of<element_type>>(i++);
- if (!elem || *elem != list_elem)
- return false;
- }
-
- return true;
- }
-
- /// \endcond
-
- public:
- /// \name Equality
- /// @{
-
- /// \brief Equality operator.
- ///
- /// \param lhs The LHS array.
- /// \param rhs The RHS array.
- ///
- /// \returns True if the arrays contained the same elements.
- TOML_NODISCARD
- friend bool operator==(const array& lhs, const array& rhs) noexcept
- {
- return equal(lhs, rhs);
- }
-
- /// \brief Inequality operator.
- ///
- /// \param lhs The LHS array.
- /// \param rhs The RHS array.
- ///
- /// \returns True if the arrays did not contain the same elements.
- TOML_NODISCARD
- friend bool operator!=(const array& lhs, const array& rhs) noexcept
- {
- return !equal(lhs, rhs);
- }
-
- /// \brief Initializer list equality operator.
- template <typename T>
- TOML_NODISCARD
- friend bool operator==(const array& lhs, const std::initializer_list<T>& rhs) noexcept
- {
- return equal_to_container(lhs, rhs);
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::initializer_list<T>&, template <typename T>);
-
- /// \brief Vector equality operator.
- template <typename T>
- TOML_NODISCARD
- friend bool operator==(const array& lhs, const std::vector<T>& rhs) noexcept
- {
- return equal_to_container(lhs, rhs);
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::vector<T>&, template <typename T>);
-
- /// @}
+ }
+ }
+
+ /// \endcond
+
+ public:
+ /// \brief Invokes a visitor on each element in the array.
+ ///
+ /// \tparam Func A callable type invocable with one of the following signatures:
+ /// <ul>
+ /// <li> `func(elem, index)`
+ /// <li> `func(elem)`
+ /// <li> `func(index, elem)`
+ /// </ul>
+ /// Where:
+ /// <ul>
+ /// <li> `elem` will recieve the element as it's concrete type with cvref-qualifications
+ ///matching the array <li> `index` will recieve a `size_t` indicating the element's index
+ /// </ul>
+ /// Visitors returning `bool` (or something convertible to `bool`) will cause iteration
+ ///to stop if they return `false`.
+ ///
+ /// \param visitor The visitor object.
+ ///
+ /// \returns A reference to the array.
+ ///
+ /// \details \cpp
+ /// toml::array arr{ 0, 1, 2, 3.0, "four", "five", 6 };
+ ///
+ /// // select only the integers using a strongly-typed visitor
+ /// arr.for_each([](toml::value<int64_t>& elem)
+ /// {
+ /// std::cout << elem << ", ";
+ /// });
+ /// std::cout << "\n";
+ ///
+ /// // select all the numeric values using a generic visitor + is_number<> metafunction
+ /// arr.for_each([](auto&& elem)
+ /// {
+ /// if constexpr (toml::is_number<decltype(elem)>)
+ /// std::cout << elem << ", ";
+ /// });
+ /// std::cout << "\n";
+ ///
+ /// // select all the numeric values until we encounter something non-numeric
+ /// arr.for_each([](auto&& elem)
+ /// {
+ /// if constexpr (toml::is_number<decltype(elem)>)
+ /// {
+ /// std::cout << elem << ", ";
+ /// return true; // "keep going"
+ /// }
+ /// else
+ /// return false; // "stop!"
+ ///
+ /// });
+ /// std::cout << "\n";
+ ///
+ /// \ecpp
+ /// \out
+ /// 0, 1, 2, 6,
+ /// 0, 1, 2, 3.0, 6,
+ /// 0, 1, 2, 3.0,
+ /// \eout
+ ///
+ /// \see node::visit()
+ template <typename Func>
+ array& for_each(Func&& visitor) & //
+ noexcept(for_each_is_nothrow<Func&&, array&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), *this);
+ return *this;
+ }
+
+ /// \brief Invokes a visitor on each element in the array (rvalue overload).
+ template <typename Func>
+ array&& for_each(Func&& visitor) && //
+ noexcept(for_each_is_nothrow<Func&&, array&&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), static_cast<array&&>(*this));
+ return static_cast<array&&>(*this);
+ }
+
+ /// \brief Invokes a visitor on each element in the array (const lvalue overload).
+ template <typename Func>
+ const array& for_each(Func&& visitor) const& //
+ noexcept(for_each_is_nothrow<Func&&, const array&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), *this);
+ return *this;
+ }
+
+ /// \brief Invokes a visitor on each element in the array (const rvalue overload).
+ template <typename Func>
+ const array&& for_each(Func&& visitor) const&& //
+ noexcept(for_each_is_nothrow<Func&&, const array&&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), static_cast<const array&&>(*this));
+ return static_cast<const array&&>(*this);
+ }
+
+ /// @}
+
+ /// \name Size and Capacity
+ /// @{
+
+ /// \brief Returns true if the array is empty.
+ TOML_NODISCARD
+ bool empty() const noexcept { return elems_.empty(); }
+
+ /// \brief Returns the number of elements in the array.
+ TOML_NODISCARD
+ size_t size() const noexcept { return elems_.size(); }
+
+ /// \brief Returns the maximum number of elements that can be stored in an array on the current
+ /// platform.
+ TOML_NODISCARD
+ size_t max_size() const noexcept { return elems_.max_size(); }
+
+ /// \brief Returns the current max number of elements that may be held in the array's internal
+ /// storage.
+ TOML_NODISCARD
+ size_t capacity() const noexcept { return elems_.capacity(); }
+
+ /// \brief Reserves internal storage capacity up to a pre-determined number of elements.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void reserve(size_t new_capacity);
+
+ /// \brief Requests the removal of any unused internal storage capacity.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void shrink_to_fit();
+
+ /// \brief Shrinks the array to the given size.
+ ///
+ /// \detail \godbolt{rxEzK5}
+ ///
+ /// \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.truncate(5); // no-op
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.truncate(1);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, 3 ]
+ /// [ 1, 2, 3 ]
+ /// [ 1]
+ /// \eout
+ ///
+ /// \remarks Does nothing if the requested size is larger than or equal to the current size.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void truncate(size_t new_size);
+
+ /// \brief Resizes the array.
+ ///
+ /// \detail \godbolt{W5zqx3}
+ ///
+ /// \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.resize(6, 42);
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.resize(2, 0);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, 3 ]
+ /// [ 1, 2, 3, 42, 42, 42 ]
+ /// [ 1, 2 ]
+ /// \eout
+ ///
+ /// \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.
+ /// \param default_init_flags Value flags to apply to new values created if new elements are
+ /// created by growing.
+ template <typename ElemType>
+ void resize(size_t new_size, ElemType&& default_init_val,
+ value_flags default_init_flags = preserve_source_value_flags) {
+ static_assert(
+ !is_node_view<ElemType>,
+ "The default element type argument to toml::array::resize may not be toml::node_view.");
+
+ if (!new_size)
+ clear();
+ else if (new_size > elems_.size())
+ insert(cend(), new_size - elems_.size(), static_cast<ElemType&&>(default_init_val),
+ default_init_flags);
+ else
+ truncate(new_size);
+ }
+
+ /// @}
+
+ /// \name Erasure
+ /// @{
+
+ /// \brief Removes the specified element from the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.erase(arr.cbegin() + 1);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, 3 ]
+ /// [ 1, 3 ]
+ /// \eout
+ ///
+ /// \param pos Iterator to the element being erased.
+ ///
+ /// \returns Iterator to the first element immediately following the removed element.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ iterator erase(const_iterator pos) noexcept;
+
+ /// \brief Removes the elements in the range [first, last) from the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, "bad", "karma" 2 };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.erase(arr.cbegin() + 1, arr.cbegin() + 3);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 'bad', 'karma', 3 ]
+ /// [ 1, 3 ]
+ /// \eout
+ ///
+ /// \param first Iterator to the first element being erased.
+ /// \param last Iterator to the one-past-the-last element being erased.
+ ///
+ /// \returns Iterator to the first element immediately following the last removed element.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ iterator erase(const_iterator first, const_iterator last) noexcept;
+
+ /// \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{} };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.flatten();
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, [ 3, 4, [ 5 ] ], 6, [] ]
+ /// [ 1, 2, 3, 4, 5, 6 ]
+ /// \eout
+ ///
+ /// \remarks Arrays inside child tables are not flattened.
+ ///
+ /// \returns A reference to the array.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array& flatten() &;
+
+ /// \brief Flattens this array, recursively hoisting the contents of child arrays up into
+ /// itself (rvalue overload).
+ array&& flatten() && { return static_cast<toml::array&&>(this->flatten()); }
+
+ /// \brief Removes empty child arrays and tables.
+ ///
+ /// \detail \cpp
+ ///
+ /// auto arr = toml::array{ 1, 2, toml::array{ }, toml::array{ 3, toml::array{ } }, 4 };
+ /// std::cout << arr << "\n";
+ ///
+ /// arr.prune(true);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, [], [ 3, [] ], 4 ]
+ /// [ 1, 2, [ 3 ], 4 ]
+ /// \eout
+ ///
+ /// \param recursive Should child arrays and tables themselves be pruned?
+ ///
+ /// \returns A reference to the array.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ array& prune(bool recursive = true) & noexcept;
+
+ /// \brief Removes empty child arrays and tables (rvalue overload).
+ ///
+ /// \param recursive Should child arrays and tables themselves be pruned?
+ ///
+ /// \returns An rvalue reference to the array.
+ array&& prune(bool recursive = true) && noexcept {
+ return static_cast<toml::array&&>(this->prune(recursive));
+ }
+
+ /// \brief Removes the last element from the array.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void pop_back() noexcept;
+
+ /// \brief Removes all elements from the array.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void clear() noexcept;
+
+ /// @}
+
+ /// \name Insertion and Emplacement
+ /// @{
+
+ /// \brief Inserts a new element at a specific position in the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 3 };
+ /// arr.insert(arr.cbegin() + 1, "two");
+ /// arr.insert(arr.cend(), toml::array{ 4, 5 });
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 'two', 3, [ 4, 5 ] ]
+ /// \eout
+ ///
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// An iterator to the newly-inserted element.
+ /// \conditional_return{Input is a null toml::node_view}
+ /// end()
+ ///
+ /// \attention The return value will always be `end()` if the input value was a null
+ /// 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,
+ value_flags flags = preserve_source_value_flags) {
+ if constexpr (is_node_view<ElemType>) {
+ if (!val) return end();
+ }
+ return iterator{insert_at(const_vector_iterator{pos},
+ impl::make_node(static_cast<ElemType&&>(val), flags))};
+ }
+
+ /// \brief Repeatedly inserts a new element starting at a specific position in the array.
+ ///
+ /// \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");
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [
+ /// 'with an evil twinkle in its eye the goose said',
+ /// 'honk',
+ /// 'honk',
+ /// 'honk',
+ /// 'and immediately we knew peace was never an option.'
+ /// ]
+ /// \eout
+ ///
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// An iterator to the newly-inserted element.
+ /// \conditional_return{count == 0}
+ /// A copy of pos
+ /// \conditional_return{Input is a null toml::node_view}
+ /// end()
+ ///
+ /// \attention The return value will always be `end()` if the input value was a null
+ /// 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,
+ value_flags flags = preserve_source_value_flags) {
+ if constexpr (is_node_view<ElemType>) {
+ if (!val) return end();
+ }
+ switch (count) {
+ case 0:
+ return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
+ case 1:
+ return insert(pos, static_cast<ElemType&&>(val), flags);
+ default: {
+ const auto start_idx = static_cast<size_t>(const_vector_iterator{pos} - elems_.cbegin());
+ preinsertion_resize(start_idx, count);
+ size_t i = start_idx;
+ for (size_t e = start_idx + count - 1u; i < e; i++)
+ elems_[i] = impl::make_node(val, flags);
+
+ // # potentially move the initial value into the last element
+ elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags);
+ return iterator{elems_.begin() + static_cast<ptrdiff_t>(start_idx)};
+ }
+ }
+ }
+
+ /// \brief Inserts a range of elements into the array at a specific position.
+ ///
+ /// \tparam Iter An iterator type. Must satisfy ForwardIterator.
+ /// \param pos The insertion position.
+ /// \param first Iterator to the first node or value being inserted.
+ /// \param last Iterator to the one-past-the-last node or value being inserted.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// An iterator to the first newly-inserted element.
+ /// \conditional_return{first >= last}
+ /// A copy of pos
+ /// \conditional_return{All objects in the range were null toml::node_views}
+ /// A copy of pos
+ template <typename Iter>
+ iterator insert(const_iterator pos, Iter first, Iter last,
+ value_flags flags = preserve_source_value_flags) {
+ const auto distance = std::distance(first, last);
+ if (distance <= 0)
+ return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
+ else {
+ auto count = distance;
+ using deref_type = decltype(*first);
+ if constexpr (is_node_view<deref_type>) {
+ for (auto it = first; it != last; it++)
+ if (!(*it)) count--;
+ if (!count)
+ return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
+ }
+ const auto start_idx = static_cast<size_t>(const_vector_iterator{pos} - elems_.cbegin());
+ preinsertion_resize(start_idx, static_cast<size_t>(count));
+ size_t i = start_idx;
+ for (auto it = first; it != last; it++) {
+ if constexpr (is_node_view<deref_type>) {
+ if (!(*it)) continue;
+ }
+ if constexpr (std::is_rvalue_reference_v<deref_type>)
+ elems_[i++] = impl::make_node(std::move(*it), flags);
+ else
+ elems_[i++] = impl::make_node(*it, flags);
+ }
+ return iterator{elems_.begin() + static_cast<ptrdiff_t>(start_idx)};
+ }
+ }
+
+ /// \brief Inserts a range of elements into the array at a specific position.
+ ///
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// An iterator to the first newly-inserted element.
+ /// \conditional_return{Input list is empty}
+ /// A copy of pos
+ /// \conditional_return{All objects in the list were null toml::node_views}
+ /// A copy of pos
+ template <typename ElemType>
+ iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist,
+ value_flags flags = preserve_source_value_flags) {
+ return insert(pos, ilist.begin(), ilist.end(), flags);
+ }
+
+ /// \brief Emplaces a new element at a specific position in the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2 };
+ ///
+ /// //add a string using std::string's substring constructor
+ /// arr.emplace<std::string>(arr.cbegin() + 1, "this is not a drill"sv, 14, 5);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 'drill', 2 ]
+ /// \eout
+ ///
+ /// \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.
+ ///
+ /// \returns An iterator to the inserted element.
+ ///
+ /// \remarks There is no difference between insert() and emplace()
+ /// for trivial value types (floats, ints, bools).
+ template <typename ElemType = void, typename... Args>
+ iterator emplace(const_iterator pos, Args&&... args) {
+ using raw_elem_type = impl::remove_cvref<ElemType>;
+ using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
+ impl::emplaced_type_of<Args&&...>, raw_elem_type>;
+
+ using type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
+ static_assert(impl::is_native<type> || impl::is_one_of<type, table, array>,
+ "Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ return iterator{
+ insert_at(const_vector_iterator{pos},
+ impl::node_ptr{new impl::wrap_node<type>{static_cast<Args&&>(args)...}})};
+ }
+
+ /// \brief Replaces the element at a specific position in the array with a different value.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// std::cout << arr << "\n";
+ /// arr.replace(arr.cbegin() + 1, "two");
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, 3 ]
+ /// [ 1, 'two', 3 ]
+ /// \eout
+ ///
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// An iterator to the replaced element.
+ /// \conditional_return{Input is a null toml::node_view}
+ /// end()
+ ///
+ /// \attention The return value will always be `end()` if the input value was a null
+ /// toml::node_view, because no replacement can take place. This is the only circumstance in
+ /// which this can occur.
+ template <typename ElemType>
+ iterator replace(const_iterator pos, ElemType&& val,
+ value_flags flags = preserve_source_value_flags) {
+ TOML_ASSERT(pos >= cbegin() && pos < cend());
+
+ if constexpr (is_node_view<ElemType>) {
+ if (!val) return end();
+ }
+
+ const auto it = elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin());
+ *it = impl::make_node(static_cast<ElemType&&>(val), flags);
+ return iterator{it};
+ }
+
+ /// \brief Appends a new element to the end of the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2 };
+ /// arr.push_back(3);
+ /// arr.push_back(4.0);
+ /// arr.push_back(toml::array{ 5, "six"sv });
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, 3, 4.0, [ 5, 'six' ] ]
+ /// \eout
+ ///
+ /// \tparam ElemType toml::node, toml::node_view, toml::table, toml::array, or a native TOML
+ /// value type
+ /// \param val The node or value being added.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \attention No insertion takes place if the input value is a null toml::node_view.
+ /// This is the only circumstance in which this can occur.
+ template <typename ElemType>
+ void push_back(ElemType&& val, value_flags flags = preserve_source_value_flags) {
+ emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), flags);
+ }
+
+ /// \brief Emplaces a new element at the end of the array.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2 };
+ /// arr.emplace_back<toml::array>(3, "four"sv);
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// [ 1, 2, [ 3, 'four' ] ]
+ /// \eout
+ ///
+ /// \tparam ElemType toml::table, toml::array, or a native TOML value type
+ /// \tparam Args Element constructor argument types.
+ /// \param args Arguments to forward to the elements's constructor.
+ ///
+ /// \returns A reference to the newly-constructed element.
+ ///
+ /// \remarks There is no difference between push_back() and emplace_back()
+ /// For trivial value types (floats, ints, bools).
+ template <typename ElemType = void, typename... Args>
+ decltype(auto) emplace_back(Args&&... args) {
+ using raw_elem_type = impl::remove_cvref<ElemType>;
+ using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
+ impl::emplaced_type_of<Args&&...>, raw_elem_type>;
+
+ static constexpr auto moving_node_ptr = std::is_same_v<elem_type, impl::node_ptr> //
+ && sizeof...(Args) == 1u //
+ && impl::first_is_same<impl::node_ptr&&, Args&&...>;
+
+ using unwrapped_type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
+
+ static_assert(moving_node_ptr //
+ || impl::is_native<unwrapped_type> //
+ || impl::is_one_of<unwrapped_type, table, array>, //
+ "ElemType argument of array::emplace_back() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ if constexpr (moving_node_ptr) {
+ insert_at_back(static_cast<Args&&>(args)...);
+ return *elems_.back();
+ } else {
+ auto ptr = new impl::wrap_node<unwrapped_type>{static_cast<Args&&>(args)...};
+ insert_at_back(impl::node_ptr{ptr});
+ return *ptr;
+ }
+ }
+
+ /// @}
+
+ private:
+ /// \cond
+
+ TOML_NODISCARD
+ TOML_EXPORTED_STATIC_FUNCTION
+ static bool TOML_CALLCONV equal(const array&, const array&) noexcept;
+
+ template <typename T>
+ TOML_NODISCARD static bool equal_to_container(const array& lhs, const T& rhs) noexcept {
+ using element_type = std::remove_const_t<typename T::value_type>;
+ static_assert(impl::is_losslessly_convertible_to_native<element_type>,
+ "Container element type must be losslessly convertible one of the native TOML "
+ "value types");
+
+ if (lhs.size() != rhs.size()) return false;
+ if (rhs.size() == 0u) return true;
+
+ size_t i{};
+ for (auto& list_elem : rhs) {
+ const auto elem = lhs.get_as<impl::native_type_of<element_type>>(i++);
+ if (!elem || *elem != list_elem) return false;
+ }
+
+ return true;
+ }
+
+ /// \endcond
+
+ public:
+ /// \name Equality
+ /// @{
+
+ /// \brief Equality operator.
+ ///
+ /// \param lhs The LHS array.
+ /// \param rhs The RHS array.
+ ///
+ /// \returns True if the arrays contained the same elements.
+ TOML_NODISCARD
+ friend bool operator==(const array& lhs, const array& rhs) noexcept { return equal(lhs, rhs); }
+
+ /// \brief Inequality operator.
+ ///
+ /// \param lhs The LHS array.
+ /// \param rhs The RHS array.
+ ///
+ /// \returns True if the arrays did not contain the same elements.
+ TOML_NODISCARD
+ friend bool operator!=(const array& lhs, const array& rhs) noexcept { return !equal(lhs, rhs); }
+
+ /// \brief Initializer list equality operator.
+ template <typename T>
+ TOML_NODISCARD friend bool operator==(const array& lhs,
+ const std::initializer_list<T>& rhs) noexcept {
+ return equal_to_container(lhs, rhs);
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::initializer_list<T>&,
+ template <typename T>);
+
+ /// \brief Vector equality operator.
+ template <typename T>
+ TOML_NODISCARD friend bool operator==(const array& lhs, const std::vector<T>& rhs) noexcept {
+ return equal_to_container(lhs, rhs);
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::vector<T>&, template <typename T>);
+
+ /// @}
#if TOML_ENABLE_FORMATTERS
- /// \brief Prints the array out to a stream as formatted TOML.
- ///
- /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
- friend std::ostream& operator<<(std::ostream& lhs, const array& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
+ /// \brief Prints the array out to a stream as formatted TOML.
+ ///
+ /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ friend std::ostream& operator<<(std::ostream& lhs, const array& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
#endif
- };
+ };
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/at_path.hpp b/vendor/toml++/impl/at_path.hpp
index e351e6b..8ea273e 100644
--- a/vendor/toml++/impl/at_path.hpp
+++ b/vendor/toml++/impl/at_path.hpp
@@ -1,96 +1,92 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "forward_declarations.hpp"
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- using parse_path_callback = bool(TOML_CALLCONV*)(void*, T);
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ using parse_path_callback = bool(TOML_CALLCONV*)(void*, T);
- TOML_NODISCARD
- bool TOML_CALLCONV parse_path(std::string_view,
- void*,
- parse_path_callback<std::string_view>,
- parse_path_callback<size_t>);
+ TOML_NODISCARD
+ bool TOML_CALLCONV parse_path(std::string_view, void*, parse_path_callback<std::string_view>,
+ parse_path_callback<size_t>);
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief Returns a view of the node matching a fully-qualified "TOML path".
- ///
- /// \detail \cpp
- /// auto config = toml::parse(R"(
- ///
- /// [foo]
- /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- ///
- /// )"sv);
- ///
- /// std::cout << toml::at_path(config, "foo.bar[2]") << "\n";
- /// std::cout << toml::at_path(config, "foo.bar[3][0]") << "\n";
- /// std::cout << toml::at_path(config, "foo.bar[4].kek") << "\n";
- /// \ecpp
- ///
- /// \out
- /// 2
- /// 3
- /// 4
- /// \eout
- ///
- ///
- /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
- /// \cpp
- /// toml::at_path(config, "foo.bar") // same as config["foo"]["bar"]
- /// toml::at_path(config, "foo. bar") // same as config["foo"][" bar"]
- /// toml::at_path(config, "foo..bar") // same as config["foo"][""]["bar"]
- /// toml::at_path(config, ".foo.bar") // same as config[""]["foo"]["bar"]
- /// \ecpp
- /// <br>
- /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
- /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
- /// If you have periods in your table keys, first consider:
- /// 1. Not doing that
- /// 2. Using node_view::operator[] instead.
- ///
- /// \param root The root node from which the path will be traversed.
- /// \param path The "TOML path" to traverse.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<node> TOML_CALLCONV at_path(node & root, std::string_view path) noexcept;
+TOML_NAMESPACE_START {
+ /// \brief Returns a view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \detail \cpp
+ /// auto config = toml::parse(R"(
+ ///
+ /// [foo]
+ /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ ///
+ /// )"sv);
+ ///
+ /// std::cout << toml::at_path(config, "foo.bar[2]") << "\n";
+ /// std::cout << toml::at_path(config, "foo.bar[3][0]") << "\n";
+ /// std::cout << toml::at_path(config, "foo.bar[4].kek") << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 2
+ /// 3
+ /// 4
+ /// \eout
+ ///
+ ///
+ /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
+ /// \cpp
+ /// toml::at_path(config, "foo.bar") // same as config["foo"]["bar"]
+ /// toml::at_path(config, "foo. bar") // same as config["foo"][" bar"]
+ /// toml::at_path(config, "foo..bar") // same as config["foo"][""]["bar"]
+ /// toml::at_path(config, ".foo.bar") // same as config[""]["foo"]["bar"]
+ /// \ecpp
+ /// <br>
+ /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted
+ /// strings. This function makes no allowance for this, instead treating all period characters as
+ /// sub-table delimiters. If you have periods in your table keys, first consider:
+ /// 1. Not doing that
+ /// 2. Using node_view::operator[] instead.
+ ///
+ /// \param root The root node from which the path will be traversed.
+ /// \param path The "TOML path" to traverse.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<node> TOML_CALLCONV at_path(node & root, std::string_view path) noexcept;
- /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
- ///
- /// \see #toml::at_path(node&, std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<const node> TOML_CALLCONV at_path(const node& root, std::string_view path) noexcept;
+ /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::at_path(node&, std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<const node> TOML_CALLCONV at_path(const node& root, std::string_view path) noexcept;
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns a view of the node matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #toml::at_path(node&, std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<node> TOML_CALLCONV at_path(node & root, std::wstring_view path);
+ /// \brief Returns a view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #toml::at_path(node&, std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<node> TOML_CALLCONV at_path(node & root, std::wstring_view path);
- /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #toml::at_path(node&, std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<const node> TOML_CALLCONV at_path(const node& root, std::wstring_view path);
+ /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #toml::at_path(node&, std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<const node> TOML_CALLCONV at_path(const node& root, std::wstring_view path);
#endif
}
diff --git a/vendor/toml++/impl/date_time.hpp b/vendor/toml++/impl/date_time.hpp
index 8957ad3..92acfbf 100644
--- a/vendor/toml++/impl/date_time.hpp
+++ b/vendor/toml++/impl/date_time.hpp
@@ -1,467 +1,417 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "forward_declarations.hpp"
-#include "print_to_stream.hpp"
#include "header_start.hpp"
+#include "print_to_stream.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A local date.
- struct TOML_TRIVIAL_ABI date
- {
- /// \brief The year component.
- uint16_t year;
-
- /// \brief The month component, from 1 - 12.
- uint8_t month;
-
- /// \brief The day component, from 1 - 31.
- uint8_t day;
-
- /// \brief Default constructor. Does not initialize the members.
- TOML_NODISCARD_CTOR
- date() noexcept = default;
-
- /// \brief Constructs a date from individual date component values.
- TOML_CONSTRAINED_TEMPLATE((impl::all_integral<Y, M, D>), typename Y, typename M, typename D)
- TOML_NODISCARD_CTOR
- constexpr date(Y y, M m, D d) noexcept //
- : year{ static_cast<uint16_t>(y) },
- month{ static_cast<uint8_t>(m) },
- day{ static_cast<uint8_t>(d) }
- {}
-
- /// \brief Equality operator.
- TOML_PURE_GETTER
- friend constexpr bool operator==(const date& lhs, const date& rhs) noexcept
- {
- return lhs.year == rhs.year //
- && lhs.month == rhs.month //
- && lhs.day == rhs.day;
- }
-
- /// \brief Inequality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator!=(const date& lhs, const date& rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- private:
- /// \cond
-
- TOML_PURE_GETTER
- static constexpr uint32_t pack(const date& d) noexcept
- {
- return (static_cast<uint32_t>(d.year) << 16) | (static_cast<uint32_t>(d.month) << 8)
- | static_cast<uint32_t>(d.day);
- }
-
- /// \endcond
-
- public:
- /// \brief Less-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<(const date& lhs, const date& rhs) noexcept
- {
- return pack(lhs) < pack(rhs);
- }
-
- /// \brief Less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<=(const date& lhs, const date& rhs) noexcept
- {
- return pack(lhs) <= pack(rhs);
- }
-
- /// \brief Greater-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>(const date& lhs, const date& rhs) noexcept
- {
- return pack(lhs) > pack(rhs);
- }
-
- /// \brief Greater-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>=(const date& lhs, const date& rhs) noexcept
- {
- return pack(lhs) >= pack(rhs);
- }
-
- /// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
- ///
- /// \detail \cpp
- /// std::cout << toml::date{ 1987, 3, 16 } << "\n";
- /// \ecpp
- ///
- /// \out
- /// 1987-03-16
- /// \eout
- friend std::ostream& operator<<(std::ostream& lhs, const date& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
-
- /// \brief A local time-of-day.
- struct TOML_TRIVIAL_ABI time
- {
- /// \brief The hour component, from 0 - 23.
- uint8_t hour;
-
- /// \brief The minute component, from 0 - 59.
- uint8_t minute;
-
- /// \brief The second component, from 0 - 59.
- uint8_t second;
-
- /// \brief The fractional nanoseconds component, from 0 - 999999999.
- uint32_t nanosecond;
-
- /// \brief Default constructor. Does not initialize the members.
- TOML_NODISCARD_CTOR
- time() noexcept = default;
-
- /// \brief Constructs a time from individual time component values.
- TOML_CONSTRAINED_TEMPLATE((impl::all_integral<H, M, S, NS>),
- typename H,
- typename M,
- typename S = uint8_t,
- typename NS = uint32_t)
- TOML_NODISCARD_CTOR
- constexpr time(H h, M m, S s = S{}, NS ns = NS{}) noexcept //
- : hour{ static_cast<uint8_t>(h) },
- minute{ static_cast<uint8_t>(m) },
- second{ static_cast<uint8_t>(s) },
- nanosecond{ static_cast<uint32_t>(ns) }
- {}
-
- /// \brief Equality operator.
- TOML_PURE_GETTER
- friend constexpr bool operator==(const time& lhs, const time& rhs) noexcept
- {
- return lhs.hour == rhs.hour //
- && lhs.minute == rhs.minute //
- && lhs.second == rhs.second //
- && lhs.nanosecond == rhs.nanosecond;
- }
-
- /// \brief Inequality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator!=(const time& lhs, const time& rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- private:
- /// \cond
-
- TOML_PURE_GETTER
- static constexpr uint64_t pack(const time& t) noexcept
- {
- return static_cast<uint64_t>(t.hour) << 48 | static_cast<uint64_t>(t.minute) << 40
- | static_cast<uint64_t>(t.second) << 32 | static_cast<uint64_t>(t.nanosecond);
- }
-
- /// \endcond
-
- public:
- /// \brief Less-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<(const time& lhs, const time& rhs) noexcept
- {
- return pack(lhs) < pack(rhs);
- }
-
- /// \brief Less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<=(const time& lhs, const time& rhs) noexcept
- {
- return pack(lhs) <= pack(rhs);
- }
-
- /// \brief Greater-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>(const time& lhs, const time& rhs) noexcept
- {
- return pack(lhs) > pack(rhs);
- }
-
- /// \brief Greater-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>=(const time& lhs, const time& rhs) noexcept
- {
- return pack(lhs) >= pack(rhs);
- }
-
- /// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
- /// \detail \cpp
- /// std::cout << toml::time{ 10, 20, 34 } << "\n";
- /// std::cout << toml::time{ 10, 20, 34, 500000000 } << "\n";
- /// \ecpp
- ///
- /// \out
- /// 10:20:34
- /// 10:20:34.5
- /// \eout
- friend std::ostream& operator<<(std::ostream& lhs, const time& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
-
- /// \brief A timezone offset.
- struct TOML_TRIVIAL_ABI time_offset
- {
- /// \brief Offset from UTC+0, in minutes.
- int16_t minutes;
-
- /// \brief Default constructor. Does not initialize the members.
- TOML_NODISCARD_CTOR
- time_offset() noexcept = default;
-
- /// \brief Constructs a timezone offset from individual hour and minute totals.
- ///
- /// \detail \cpp
- /// std::cout << toml::time_offset{ 2, 30 } << "\n";
- /// std::cout << toml::time_offset{ -2, 30 } << "\n";
- /// std::cout << toml::time_offset{ -2, -30 } << "\n";
- /// std::cout << toml::time_offset{ 0, 0 } << "\n";
- /// \ecpp
- ///
- /// \out
- /// +02:30
- /// -01:30
- /// -02:30
- /// Z
- /// \eout
- ///
- /// \tparam H An integral type.
- /// \tparam M An integral type.
- ///
- /// \param h The total hours.
- /// \param m The total minutes.
- TOML_CONSTRAINED_TEMPLATE((impl::all_integral<H, M>), typename H, typename M)
- TOML_NODISCARD_CTOR
- constexpr time_offset(H h, M m) noexcept //
- : minutes{ static_cast<int16_t>(static_cast<impl::common_signed_type<H, M>>(h)
- * impl::common_signed_type<H, M>{ 60 }
- + static_cast<impl::common_signed_type<H, M>>(m)) }
- {}
-
- /// \brief Equality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator==(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes == rhs.minutes;
- }
-
- /// \brief Inequality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator!=(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes != rhs.minutes;
- }
-
- /// \brief Less-than operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator<(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes < rhs.minutes;
- }
-
- /// \brief Less-than-or-equal-to operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator<=(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes <= rhs.minutes;
- }
-
- /// \brief Greater-than operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator>(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes > rhs.minutes;
- }
-
- /// \brief Greater-than-or-equal-to operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator>=(time_offset lhs, time_offset rhs) noexcept
- {
- return lhs.minutes >= rhs.minutes;
- }
-
- /// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
- /// \detail \cpp
- /// std::cout << toml::time_offset{ 2, 30 } << "\n";
- /// std::cout << toml::time_offset{ 2, -30 } << "\n";
- /// std::cout << toml::time_offset{} << "\n";
- /// std::cout << toml::time_offset{ -2, 30 } << "\n";
- /// std::cout << toml::time_offset{ -2, -30 } << "\n";
- /// \ecpp
- ///
- /// \out
- /// +02:30
- /// +01:30
- /// Z
- /// -01:30
- /// -02:30
- /// \eout
- friend std::ostream& operator<<(std::ostream& lhs, const time_offset& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
-
- TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
-
- /// \brief A date-time.
- struct date_time
- {
- /// \brief The date component.
- toml::date date;
-
- /// \brief The time component.
- toml::time time;
-
- /// \brief The timezone offset component.
- ///
- /// \remarks The date_time is said to be 'local' if the offset is empty.
- optional<toml::time_offset> offset;
-
- /// \brief Default constructor. Does not initialize the members.
- TOML_NODISCARD_CTOR
- date_time() noexcept = default;
-
- /// \brief Constructs a local date-time.
- ///
- /// \param d The date component.
- /// \param t The time component.
- TOML_NODISCARD_CTOR
- constexpr date_time(const toml::date& d, const toml::time& t) noexcept //
- : date{ d },
- time{ t },
- offset{} // TINAE - icc bugfix
- {}
-
- /// \brief Constructs a local date-time.
- ///
- /// \param d The date component.
- TOML_NODISCARD_CTOR
- explicit constexpr date_time(const toml::date& d) noexcept //
- : date{ d },
- time{},
- offset{} // TINAE - icc bugfix
- {}
-
- /// \brief Constructs a local date-time.
- ///
- /// \param t The time component.
- TOML_NODISCARD_CTOR
- explicit constexpr date_time(const toml::time& t) noexcept //
- : date{},
- time{ t },
- offset{} // TINAE - icc bugfix
- {}
-
- /// \brief Constructs an offset date-time.
- ///
- /// \param d The date component.
- /// \param t The time component.
- /// \param off The timezone offset.
- TOML_NODISCARD_CTOR
- constexpr date_time(const toml::date& d, const toml::time& t, const toml::time_offset& off) noexcept
- : date{ d },
- time{ t },
- offset{ off }
- {}
-
- /// \brief Returns true if this date_time does not contain timezone offset information.
- TOML_PURE_INLINE_GETTER
- constexpr bool is_local() const noexcept
- {
- return !offset.has_value();
- }
-
- /// \brief Equality operator.
- TOML_PURE_GETTER
- friend constexpr bool operator==(const date_time& lhs, const date_time& rhs) noexcept
- {
- return lhs.date == rhs.date //
- && lhs.time == rhs.time //
- && lhs.offset == rhs.offset;
- }
-
- /// \brief Inequality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator!=(const date_time& lhs, const date_time& rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- /// \brief Less-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<(const date_time& lhs, const date_time& rhs) noexcept
- {
- if (lhs.date != rhs.date)
- return lhs.date < rhs.date;
- if (lhs.time != rhs.time)
- return lhs.time < rhs.time;
- return lhs.offset < rhs.offset;
- }
-
- /// \brief Less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<=(const date_time& lhs, const date_time& rhs) noexcept
- {
- if (lhs.date != rhs.date)
- return lhs.date < rhs.date;
- if (lhs.time != rhs.time)
- return lhs.time < rhs.time;
- return lhs.offset <= rhs.offset;
- }
-
- /// \brief Greater-than operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator>(const date_time& lhs, const date_time& rhs) noexcept
- {
- return !(lhs <= rhs);
- }
-
- /// \brief Greater-than-or-equal-to operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator>=(const date_time& lhs, const date_time& rhs) noexcept
- {
- return !(lhs < rhs);
- }
-
- /// \brief Prints a date_time out to a stream in RFC 3339 format.
- /// \detail \cpp
- /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << "\n";
- /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << "\n";
- /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << "\n";
- /// \ecpp
- ///
- /// \out
- /// 1987-03-16T10:20:34
- /// 1987-03-16T10:20:34-02:30
- /// 1987-03-16T10:20:34Z
- /// \eout
- friend std::ostream& operator<<(std::ostream& lhs, const date_time& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
-
- TOML_ABI_NAMESPACE_END; // TOML_HAS_CUSTOM_OPTIONAL_TYPE
+TOML_NAMESPACE_START {
+ /// \brief A local date.
+ struct TOML_TRIVIAL_ABI date {
+ /// \brief The year component.
+ uint16_t year;
+
+ /// \brief The month component, from 1 - 12.
+ uint8_t month;
+
+ /// \brief The day component, from 1 - 31.
+ uint8_t day;
+
+ /// \brief Default constructor. Does not initialize the members.
+ TOML_NODISCARD_CTOR
+ date() noexcept = default;
+
+ /// \brief Constructs a date from individual date component values.
+ TOML_CONSTRAINED_TEMPLATE((impl::all_integral<Y, M, D>), typename Y, typename M, typename D)
+ TOML_NODISCARD_CTOR
+ constexpr date(Y y, M m, D d) noexcept //
+ : year{static_cast<uint16_t>(y)},
+ month{static_cast<uint8_t>(m)},
+ day{static_cast<uint8_t>(d)} {}
+
+ /// \brief Equality operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator==(const date& lhs, const date& rhs) noexcept {
+ return lhs.year == rhs.year //
+ && lhs.month == rhs.month //
+ && lhs.day == rhs.day;
+ }
+
+ /// \brief Inequality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator!=(const date& lhs, const date& rhs) noexcept {
+ return !(lhs == rhs);
+ }
+
+ private:
+ /// \cond
+
+ TOML_PURE_GETTER
+ static constexpr uint32_t pack(const date& d) noexcept {
+ return (static_cast<uint32_t>(d.year) << 16) | (static_cast<uint32_t>(d.month) << 8) |
+ static_cast<uint32_t>(d.day);
+ }
+
+ /// \endcond
+
+ public:
+ /// \brief Less-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<(const date& lhs, const date& rhs) noexcept {
+ return pack(lhs) < pack(rhs);
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<=(const date& lhs, const date& rhs) noexcept {
+ return pack(lhs) <= pack(rhs);
+ }
+
+ /// \brief Greater-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>(const date& lhs, const date& rhs) noexcept {
+ return pack(lhs) > pack(rhs);
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>=(const date& lhs, const date& rhs) noexcept {
+ return pack(lhs) >= pack(rhs);
+ }
+
+ /// \brief Prints a date out to a stream as `YYYY-MM-DD` (per RFC 3339).
+ ///
+ /// \detail \cpp
+ /// std::cout << toml::date{ 1987, 3, 16 } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 1987-03-16
+ /// \eout
+ friend std::ostream& operator<<(std::ostream& lhs, const date& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
+
+ /// \brief A local time-of-day.
+ struct TOML_TRIVIAL_ABI time {
+ /// \brief The hour component, from 0 - 23.
+ uint8_t hour;
+
+ /// \brief The minute component, from 0 - 59.
+ uint8_t minute;
+
+ /// \brief The second component, from 0 - 59.
+ uint8_t second;
+
+ /// \brief The fractional nanoseconds component, from 0 - 999999999.
+ uint32_t nanosecond;
+
+ /// \brief Default constructor. Does not initialize the members.
+ TOML_NODISCARD_CTOR
+ time() noexcept = default;
+
+ /// \brief Constructs a time from individual time component values.
+ TOML_CONSTRAINED_TEMPLATE((impl::all_integral<H, M, S, NS>), typename H, typename M,
+ typename S = uint8_t, typename NS = uint32_t)
+ TOML_NODISCARD_CTOR
+ constexpr time(H h, M m, S s = S{}, NS ns = NS{}) noexcept //
+ : hour{static_cast<uint8_t>(h)},
+ minute{static_cast<uint8_t>(m)},
+ second{static_cast<uint8_t>(s)},
+ nanosecond{static_cast<uint32_t>(ns)} {}
+
+ /// \brief Equality operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator==(const time& lhs, const time& rhs) noexcept {
+ return lhs.hour == rhs.hour //
+ && lhs.minute == rhs.minute //
+ && lhs.second == rhs.second //
+ && lhs.nanosecond == rhs.nanosecond;
+ }
+
+ /// \brief Inequality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator!=(const time& lhs, const time& rhs) noexcept {
+ return !(lhs == rhs);
+ }
+
+ private:
+ /// \cond
+
+ TOML_PURE_GETTER
+ static constexpr uint64_t pack(const time& t) noexcept {
+ return static_cast<uint64_t>(t.hour) << 48 | static_cast<uint64_t>(t.minute) << 40 |
+ static_cast<uint64_t>(t.second) << 32 | static_cast<uint64_t>(t.nanosecond);
+ }
+
+ /// \endcond
+
+ public:
+ /// \brief Less-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<(const time& lhs, const time& rhs) noexcept {
+ return pack(lhs) < pack(rhs);
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<=(const time& lhs, const time& rhs) noexcept {
+ return pack(lhs) <= pack(rhs);
+ }
+
+ /// \brief Greater-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>(const time& lhs, const time& rhs) noexcept {
+ return pack(lhs) > pack(rhs);
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>=(const time& lhs, const time& rhs) noexcept {
+ return pack(lhs) >= pack(rhs);
+ }
+
+ /// \brief Prints a time out to a stream as `HH:MM:SS.FFFFFF` (per RFC 3339).
+ /// \detail \cpp
+ /// std::cout << toml::time{ 10, 20, 34 } << "\n";
+ /// std::cout << toml::time{ 10, 20, 34, 500000000 } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 10:20:34
+ /// 10:20:34.5
+ /// \eout
+ friend std::ostream& operator<<(std::ostream& lhs, const time& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
+
+ /// \brief A timezone offset.
+ struct TOML_TRIVIAL_ABI time_offset {
+ /// \brief Offset from UTC+0, in minutes.
+ int16_t minutes;
+
+ /// \brief Default constructor. Does not initialize the members.
+ TOML_NODISCARD_CTOR
+ time_offset() noexcept = default;
+
+ /// \brief Constructs a timezone offset from individual hour and minute totals.
+ ///
+ /// \detail \cpp
+ /// std::cout << toml::time_offset{ 2, 30 } << "\n";
+ /// std::cout << toml::time_offset{ -2, 30 } << "\n";
+ /// std::cout << toml::time_offset{ -2, -30 } << "\n";
+ /// std::cout << toml::time_offset{ 0, 0 } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// +02:30
+ /// -01:30
+ /// -02:30
+ /// Z
+ /// \eout
+ ///
+ /// \tparam H An integral type.
+ /// \tparam M An integral type.
+ ///
+ /// \param h The total hours.
+ /// \param m The total minutes.
+ TOML_CONSTRAINED_TEMPLATE((impl::all_integral<H, M>), typename H, typename M)
+ TOML_NODISCARD_CTOR
+ constexpr time_offset(H h, M m) noexcept //
+ : minutes{static_cast<int16_t>(static_cast<impl::common_signed_type<H, M>>(h) *
+ impl::common_signed_type<H, M>{60} +
+ static_cast<impl::common_signed_type<H, M>>(m))} {}
+
+ /// \brief Equality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator==(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes == rhs.minutes;
+ }
+
+ /// \brief Inequality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator!=(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes != rhs.minutes;
+ }
+
+ /// \brief Less-than operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator<(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes < rhs.minutes;
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator<=(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes <= rhs.minutes;
+ }
+
+ /// \brief Greater-than operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator>(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes > rhs.minutes;
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator>=(time_offset lhs, time_offset rhs) noexcept {
+ return lhs.minutes >= rhs.minutes;
+ }
+
+ /// \brief Prints a time_offset out to a stream as `+-HH:MM or Z` (per RFC 3339).
+ /// \detail \cpp
+ /// std::cout << toml::time_offset{ 2, 30 } << "\n";
+ /// std::cout << toml::time_offset{ 2, -30 } << "\n";
+ /// std::cout << toml::time_offset{} << "\n";
+ /// std::cout << toml::time_offset{ -2, 30 } << "\n";
+ /// std::cout << toml::time_offset{ -2, -30 } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// +02:30
+ /// +01:30
+ /// Z
+ /// -01:30
+ /// -02:30
+ /// \eout
+ friend std::ostream& operator<<(std::ostream& lhs, const time_offset& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
+
+ TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
+
+ /// \brief A date-time.
+ struct date_time {
+ /// \brief The date component.
+ toml::date date;
+
+ /// \brief The time component.
+ toml::time time;
+
+ /// \brief The timezone offset component.
+ ///
+ /// \remarks The date_time is said to be 'local' if the offset is empty.
+ optional<toml::time_offset> offset;
+
+ /// \brief Default constructor. Does not initialize the members.
+ TOML_NODISCARD_CTOR
+ date_time() noexcept = default;
+
+ /// \brief Constructs a local date-time.
+ ///
+ /// \param d The date component.
+ /// \param t The time component.
+ TOML_NODISCARD_CTOR
+ constexpr date_time(const toml::date& d, const toml::time& t) noexcept //
+ : date{d},
+ time{t},
+ offset{} // TINAE - icc bugfix
+ {}
+
+ /// \brief Constructs a local date-time.
+ ///
+ /// \param d The date component.
+ TOML_NODISCARD_CTOR
+ explicit constexpr date_time(const toml::date& d) noexcept //
+ : date{d},
+ time{},
+ offset{} // TINAE - icc bugfix
+ {}
+
+ /// \brief Constructs a local date-time.
+ ///
+ /// \param t The time component.
+ TOML_NODISCARD_CTOR
+ explicit constexpr date_time(const toml::time& t) noexcept //
+ : date{},
+ time{t},
+ offset{} // TINAE - icc bugfix
+ {}
+
+ /// \brief Constructs an offset date-time.
+ ///
+ /// \param d The date component.
+ /// \param t The time component.
+ /// \param off The timezone offset.
+ TOML_NODISCARD_CTOR
+ constexpr date_time(const toml::date& d, const toml::time& t,
+ const toml::time_offset& off) noexcept
+ : date{d}, time{t}, offset{off} {}
+
+ /// \brief Returns true if this date_time does not contain timezone offset information.
+ TOML_PURE_INLINE_GETTER
+ constexpr bool is_local() const noexcept { return !offset.has_value(); }
+
+ /// \brief Equality operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator==(const date_time& lhs, const date_time& rhs) noexcept {
+ return lhs.date == rhs.date //
+ && lhs.time == rhs.time //
+ && lhs.offset == rhs.offset;
+ }
+
+ /// \brief Inequality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator!=(const date_time& lhs, const date_time& rhs) noexcept {
+ return !(lhs == rhs);
+ }
+
+ /// \brief Less-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<(const date_time& lhs, const date_time& rhs) noexcept {
+ if (lhs.date != rhs.date) return lhs.date < rhs.date;
+ if (lhs.time != rhs.time) return lhs.time < rhs.time;
+ return lhs.offset < rhs.offset;
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<=(const date_time& lhs, const date_time& rhs) noexcept {
+ if (lhs.date != rhs.date) return lhs.date < rhs.date;
+ if (lhs.time != rhs.time) return lhs.time < rhs.time;
+ return lhs.offset <= rhs.offset;
+ }
+
+ /// \brief Greater-than operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator>(const date_time& lhs, const date_time& rhs) noexcept {
+ return !(lhs <= rhs);
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator>=(const date_time& lhs, const date_time& rhs) noexcept {
+ return !(lhs < rhs);
+ }
+
+ /// \brief Prints a date_time out to a stream in RFC 3339 format.
+ /// \detail \cpp
+ /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 } } << "\n";
+ /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, { -2, -30 } } << "\n";
+ /// std::cout << toml::date_time{ { 1987, 3, 16 }, { 10, 20, 34 }, {} } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 1987-03-16T10:20:34
+ /// 1987-03-16T10:20:34-02:30
+ /// 1987-03-16T10:20:34Z
+ /// \eout
+ friend std::ostream& operator<<(std::ostream& lhs, const date_time& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
+
+ TOML_ABI_NAMESPACE_END; // TOML_HAS_CUSTOM_OPTIONAL_TYPE
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/formatter.hpp b/vendor/toml++/impl/formatter.hpp
index 0c97833..ba3a349 100644
--- a/vendor/toml++/impl/formatter.hpp
+++ b/vendor/toml++/impl/formatter.hpp
@@ -1,194 +1,161 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_ENABLE_FORMATTERS
#include "forward_declarations.hpp"
-#include "print_to_stream.hpp"
#include "header_start.hpp"
+#include "print_to_stream.hpp"
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- struct formatter_constants
- {
- format_flags mandatory_flags;
- format_flags ignored_flags;
-
- std::string_view float_pos_inf;
- std::string_view float_neg_inf;
- std::string_view float_nan;
-
- std::string_view bool_true;
- std::string_view bool_false;
- };
-
- struct formatter_config
- {
- format_flags flags;
- std::string_view indent;
- };
-
- class TOML_EXPORTED_CLASS formatter
- {
- private:
- const node* source_;
+TOML_IMPL_NAMESPACE_START {
+ struct formatter_constants {
+ format_flags mandatory_flags;
+ format_flags ignored_flags;
+
+ std::string_view float_pos_inf;
+ std::string_view float_neg_inf;
+ std::string_view float_nan;
+
+ std::string_view bool_true;
+ std::string_view bool_false;
+ };
+
+ struct formatter_config {
+ format_flags flags;
+ std::string_view indent;
+ };
+
+ class TOML_EXPORTED_CLASS formatter {
+ private:
+ const node* source_;
#if TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
- const parse_result* result_;
+ const parse_result* result_;
#endif
- const formatter_constants* constants_;
- formatter_config config_;
- size_t indent_columns_;
- format_flags int_format_mask_;
- std::ostream* stream_; //
- int indent_; // these are set in attach()
- bool naked_newline_; //
-
- protected:
- TOML_PURE_INLINE_GETTER
- const node& source() const noexcept
- {
- return *source_;
- }
-
- TOML_PURE_INLINE_GETTER
- std::ostream& stream() const noexcept
- {
- return *stream_;
- }
-
- TOML_PURE_INLINE_GETTER
- int indent() const noexcept
- {
- return indent_;
- }
-
- void indent(int level) noexcept
- {
- indent_ = level;
- }
-
- void increase_indent() noexcept
- {
- indent_++;
- }
-
- void decrease_indent() noexcept
- {
- indent_--;
- }
-
- TOML_PURE_INLINE_GETTER
- size_t indent_columns() const noexcept
- {
- return indent_columns_;
- }
-
- TOML_PURE_INLINE_GETTER
- bool indent_array_elements() const noexcept
- {
- return !!(config_.flags & format_flags::indent_array_elements);
- }
-
- TOML_PURE_INLINE_GETTER
- bool indent_sub_tables() const noexcept
- {
- return !!(config_.flags & format_flags::indent_sub_tables);
- }
-
- TOML_PURE_INLINE_GETTER
- bool literal_strings_allowed() const noexcept
- {
- return !!(config_.flags & format_flags::allow_literal_strings);
- }
-
- TOML_PURE_INLINE_GETTER
- bool multi_line_strings_allowed() const noexcept
- {
- return !!(config_.flags & format_flags::allow_multi_line_strings);
- }
-
- TOML_PURE_INLINE_GETTER
- bool real_tabs_in_strings_allowed() const noexcept
- {
- return !!(config_.flags & format_flags::allow_real_tabs_in_strings);
- }
-
- TOML_PURE_INLINE_GETTER
- bool unicode_strings_allowed() const noexcept
- {
- return !!(config_.flags & format_flags::allow_unicode_strings);
- }
-
- TOML_PURE_INLINE_GETTER
- bool terse_kvps() const noexcept
- {
- return !!(config_.flags & format_flags::terse_key_value_pairs);
- }
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void attach(std::ostream& stream) noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void detach() noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_newline(bool force = false);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_indent();
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_unformatted(char);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_unformatted(std::string_view);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_string(std::string_view str,
- bool allow_multi_line = true,
- bool allow_bare = false,
- bool allow_literal_whitespace = true);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<std::string>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<int64_t>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<double>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<bool>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<date>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<time>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const value<date_time>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_value(const node&, node_type);
-
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- bool dump_failed_parse_result();
-
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- formatter(const node*, const parse_result*, const formatter_constants&, const formatter_config&) noexcept;
- };
+ const formatter_constants* constants_;
+ formatter_config config_;
+ size_t indent_columns_;
+ format_flags int_format_mask_;
+ std::ostream* stream_; //
+ int indent_; // these are set in attach()
+ bool naked_newline_; //
+
+ protected:
+ TOML_PURE_INLINE_GETTER
+ const node& source() const noexcept { return *source_; }
+
+ TOML_PURE_INLINE_GETTER
+ std::ostream& stream() const noexcept { return *stream_; }
+
+ TOML_PURE_INLINE_GETTER
+ int indent() const noexcept { return indent_; }
+
+ void indent(int level) noexcept { indent_ = level; }
+
+ void increase_indent() noexcept { indent_++; }
+
+ void decrease_indent() noexcept { indent_--; }
+
+ TOML_PURE_INLINE_GETTER
+ size_t indent_columns() const noexcept { return indent_columns_; }
+
+ TOML_PURE_INLINE_GETTER
+ bool indent_array_elements() const noexcept {
+ return !!(config_.flags & format_flags::indent_array_elements);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool indent_sub_tables() const noexcept {
+ return !!(config_.flags & format_flags::indent_sub_tables);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool literal_strings_allowed() const noexcept {
+ return !!(config_.flags & format_flags::allow_literal_strings);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool multi_line_strings_allowed() const noexcept {
+ return !!(config_.flags & format_flags::allow_multi_line_strings);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool real_tabs_in_strings_allowed() const noexcept {
+ return !!(config_.flags & format_flags::allow_real_tabs_in_strings);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool unicode_strings_allowed() const noexcept {
+ return !!(config_.flags & format_flags::allow_unicode_strings);
+ }
+
+ TOML_PURE_INLINE_GETTER
+ bool terse_kvps() const noexcept {
+ return !!(config_.flags & format_flags::terse_key_value_pairs);
+ }
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void attach(std::ostream& stream) noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void detach() noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_newline(bool force = false);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_indent();
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_unformatted(char);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_unformatted(std::string_view);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_string(std::string_view str, bool allow_multi_line = true, bool allow_bare = false,
+ bool allow_literal_whitespace = true);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<std::string>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<int64_t>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<double>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<bool>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<date>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<time>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const value<date_time>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_value(const node&, node_type);
+
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool dump_failed_parse_result();
+
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ formatter(const node*, const parse_result*, const formatter_constants&,
+ const formatter_config&) noexcept;
+ };
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
#include "header_end.hpp"
-#endif // TOML_ENABLE_FORMATTERS
+#endif // TOML_ENABLE_FORMATTERS
diff --git a/vendor/toml++/impl/forward_declarations.hpp b/vendor/toml++/impl/forward_declarations.hpp
index 386a9e0..b755855 100644
--- a/vendor/toml++/impl/forward_declarations.hpp
+++ b/vendor/toml++/impl/forward_declarations.hpp
@@ -1,38 +1,43 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_string.hpp"
#include "std_new.hpp"
+#include "std_string.hpp"
TOML_DISABLE_WARNINGS;
-#include <cstdint>
-#include <cstddef>
-#include <cstring>
#include <cfloat>
#include <climits>
#include <cmath>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <iosfwd>
#include <limits>
#include <memory>
-#include <iosfwd>
#include <type_traits>
TOML_ENABLE_WARNINGS;
#include "header_start.hpp"
-//#---------------------------------------------------------------------------------------------------------------------
-//# ENVIRONMENT GROUND-TRUTHS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # ENVIRONMENT GROUND-TRUTHS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
#ifndef TOML_DISABLE_ENVIRONMENT_CHECKS
-#define TOML_ENV_MESSAGE \
- "If you're seeing this error it's because you're building toml++ for an environment that doesn't conform to " \
- "one of the 'ground truths' assumed by the library. Essentially this just means that I don't have the " \
- "resources to test on more platforms, but I wish I did! You can try disabling the checks by defining " \
- "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue at " \
- "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target environment. " \
- "Thanks!"
+#define TOML_ENV_MESSAGE \
+ "If you're seeing this error it's because you're building toml++ for an environment that " \
+ "doesn't conform to " \
+ "one of the 'ground truths' assumed by the library. Essentially this just means that I don't " \
+ "have the " \
+ "resources to test on more platforms, but I wish I did! You can try disabling the checks by " \
+ "defining " \
+ "TOML_DISABLE_ENVIRONMENT_CHECKS, but your mileage may vary. Please consider filing an issue " \
+ "at " \
+ "https://github.com/marzer/tomlplusplus/issues to help me improve support for your target " \
+ "environment. " \
+ "Thanks!"
static_assert(CHAR_BIT == 8, TOML_ENV_MESSAGE);
#ifdef FLT_RADIX
@@ -46,83 +51,81 @@ static_assert(std::numeric_limits<double>::digits10 == 15, TOML_ENV_MESSAGE);
static_assert(std::numeric_limits<double>::radix == 2, TOML_ENV_MESSAGE);
#undef TOML_ENV_MESSAGE
-#endif // !TOML_DISABLE_ENVIRONMENT_CHECKS
+#endif // !TOML_DISABLE_ENVIRONMENT_CHECKS
/// \endcond
-//#---------------------------------------------------------------------------------------------------------------------
-//# UNDOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # UNDOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
// undocumented forward declarations are hidden from doxygen because they fuck it up =/
-namespace toml // non-abi namespace; this is not an error
-{
- using ::std::size_t;
- using ::std::intptr_t;
- using ::std::uintptr_t;
- using ::std::ptrdiff_t;
- using ::std::nullptr_t;
- using ::std::int8_t;
- using ::std::int16_t;
- using ::std::int32_t;
- using ::std::int64_t;
- using ::std::uint8_t;
- using ::std::uint16_t;
- using ::std::uint32_t;
- using ::std::uint64_t;
- using ::std::uint_least32_t;
- using ::std::uint_least64_t;
-}
-
-TOML_NAMESPACE_START
+namespace toml // non-abi namespace; this is not an error
{
- struct date;
- struct time;
- struct time_offset;
-
- TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
- struct date_time;
- TOML_ABI_NAMESPACE_END;
-
- struct source_position;
- struct source_region;
-
- class node;
- template <typename>
- class node_view;
-
- class key;
- class array;
- class table;
- template <typename>
- class value;
-
- class path;
-
- class toml_formatter;
- class json_formatter;
- class yaml_formatter;
-
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
+using ::std::int16_t;
+using ::std::int32_t;
+using ::std::int64_t;
+using ::std::int8_t;
+using ::std::intptr_t;
+using ::std::nullptr_t;
+using ::std::ptrdiff_t;
+using ::std::size_t;
+using ::std::uint16_t;
+using ::std::uint32_t;
+using ::std::uint64_t;
+using ::std::uint8_t;
+using ::std::uint_least32_t;
+using ::std::uint_least64_t;
+using ::std::uintptr_t;
+} // namespace toml
+
+TOML_NAMESPACE_START {
+ struct date;
+ struct time;
+ struct time_offset;
+
+ TOML_ABI_NAMESPACE_BOOL(TOML_HAS_CUSTOM_OPTIONAL_TYPE, custopt, stdopt);
+ struct date_time;
+ TOML_ABI_NAMESPACE_END;
+
+ struct source_position;
+ struct source_region;
+
+ class node;
+ template <typename>
+ class node_view;
+
+ class key;
+ class array;
+ class table;
+ template <typename>
+ class value;
+
+ class path;
+
+ class toml_formatter;
+ class json_formatter;
+ class yaml_formatter;
+
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
#if TOML_EXCEPTIONS
- using parse_result = table;
+ using parse_result = table;
#else
- class parse_result;
+ class parse_result;
#endif
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
}
TOML_NAMESPACE_END;
-TOML_IMPL_NAMESPACE_START
-{
- using node_ptr = std::unique_ptr<node>;
+TOML_IMPL_NAMESPACE_START {
+ using node_ptr = std::unique_ptr<node>;
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex);
- class parser;
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, impl_ex, impl_noex);
+ class parser;
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
- // clang-format off
+ // clang-format off
inline constexpr std::string_view control_char_escapes[] =
{
@@ -174,7 +177,7 @@ TOML_IMPL_NAMESPACE_START
"date-time"sv
};
- // clang-format on
+ // clang-format on
}
TOML_IMPL_NAMESPACE_END;
@@ -190,906 +193,819 @@ TOML_IMPL_NAMESPACE_END;
/// \endcond
-//#---------------------------------------------------------------------------------------------------------------------
-//# DOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # DOCUMENTED TYPEDEFS AND FORWARD DECLARATIONS
+// #---------------------------------------------------------------------------------------------------------------------
/// \brief The root namespace for all toml++ functions and types.
-namespace toml
-{
-}
+namespace toml {}
-TOML_NAMESPACE_START // abi namespace
+TOML_NAMESPACE_START // abi namespace
{
- /// \brief Convenience literal operators for working with toml++.
- ///
- /// \detail This namespace exists so you can safely hoist the toml++ literal operators into another scope
- /// without dragging in everything from the toml namespace: \cpp
- ///
- /// #include <toml++/toml.hpp>
- /// using namespace toml::literals;
- ///
- /// int main()
- /// {
- /// toml::table tbl = "vals = [1, 2, 3]"_toml;
- ///
- /// // ... do stuff with the table generated by the "_toml" literal ...
- ///
- /// return 0;
- /// }
- /// \ecpp
- ///
- inline namespace literals
- {
- }
-
- /// \brief TOML node type identifiers.
- enum class TOML_CLOSED_ENUM node_type : uint8_t
- {
- none, ///< Not-a-node.
- table, ///< The node is a toml::table.
- array, ///< The node is a toml::array.
- string, ///< The node is a toml::value<std::string>.
- integer, ///< The node is a toml::value<int64_t>.
- floating_point, ///< The node is a toml::value<double>.
- boolean, ///< The node is a toml::value<bool>.
- date, ///< The node is a toml::value<date>.
- time, ///< The node is a toml::value<time>.
- date_time ///< The node is a toml::value<date_time>.
- };
-
- /// \brief Pretty-prints the value of a node_type to a stream.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2.0, "3", false };
- /// for (size_t i = 0; i < arr.size() i++)
- /// std::cout << "Element ["sv << i << "] is: "sv << arr[i].type() << "\n";
- /// \ecpp
- ///
- /// \out
- /// Element [0] is: integer
- /// Element [1] is: floating-point
- /// Element [2] is: string
- /// Element [3] is: boolean
- /// \eout
- template <typename Char>
- inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, node_type rhs)
- {
- const auto str = impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(rhs)];
- using str_char_t = decltype(str)::value_type;
- if constexpr (std::is_same_v<Char, str_char_t>)
- return lhs << str;
- else
- {
- if constexpr (sizeof(Char) == sizeof(str_char_t))
- return lhs << std::basic_string_view<Char>{ reinterpret_cast<const Char*>(str.data()), str.length() };
- else
- return lhs << str.data();
- }
- }
-
- /// \brief Metadata associated with TOML values.
- enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error
- {
- /// \brief None.
- none,
-
- /// \brief Format integer values as binary.
- format_as_binary = 1,
-
- /// \brief Format integer values as octal.
- format_as_octal = 2,
-
- /// \brief Format integer values as hexadecimal.
- format_as_hexadecimal = 3,
- };
- TOML_MAKE_FLAGS(value_flags);
-
- /// \brief Special #toml::value_flags constant used for array + table insert functions to specify that any value
- /// nodes being copied should not have their flags property overridden by the inserting function's `flags` argument.
- inline constexpr value_flags preserve_source_value_flags =
- POXY_IMPLEMENTATION_DETAIL(value_flags{ static_cast<std::underlying_type_t<value_flags>>(-1) });
-
- /// \brief Format flags for modifying how TOML data is printed to streams.
- ///
- /// \note Formatters may disregard/override any of these flags according to the requirements of their
- /// output target (e.g. #toml::json_formatter will always apply quotes to dates and times).
- enum class TOML_CLOSED_FLAGS_ENUM format_flags : uint64_t
- {
- /// \brief None.
- none,
-
- /// \brief Dates and times will be emitted as quoted strings.
- quote_dates_and_times = (1ull << 0),
-
- /// \brief Infinities and NaNs will be emitted as quoted strings.
- quote_infinities_and_nans = (1ull << 1),
-
- /// \brief Strings will be emitted as single-quoted literal strings where possible.
- allow_literal_strings = (1ull << 2),
-
- /// \brief Strings containing newlines will be emitted as triple-quoted 'multi-line' strings where possible.
- allow_multi_line_strings = (1ull << 3),
-
- /// \brief Allow real tab characters in string literals (as opposed to the escaped form `\t`).
- allow_real_tabs_in_strings = (1ull << 4),
-
- /// \brief Allow non-ASCII characters in strings (as opposed to their escaped form, e.g. `\u00DA`).
- allow_unicode_strings = (1ull << 5),
-
- /// \brief Allow integers with #value_flags::format_as_binary to be emitted as binary.
- allow_binary_integers = (1ull << 6),
-
- /// \brief Allow integers with #value_flags::format_as_octal to be emitted as octal.
- allow_octal_integers = (1ull << 7),
-
- /// \brief Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal.
- allow_hexadecimal_integers = (1ull << 8),
-
- /// \brief Apply indentation to tables nested within other tables/arrays.
- indent_sub_tables = (1ull << 9),
-
- /// \brief Apply indentation to array elements when the array is forced to wrap over multiple lines.
- indent_array_elements = (1ull << 10),
-
- /// \brief Combination mask of all indentation-enabling flags.
- indentation = indent_sub_tables | indent_array_elements,
-
- /// \brief Emit floating-point values with relaxed (human-friendly) precision.
- /// \warning Setting this flag may cause serialized documents to no longer round-trip correctly
- /// since floats might have a less precise value upon being written out than they did when being
- /// read in. Use this flag at your own risk.
- relaxed_float_precision = (1ull << 11),
-
- /// \brief Avoids the use of whitespace around key-value pairs.
- terse_key_value_pairs = (1ull << 12),
- };
- TOML_MAKE_FLAGS(format_flags);
-
- /// \brief Helper class for suppressing move-construction in single-argument array constructors.
- ///
- /// \detail \cpp
- /// // desired result: [ [ 42 ] ]
- /// auto bad = toml::array{ toml::array{ 42 } };
- /// auto good = toml::array{ toml::inserter{ toml::array{ 42 } } };
- /// std::cout << "bad: " << bad << "\n";
- /// std::cout << "good:" << good << "\n";
- /// \ecpp
- /// \out
- /// bad: [ 42 ]
- /// good: [ [ 42 ] ]
- /// \eout
- ///
- /// \see toml::array
- template <typename T>
- struct TOML_TRIVIAL_ABI inserter
- {
- static_assert(std::is_reference_v<T>);
-
- T value;
- };
- template <typename T>
- inserter(T&&) -> inserter<T&&>;
- template <typename T>
- inserter(T&) -> inserter<T&>;
-
- /// \brief The 'default' formatter used by TOML objects when they are printed to a stream.
- /// \detail This is an alias for #toml::toml_formatter.
- using default_formatter = toml_formatter;
+ /// \brief Convenience literal operators for working with toml++.
+ ///
+ /// \detail This namespace exists so you can safely hoist the toml++ literal operators into
+ /// another scope without dragging in everything from the toml namespace: \cpp
+ ///
+ /// #include <toml++/toml.hpp>
+ /// using namespace toml::literals;
+ ///
+ /// int main()
+ /// {
+ /// toml::table tbl = "vals = [1, 2, 3]"_toml;
+ ///
+ /// // ... do stuff with the table generated by the "_toml" literal ...
+ ///
+ /// return 0;
+ /// }
+ /// \ecpp
+ ///
+ inline namespace literals {}
+
+ /// \brief TOML node type identifiers.
+ enum class TOML_CLOSED_ENUM node_type : uint8_t {
+ none, ///< Not-a-node.
+ table, ///< The node is a toml::table.
+ array, ///< The node is a toml::array.
+ string, ///< The node is a toml::value<std::string>.
+ integer, ///< The node is a toml::value<int64_t>.
+ floating_point, ///< The node is a toml::value<double>.
+ boolean, ///< The node is a toml::value<bool>.
+ date, ///< The node is a toml::value<date>.
+ time, ///< The node is a toml::value<time>.
+ date_time ///< The node is a toml::value<date_time>.
+ };
+
+ /// \brief Pretty-prints the value of a node_type to a stream.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2.0, "3", false };
+ /// for (size_t i = 0; i < arr.size() i++)
+ /// std::cout << "Element ["sv << i << "] is: "sv << arr[i].type() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// Element [0] is: integer
+ /// Element [1] is: floating-point
+ /// Element [2] is: string
+ /// Element [3] is: boolean
+ /// \eout
+ template <typename Char>
+ inline std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& lhs, node_type rhs) {
+ const auto str =
+ impl::node_type_friendly_names[static_cast<std::underlying_type_t<node_type>>(rhs)];
+ using str_char_t = decltype(str)::value_type;
+ if constexpr (std::is_same_v<Char, str_char_t>)
+ return lhs << str;
+ else {
+ if constexpr (sizeof(Char) == sizeof(str_char_t))
+ return lhs << std::basic_string_view<Char>{reinterpret_cast<const Char*>(str.data()),
+ str.length()};
+ else
+ return lhs << str.data();
+ }
+ }
+
+ /// \brief Metadata associated with TOML values.
+ enum class TOML_OPEN_FLAGS_ENUM
+ value_flags : uint16_t // being an "OPEN" flags enum is not an error
+ {
+ /// \brief None.
+ none,
+
+ /// \brief Format integer values as binary.
+ format_as_binary = 1,
+
+ /// \brief Format integer values as octal.
+ format_as_octal = 2,
+
+ /// \brief Format integer values as hexadecimal.
+ format_as_hexadecimal = 3,
+ };
+ TOML_MAKE_FLAGS(value_flags);
+
+ /// \brief Special #toml::value_flags constant used for array + table insert functions to specify
+ /// that any value nodes being copied should not have their flags property overridden by the
+ /// inserting function's `flags` argument.
+ inline constexpr value_flags preserve_source_value_flags =
+ POXY_IMPLEMENTATION_DETAIL(value_flags{static_cast<std::underlying_type_t<value_flags>>(-1)});
+
+ /// \brief Format flags for modifying how TOML data is printed to streams.
+ ///
+ /// \note Formatters may disregard/override any of these flags according to the requirements of
+ /// their
+ /// output target (e.g. #toml::json_formatter will always apply quotes to dates and times).
+ enum class TOML_CLOSED_FLAGS_ENUM format_flags : uint64_t {
+ /// \brief None.
+ none,
+
+ /// \brief Dates and times will be emitted as quoted strings.
+ quote_dates_and_times = (1ull << 0),
+
+ /// \brief Infinities and NaNs will be emitted as quoted strings.
+ quote_infinities_and_nans = (1ull << 1),
+
+ /// \brief Strings will be emitted as single-quoted literal strings where possible.
+ allow_literal_strings = (1ull << 2),
+
+ /// \brief Strings containing newlines will be emitted as triple-quoted 'multi-line' strings
+ /// where possible.
+ allow_multi_line_strings = (1ull << 3),
+
+ /// \brief Allow real tab characters in string literals (as opposed to the escaped form `\t`).
+ allow_real_tabs_in_strings = (1ull << 4),
+
+ /// \brief Allow non-ASCII characters in strings (as opposed to their escaped form, e.g.
+ /// `\u00DA`).
+ allow_unicode_strings = (1ull << 5),
+
+ /// \brief Allow integers with #value_flags::format_as_binary to be emitted as binary.
+ allow_binary_integers = (1ull << 6),
+
+ /// \brief Allow integers with #value_flags::format_as_octal to be emitted as octal.
+ allow_octal_integers = (1ull << 7),
+
+ /// \brief Allow integers with #value_flags::format_as_hexadecimal to be emitted as hexadecimal.
+ allow_hexadecimal_integers = (1ull << 8),
+
+ /// \brief Apply indentation to tables nested within other tables/arrays.
+ indent_sub_tables = (1ull << 9),
+
+ /// \brief Apply indentation to array elements when the array is forced to wrap over multiple
+ /// lines.
+ indent_array_elements = (1ull << 10),
+
+ /// \brief Combination mask of all indentation-enabling flags.
+ indentation = indent_sub_tables | indent_array_elements,
+
+ /// \brief Emit floating-point values with relaxed (human-friendly) precision.
+ /// \warning Setting this flag may cause serialized documents to no longer round-trip correctly
+ /// since floats might have a less precise value upon being written out than they did when
+ ///being read in. Use this flag at your own risk.
+ relaxed_float_precision = (1ull << 11),
+
+ /// \brief Avoids the use of whitespace around key-value pairs.
+ terse_key_value_pairs = (1ull << 12),
+ };
+ TOML_MAKE_FLAGS(format_flags);
+
+ /// \brief Helper class for suppressing move-construction in single-argument array constructors.
+ ///
+ /// \detail \cpp
+ /// // desired result: [ [ 42 ] ]
+ /// auto bad = toml::array{ toml::array{ 42 } };
+ /// auto good = toml::array{ toml::inserter{ toml::array{ 42 } } };
+ /// std::cout << "bad: " << bad << "\n";
+ /// std::cout << "good:" << good << "\n";
+ /// \ecpp
+ /// \out
+ /// bad: [ 42 ]
+ /// good: [ [ 42 ] ]
+ /// \eout
+ ///
+ /// \see toml::array
+ template <typename T>
+ struct TOML_TRIVIAL_ABI inserter {
+ static_assert(std::is_reference_v<T>);
+
+ T value;
+ };
+ template <typename T>
+ inserter(T&&) -> inserter<T&&>;
+ template <typename T>
+ inserter(T&) -> inserter<T&>;
+
+ /// \brief The 'default' formatter used by TOML objects when they are printed to a stream.
+ /// \detail This is an alias for #toml::toml_formatter.
+ using default_formatter = toml_formatter;
}
TOML_NAMESPACE_END;
-//#---------------------------------------------------------------------------------------------------------------------
-//# METAFUNCTIONS & TYPE TRAITS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # METAFUNCTIONS & TYPE TRAITS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ using remove_cvref = std::remove_cv_t<std::remove_reference_t<T>>;
- template <typename... T>
- using common_signed_type = std::common_type_t<std::make_signed_t<T>...>;
+ template <typename... T>
+ using common_signed_type = std::common_type_t<std::make_signed_t<T>...>;
- template <typename T, typename... U>
- inline constexpr bool is_one_of = (false || ... || std::is_same_v<T, U>);
+ template <typename T, typename... U>
+ inline constexpr bool is_one_of = (false || ... || std::is_same_v<T, U>);
- template <typename... T>
- inline constexpr bool all_integral = (std::is_integral_v<T> && ...);
+ template <typename... T>
+ inline constexpr bool all_integral = (std::is_integral_v<T> && ...);
- template <typename T>
- inline constexpr bool is_cvref = std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
+ template <typename T>
+ inline constexpr bool is_cvref =
+ std::is_reference_v<T> || std::is_const_v<T> || std::is_volatile_v<T>;
- template <typename T>
- inline constexpr bool is_wide_string =
- is_one_of<std::decay_t<T>, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>;
+ template <typename T>
+ inline constexpr bool is_wide_string =
+ is_one_of<std::decay_t<T>, const wchar_t*, wchar_t*, std::wstring_view, std::wstring>;
- template <typename T>
- inline constexpr bool value_retrieval_is_nothrow = !std::is_same_v<remove_cvref<T>, std::string>
+ template <typename T>
+ inline constexpr bool value_retrieval_is_nothrow =
+ !std::is_same_v<remove_cvref<T>, std::string>
#if TOML_HAS_CHAR8
- && !std::is_same_v<remove_cvref<T>, std::u8string>
+ && !std::is_same_v<remove_cvref<T>, std::u8string>
#endif
- && !is_wide_string<T>;
-
- template <typename, typename>
- struct copy_ref_;
- template <typename Dest, typename Src>
- using copy_ref = typename copy_ref_<Dest, Src>::type;
-
- template <typename Dest, typename Src>
- struct copy_ref_
- {
- using type = Dest;
- };
-
- template <typename Dest, typename Src>
- struct copy_ref_<Dest, Src&>
- {
- using type = std::add_lvalue_reference_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_ref_<Dest, Src&&>
- {
- using type = std::add_rvalue_reference_t<Dest>;
- };
-
- template <typename, typename>
- struct copy_cv_;
- template <typename Dest, typename Src>
- using copy_cv = typename copy_cv_<Dest, Src>::type;
-
- template <typename Dest, typename Src>
- struct copy_cv_
- {
- using type = Dest;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, const Src>
- {
- using type = std::add_const_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, volatile Src>
- {
- using type = std::add_volatile_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- struct copy_cv_<Dest, const volatile Src>
- {
- using type = std::add_cv_t<Dest>;
- };
-
- template <typename Dest, typename Src>
- using copy_cvref =
- copy_ref<copy_ref<copy_cv<std::remove_reference_t<Dest>, std::remove_reference_t<Src>>, Dest>, Src>;
-
- template <typename...>
- inline constexpr bool always_false = false;
-
- template <typename T, typename... U>
- inline constexpr bool first_is_same = false;
- template <typename T, typename... U>
- inline constexpr bool first_is_same<T, T, U...> = true;
-
- template <typename T, bool = std::is_enum_v<T>>
- struct underlying_type_
- {
- using type = std::underlying_type_t<T>;
- };
- template <typename T>
- struct underlying_type_<T, false>
- {
- using type = T;
- };
- template <typename T>
- using underlying_type = typename underlying_type_<T>::type;
-
- // general value traits
- // (as they relate to their equivalent native TOML type)
- struct default_value_traits
- {
- using native_type = void;
- static constexpr bool is_native = false;
- static constexpr bool is_losslessly_convertible_to_native = false;
- static constexpr bool can_represent_native = false;
- static constexpr bool can_partially_represent_native = false;
- static constexpr auto type = node_type::none;
- };
-
- template <typename T>
- struct value_traits;
-
- template <typename T, bool = std::is_enum_v<T>>
- struct value_traits_base_selector
- {
- static_assert(!is_cvref<T>);
-
- using type = default_value_traits;
- };
- template <typename T>
- struct value_traits_base_selector<T, true>
- {
- static_assert(!is_cvref<T>);
-
- using type = value_traits<underlying_type<T>>;
- };
-
- template <typename T>
- struct value_traits : value_traits_base_selector<T>::type
- {};
- template <typename T>
- struct value_traits<const T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<volatile T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<const volatile T> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<T&> : value_traits<T>
- {};
- template <typename T>
- struct value_traits<T&&> : value_traits<T>
- {};
-
- // integer value_traits specializations - standard types
- template <typename T>
- struct integer_limits
- {
- static constexpr T min = T{ (std::numeric_limits<underlying_type<T>>::min)() };
- static constexpr T max = T{ (std::numeric_limits<underlying_type<T>>::max)() };
- };
- template <typename T>
- struct integer_traits_base : integer_limits<T>
- {
- using native_type = int64_t;
- static constexpr bool is_native = std::is_same_v<underlying_type<T>, native_type>;
- static constexpr bool is_signed = static_cast<underlying_type<T>>(-1) < underlying_type<T>{};
- static constexpr auto type = node_type::integer;
- static constexpr bool can_partially_represent_native = true;
- };
- template <typename T>
- struct unsigned_integer_traits : integer_traits_base<T>
- {
- static constexpr bool is_losslessly_convertible_to_native =
- integer_limits<underlying_type<T>>::max <= 9223372036854775807ULL;
- static constexpr bool can_represent_native = false;
- };
- template <typename T>
- struct signed_integer_traits : integer_traits_base<T>
- {
- using native_type = int64_t;
- static constexpr bool is_losslessly_convertible_to_native =
- integer_limits<underlying_type<T>>::min >= (-9223372036854775807LL - 1LL)
- && integer_limits<underlying_type<T>>::max <= 9223372036854775807LL;
- static constexpr bool can_represent_native =
- integer_limits<underlying_type<T>>::min <= (-9223372036854775807LL - 1LL)
- && integer_limits<underlying_type<T>>::max >= 9223372036854775807LL;
- };
- template <typename T, bool S = integer_traits_base<T>::is_signed>
- struct integer_traits : signed_integer_traits<T>
- {};
- template <typename T>
- struct integer_traits<T, false> : unsigned_integer_traits<T>
- {};
- template <>
- struct value_traits<signed char> : integer_traits<signed char>
- {};
- template <>
- struct value_traits<unsigned char> : integer_traits<unsigned char>
- {};
- template <>
- struct value_traits<signed short> : integer_traits<signed short>
- {};
- template <>
- struct value_traits<unsigned short> : integer_traits<unsigned short>
- {};
- template <>
- struct value_traits<signed int> : integer_traits<signed int>
- {};
- template <>
- struct value_traits<unsigned int> : integer_traits<unsigned int>
- {};
- template <>
- struct value_traits<signed long> : integer_traits<signed long>
- {};
- template <>
- struct value_traits<unsigned long> : integer_traits<unsigned long>
- {};
- template <>
- struct value_traits<signed long long> : integer_traits<signed long long>
- {};
- template <>
- struct value_traits<unsigned long long> : integer_traits<unsigned long long>
- {};
- static_assert(value_traits<int64_t>::is_native);
- static_assert(value_traits<int64_t>::is_signed);
- static_assert(value_traits<int64_t>::is_losslessly_convertible_to_native);
- static_assert(value_traits<int64_t>::can_represent_native);
- static_assert(value_traits<int64_t>::can_partially_represent_native);
-
- // integer value_traits specializations - non-standard types
+ && !is_wide_string<T>;
+
+ template <typename, typename>
+ struct copy_ref_;
+ template <typename Dest, typename Src>
+ using copy_ref = typename copy_ref_<Dest, Src>::type;
+
+ template <typename Dest, typename Src>
+ struct copy_ref_ {
+ using type = Dest;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_ref_<Dest, Src&> {
+ using type = std::add_lvalue_reference_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_ref_<Dest, Src&&> {
+ using type = std::add_rvalue_reference_t<Dest>;
+ };
+
+ template <typename, typename>
+ struct copy_cv_;
+ template <typename Dest, typename Src>
+ using copy_cv = typename copy_cv_<Dest, Src>::type;
+
+ template <typename Dest, typename Src>
+ struct copy_cv_ {
+ using type = Dest;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, const Src> {
+ using type = std::add_const_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, volatile Src> {
+ using type = std::add_volatile_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ struct copy_cv_<Dest, const volatile Src> {
+ using type = std::add_cv_t<Dest>;
+ };
+
+ template <typename Dest, typename Src>
+ using copy_cvref =
+ copy_ref<copy_ref<copy_cv<std::remove_reference_t<Dest>, std::remove_reference_t<Src>>, Dest>,
+ Src>;
+
+ template <typename...>
+ inline constexpr bool always_false = false;
+
+ template <typename T, typename... U>
+ inline constexpr bool first_is_same = false;
+ template <typename T, typename... U>
+ inline constexpr bool first_is_same<T, T, U...> = true;
+
+ template <typename T, bool = std::is_enum_v<T>>
+ struct underlying_type_ {
+ using type = std::underlying_type_t<T>;
+ };
+ template <typename T>
+ struct underlying_type_<T, false> {
+ using type = T;
+ };
+ template <typename T>
+ using underlying_type = typename underlying_type_<T>::type;
+
+ // general value traits
+ // (as they relate to their equivalent native TOML type)
+ struct default_value_traits {
+ using native_type = void;
+ static constexpr bool is_native = false;
+ static constexpr bool is_losslessly_convertible_to_native = false;
+ static constexpr bool can_represent_native = false;
+ static constexpr bool can_partially_represent_native = false;
+ static constexpr auto type = node_type::none;
+ };
+
+ template <typename T>
+ struct value_traits;
+
+ template <typename T, bool = std::is_enum_v<T>>
+ struct value_traits_base_selector {
+ static_assert(!is_cvref<T>);
+
+ using type = default_value_traits;
+ };
+ template <typename T>
+ struct value_traits_base_selector<T, true> {
+ static_assert(!is_cvref<T>);
+
+ using type = value_traits<underlying_type<T>>;
+ };
+
+ template <typename T>
+ struct value_traits : value_traits_base_selector<T>::type {};
+ template <typename T>
+ struct value_traits<const T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<volatile T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<const volatile T> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<T&> : value_traits<T> {};
+ template <typename T>
+ struct value_traits<T&&> : value_traits<T> {};
+
+ // integer value_traits specializations - standard types
+ template <typename T>
+ struct integer_limits {
+ static constexpr T min = T{(std::numeric_limits<underlying_type<T>>::min)()};
+ static constexpr T max = T{(std::numeric_limits<underlying_type<T>>::max)()};
+ };
+ template <typename T>
+ struct integer_traits_base : integer_limits<T> {
+ using native_type = int64_t;
+ static constexpr bool is_native = std::is_same_v<underlying_type<T>, native_type>;
+ static constexpr bool is_signed = static_cast<underlying_type<T>>(-1) < underlying_type<T>{};
+ static constexpr auto type = node_type::integer;
+ static constexpr bool can_partially_represent_native = true;
+ };
+ template <typename T>
+ struct unsigned_integer_traits : integer_traits_base<T> {
+ static constexpr bool is_losslessly_convertible_to_native =
+ integer_limits<underlying_type<T>>::max <= 9223372036854775807ULL;
+ static constexpr bool can_represent_native = false;
+ };
+ template <typename T>
+ struct signed_integer_traits : integer_traits_base<T> {
+ using native_type = int64_t;
+ static constexpr bool is_losslessly_convertible_to_native =
+ integer_limits<underlying_type<T>>::min >= (-9223372036854775807LL - 1LL) &&
+ integer_limits<underlying_type<T>>::max <= 9223372036854775807LL;
+ static constexpr bool can_represent_native =
+ integer_limits<underlying_type<T>>::min <= (-9223372036854775807LL - 1LL) &&
+ integer_limits<underlying_type<T>>::max >= 9223372036854775807LL;
+ };
+ template <typename T, bool S = integer_traits_base<T>::is_signed>
+ struct integer_traits : signed_integer_traits<T> {};
+ template <typename T>
+ struct integer_traits<T, false> : unsigned_integer_traits<T> {};
+ template <>
+ struct value_traits<signed char> : integer_traits<signed char> {};
+ template <>
+ struct value_traits<unsigned char> : integer_traits<unsigned char> {};
+ template <>
+ struct value_traits<signed short> : integer_traits<signed short> {};
+ template <>
+ struct value_traits<unsigned short> : integer_traits<unsigned short> {};
+ template <>
+ struct value_traits<signed int> : integer_traits<signed int> {};
+ template <>
+ struct value_traits<unsigned int> : integer_traits<unsigned int> {};
+ template <>
+ struct value_traits<signed long> : integer_traits<signed long> {};
+ template <>
+ struct value_traits<unsigned long> : integer_traits<unsigned long> {};
+ template <>
+ struct value_traits<signed long long> : integer_traits<signed long long> {};
+ template <>
+ struct value_traits<unsigned long long> : integer_traits<unsigned long long> {};
+ static_assert(value_traits<int64_t>::is_native);
+ static_assert(value_traits<int64_t>::is_signed);
+ static_assert(value_traits<int64_t>::is_losslessly_convertible_to_native);
+ static_assert(value_traits<int64_t>::can_represent_native);
+ static_assert(value_traits<int64_t>::can_partially_represent_native);
+
+ // integer value_traits specializations - non-standard types
#ifdef TOML_INT128
- template <>
- struct integer_limits<TOML_INT128>
- {
- static constexpr TOML_INT128 max =
- static_cast<TOML_INT128>((TOML_UINT128{ 1u } << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
- static constexpr TOML_INT128 min = -max - TOML_INT128{ 1 };
- };
- template <>
- struct integer_limits<TOML_UINT128>
- {
- static constexpr TOML_UINT128 min = TOML_UINT128{};
- static constexpr TOML_UINT128 max = (2u * static_cast<TOML_UINT128>(integer_limits<TOML_INT128>::max)) + 1u;
- };
- template <>
- struct value_traits<TOML_INT128> : integer_traits<TOML_INT128>
- {};
- template <>
- struct value_traits<TOML_UINT128> : integer_traits<TOML_UINT128>
- {};
+ template <>
+ struct integer_limits<TOML_INT128> {
+ static constexpr TOML_INT128 max =
+ static_cast<TOML_INT128>((TOML_UINT128{1u} << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1);
+ static constexpr TOML_INT128 min = -max - TOML_INT128{1};
+ };
+ template <>
+ struct integer_limits<TOML_UINT128> {
+ static constexpr TOML_UINT128 min = TOML_UINT128{};
+ static constexpr TOML_UINT128 max =
+ (2u * static_cast<TOML_UINT128>(integer_limits<TOML_INT128>::max)) + 1u;
+ };
+ template <>
+ struct value_traits<TOML_INT128> : integer_traits<TOML_INT128> {};
+ template <>
+ struct value_traits<TOML_UINT128> : integer_traits<TOML_UINT128> {};
#endif
#ifdef TOML_SMALL_INT_TYPE
- template <>
- struct value_traits<TOML_SMALL_INT_TYPE> : signed_integer_traits<TOML_SMALL_INT_TYPE>
- {};
+ template <>
+ struct value_traits<TOML_SMALL_INT_TYPE> : signed_integer_traits<TOML_SMALL_INT_TYPE> {};
#endif
- // floating-point traits base
- template <typename T, int MantissaDigits, int DecimalDigits>
- struct float_traits_base
- {
- static constexpr auto type = node_type::floating_point;
- using native_type = double;
- static constexpr bool is_native = std::is_same_v<T, native_type>;
- static constexpr bool is_signed = true;
-
- static constexpr int bits = static_cast<int>(sizeof(T) * CHAR_BIT);
- static constexpr int digits = MantissaDigits;
- static constexpr int digits10 = DecimalDigits;
-
- static constexpr bool is_losslessly_convertible_to_native = bits <= 64 //
- && digits <= 53 // DBL_MANT_DIG
- && digits10 <= 15; // DBL_DIG
-
- static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG
- && digits10 >= 15; // DBL_DIG
-
- static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0;
- };
- template <typename T>
- struct float_traits : float_traits_base<T, std::numeric_limits<T>::digits, std::numeric_limits<T>::digits10>
- {};
+ // floating-point traits base
+ template <typename T, int MantissaDigits, int DecimalDigits>
+ struct float_traits_base {
+ static constexpr auto type = node_type::floating_point;
+ using native_type = double;
+ static constexpr bool is_native = std::is_same_v<T, native_type>;
+ static constexpr bool is_signed = true;
+
+ static constexpr int bits = static_cast<int>(sizeof(T) * CHAR_BIT);
+ static constexpr int digits = MantissaDigits;
+ static constexpr int digits10 = DecimalDigits;
+
+ static constexpr bool is_losslessly_convertible_to_native = bits <= 64 //
+ && digits <= 53 // DBL_MANT_DIG
+ && digits10 <= 15; // DBL_DIG
+
+ static constexpr bool can_represent_native = digits >= 53 // DBL_MANT_DIG
+ && digits10 >= 15; // DBL_DIG
+
+ static constexpr bool can_partially_represent_native = digits > 0 && digits10 > 0;
+ };
+ template <typename T>
+ struct float_traits
+ : float_traits_base<T, std::numeric_limits<T>::digits, std::numeric_limits<T>::digits10> {};
#if TOML_ENABLE_FLOAT16
- template <>
- struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__>
- {};
+ template <>
+ struct float_traits<_Float16> : float_traits_base<_Float16, __FLT16_MANT_DIG__, __FLT16_DIG__> {};
#endif
#ifdef TOML_FLOAT128
- template <>
- struct float_traits<TOML_FLOAT128> : float_traits_base<TOML_FLOAT128, __FLT128_MANT_DIG__, __FLT128_DIG__>
- {};
+ template <>
+ struct float_traits<TOML_FLOAT128>
+ : float_traits_base<TOML_FLOAT128, __FLT128_MANT_DIG__, __FLT128_DIG__> {};
#endif
- // floating-point traits
- template <>
- struct value_traits<float> : float_traits<float>
- {};
- template <>
- struct value_traits<double> : float_traits<double>
- {};
- template <>
- struct value_traits<long double> : float_traits<long double>
- {};
+ // floating-point traits
+ template <>
+ struct value_traits<float> : float_traits<float> {};
+ template <>
+ struct value_traits<double> : float_traits<double> {};
+ template <>
+ struct value_traits<long double> : float_traits<long double> {};
#if TOML_ENABLE_FLOAT16
- template <>
- struct value_traits<_Float16> : float_traits<_Float16>
- {};
+ template <>
+ struct value_traits<_Float16> : float_traits<_Float16> {};
#endif
#ifdef TOML_FLOAT128
- template <>
- struct value_traits<TOML_FLOAT128> : float_traits<TOML_FLOAT128>
- {};
+ template <>
+ struct value_traits<TOML_FLOAT128> : float_traits<TOML_FLOAT128> {};
#endif
#ifdef TOML_SMALL_FLOAT_TYPE
- template <>
- struct value_traits<TOML_SMALL_FLOAT_TYPE> : float_traits<TOML_SMALL_FLOAT_TYPE>
- {};
+ template <>
+ struct value_traits<TOML_SMALL_FLOAT_TYPE> : float_traits<TOML_SMALL_FLOAT_TYPE> {};
#endif
- static_assert(value_traits<double>::is_native);
- static_assert(value_traits<double>::is_losslessly_convertible_to_native);
- static_assert(value_traits<double>::can_represent_native);
- static_assert(value_traits<double>::can_partially_represent_native);
-
- // string value_traits specializations - char-based strings
- template <typename T>
- struct string_traits
- {
- using native_type = std::string;
- static constexpr bool is_native = std::is_same_v<T, native_type>;
- static constexpr bool is_losslessly_convertible_to_native = true;
- static constexpr bool can_represent_native =
- !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
- static constexpr bool can_partially_represent_native = can_represent_native;
- static constexpr auto type = node_type::string;
- };
- template <>
- struct value_traits<std::string> : string_traits<std::string>
- {};
- template <>
- struct value_traits<std::string_view> : string_traits<std::string_view>
- {};
- template <>
- struct value_traits<const char*> : string_traits<const char*>
- {};
- template <size_t N>
- struct value_traits<const char[N]> : string_traits<const char[N]>
- {};
- template <>
- struct value_traits<char*> : string_traits<char*>
- {};
- template <size_t N>
- struct value_traits<char[N]> : string_traits<char[N]>
- {};
-
- // string value_traits specializations - char8_t-based strings
+ static_assert(value_traits<double>::is_native);
+ static_assert(value_traits<double>::is_losslessly_convertible_to_native);
+ static_assert(value_traits<double>::can_represent_native);
+ static_assert(value_traits<double>::can_partially_represent_native);
+
+ // string value_traits specializations - char-based strings
+ template <typename T>
+ struct string_traits {
+ using native_type = std::string;
+ static constexpr bool is_native = std::is_same_v<T, native_type>;
+ static constexpr bool is_losslessly_convertible_to_native = true;
+ static constexpr bool can_represent_native =
+ !std::is_array_v<T> && (!std::is_pointer_v<T> || std::is_const_v<std::remove_pointer_t<T>>);
+ static constexpr bool can_partially_represent_native = can_represent_native;
+ static constexpr auto type = node_type::string;
+ };
+ template <>
+ struct value_traits<std::string> : string_traits<std::string> {};
+ template <>
+ struct value_traits<std::string_view> : string_traits<std::string_view> {};
+ template <>
+ struct value_traits<const char*> : string_traits<const char*> {};
+ template <size_t N>
+ struct value_traits<const char[N]> : string_traits<const char[N]> {};
+ template <>
+ struct value_traits<char*> : string_traits<char*> {};
+ template <size_t N>
+ struct value_traits<char[N]> : string_traits<char[N]> {};
+
+ // string value_traits specializations - char8_t-based strings
#if TOML_HAS_CHAR8
- template <>
- struct value_traits<std::u8string> : string_traits<std::u8string>
- {};
- template <>
- struct value_traits<std::u8string_view> : string_traits<std::u8string_view>
- {};
- template <>
- struct value_traits<const char8_t*> : string_traits<const char8_t*>
- {};
- template <size_t N>
- struct value_traits<const char8_t[N]> : string_traits<const char8_t[N]>
- {};
- template <>
- struct value_traits<char8_t*> : string_traits<char8_t*>
- {};
- template <size_t N>
- struct value_traits<char8_t[N]> : string_traits<char8_t[N]>
- {};
+ template <>
+ struct value_traits<std::u8string> : string_traits<std::u8string> {};
+ template <>
+ struct value_traits<std::u8string_view> : string_traits<std::u8string_view> {};
+ template <>
+ struct value_traits<const char8_t*> : string_traits<const char8_t*> {};
+ template <size_t N>
+ struct value_traits<const char8_t[N]> : string_traits<const char8_t[N]> {};
+ template <>
+ struct value_traits<char8_t*> : string_traits<char8_t*> {};
+ template <size_t N>
+ struct value_traits<char8_t[N]> : string_traits<char8_t[N]> {};
#endif
- // string value_traits specializations - wchar_t-based strings on Windows
+ // string value_traits specializations - wchar_t-based strings on Windows
#if TOML_ENABLE_WINDOWS_COMPAT
- template <typename T>
- struct wstring_traits
- {
- using native_type = std::string;
- static constexpr bool is_native = false;
- static constexpr bool is_losslessly_convertible_to_native = true; // narrow
- static constexpr bool can_represent_native = std::is_same_v<T, std::wstring>; // widen
- static constexpr bool can_partially_represent_native = can_represent_native;
- static constexpr auto type = node_type::string;
- };
- template <>
- struct value_traits<std::wstring> : wstring_traits<std::wstring>
- {};
- template <>
- struct value_traits<std::wstring_view> : wstring_traits<std::wstring_view>
- {};
- template <>
- struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*>
- {};
- template <size_t N>
- struct value_traits<const wchar_t[N]> : wstring_traits<const wchar_t[N]>
- {};
- template <>
- struct value_traits<wchar_t*> : wstring_traits<wchar_t*>
- {};
- template <size_t N>
- struct value_traits<wchar_t[N]> : wstring_traits<wchar_t[N]>
- {};
+ template <typename T>
+ struct wstring_traits {
+ using native_type = std::string;
+ static constexpr bool is_native = false;
+ static constexpr bool is_losslessly_convertible_to_native = true; // narrow
+ static constexpr bool can_represent_native = std::is_same_v<T, std::wstring>; // widen
+ static constexpr bool can_partially_represent_native = can_represent_native;
+ static constexpr auto type = node_type::string;
+ };
+ template <>
+ struct value_traits<std::wstring> : wstring_traits<std::wstring> {};
+ template <>
+ struct value_traits<std::wstring_view> : wstring_traits<std::wstring_view> {};
+ template <>
+ struct value_traits<const wchar_t*> : wstring_traits<const wchar_t*> {};
+ template <size_t N>
+ struct value_traits<const wchar_t[N]> : wstring_traits<const wchar_t[N]> {};
+ template <>
+ struct value_traits<wchar_t*> : wstring_traits<wchar_t*> {};
+ template <size_t N>
+ struct value_traits<wchar_t[N]> : wstring_traits<wchar_t[N]> {};
#endif
- // other 'native' value_traits specializations
- template <typename T, node_type NodeType>
- struct native_value_traits
- {
- using native_type = T;
- static constexpr bool is_native = true;
- static constexpr bool is_losslessly_convertible_to_native = true;
- static constexpr bool can_represent_native = true;
- static constexpr bool can_partially_represent_native = true;
- static constexpr auto type = NodeType;
- };
- template <>
- struct value_traits<bool> : native_value_traits<bool, node_type::boolean>
- {};
- template <>
- struct value_traits<date> : native_value_traits<date, node_type::date>
- {};
- template <>
- struct value_traits<time> : native_value_traits<time, node_type::time>
- {};
- template <>
- struct value_traits<date_time> : native_value_traits<date_time, node_type::date_time>
- {};
-
- // native value category queries
- template <typename T>
- using native_type_of = typename value_traits<T>::native_type;
- template <typename T>
- inline constexpr bool is_native = value_traits<T>::is_native;
- template <typename T>
- inline constexpr bool can_represent_native = value_traits<T>::can_represent_native;
- template <typename T>
- inline constexpr bool can_partially_represent_native = value_traits<T>::can_partially_represent_native;
- template <typename T>
- inline constexpr bool is_losslessly_convertible_to_native = value_traits<T>::is_losslessly_convertible_to_native;
- template <typename T, typename... U>
- inline constexpr bool is_natively_one_of = is_one_of<native_type_of<T>, U...>;
-
- // native value types => nodes
- template <typename T>
- struct node_wrapper
- {
- using type = T;
- };
- template <typename T>
- struct node_wrapper<const T>
- {
- using type = std::add_const_t<typename node_wrapper<T>::type>;
- };
- template <typename T>
- struct node_wrapper<volatile T>
- {
- using type = std::add_volatile_t<typename node_wrapper<T>::type>;
- };
- template <typename T>
- struct node_wrapper<const volatile T>
- {
- using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
- };
- template <>
- struct node_wrapper<std::string>
- {
- using type = value<std::string>;
- };
- template <>
- struct node_wrapper<int64_t>
- {
- using type = value<int64_t>;
- };
- template <>
- struct node_wrapper<double>
- {
- using type = value<double>;
- };
- template <>
- struct node_wrapper<bool>
- {
- using type = value<bool>;
- };
- template <>
- struct node_wrapper<date>
- {
- using type = value<date>;
- };
- template <>
- struct node_wrapper<time>
- {
- using type = value<time>;
- };
- template <>
- struct node_wrapper<date_time>
- {
- using type = value<date_time>;
- };
- template <typename T>
- using wrap_node = typename node_wrapper<std::remove_reference_t<T>>::type;
-
- // nodes => native value types
- template <typename T>
- struct node_unwrapper
- {
- using type = T;
- };
- template <typename T>
- struct node_unwrapper<value<T>>
- {
- using type = T;
- };
- template <typename T>
- struct node_unwrapper<const value<T>>
- {
- using type = std::add_const_t<T>;
- };
- template <typename T>
- struct node_unwrapper<volatile value<T>>
- {
- using type = std::add_volatile_t<T>;
- };
- template <typename T>
- struct node_unwrapper<const volatile value<T>>
- {
- using type = std::add_volatile_t<std::add_const_t<T>>;
- };
- template <typename T>
- using unwrap_node = typename node_unwrapper<std::remove_reference_t<T>>::type;
-
- template <typename T>
- struct node_type_getter
- {
- static constexpr auto value = value_traits<T>::type;
- };
- template <>
- struct node_type_getter<table>
- {
- static constexpr auto value = node_type::table;
- };
- template <>
- struct node_type_getter<array>
- {
- static constexpr auto value = node_type::array;
- };
- template <>
- struct node_type_getter<void>
- {
- static constexpr auto value = node_type::none;
- };
- template <typename T>
- inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
-
- template <typename T, typename ConvertFrom>
- inline constexpr bool is_constructible_or_convertible = std::is_constructible_v<T, ConvertFrom> //
- || std::is_convertible_v<ConvertFrom, T>;
+ // other 'native' value_traits specializations
+ template <typename T, node_type NodeType>
+ struct native_value_traits {
+ using native_type = T;
+ static constexpr bool is_native = true;
+ static constexpr bool is_losslessly_convertible_to_native = true;
+ static constexpr bool can_represent_native = true;
+ static constexpr bool can_partially_represent_native = true;
+ static constexpr auto type = NodeType;
+ };
+ template <>
+ struct value_traits<bool> : native_value_traits<bool, node_type::boolean> {};
+ template <>
+ struct value_traits<date> : native_value_traits<date, node_type::date> {};
+ template <>
+ struct value_traits<time> : native_value_traits<time, node_type::time> {};
+ template <>
+ struct value_traits<date_time> : native_value_traits<date_time, node_type::date_time> {};
+
+ // native value category queries
+ template <typename T>
+ using native_type_of = typename value_traits<T>::native_type;
+ template <typename T>
+ inline constexpr bool is_native = value_traits<T>::is_native;
+ template <typename T>
+ inline constexpr bool can_represent_native = value_traits<T>::can_represent_native;
+ template <typename T>
+ inline constexpr bool can_partially_represent_native =
+ value_traits<T>::can_partially_represent_native;
+ template <typename T>
+ inline constexpr bool is_losslessly_convertible_to_native =
+ value_traits<T>::is_losslessly_convertible_to_native;
+ template <typename T, typename... U>
+ inline constexpr bool is_natively_one_of = is_one_of<native_type_of<T>, U...>;
+
+ // native value types => nodes
+ template <typename T>
+ struct node_wrapper {
+ using type = T;
+ };
+ template <typename T>
+ struct node_wrapper<const T> {
+ using type = std::add_const_t<typename node_wrapper<T>::type>;
+ };
+ template <typename T>
+ struct node_wrapper<volatile T> {
+ using type = std::add_volatile_t<typename node_wrapper<T>::type>;
+ };
+ template <typename T>
+ struct node_wrapper<const volatile T> {
+ using type = std::add_const_t<std::add_volatile_t<typename node_wrapper<T>::type>>;
+ };
+ template <>
+ struct node_wrapper<std::string> {
+ using type = value<std::string>;
+ };
+ template <>
+ struct node_wrapper<int64_t> {
+ using type = value<int64_t>;
+ };
+ template <>
+ struct node_wrapper<double> {
+ using type = value<double>;
+ };
+ template <>
+ struct node_wrapper<bool> {
+ using type = value<bool>;
+ };
+ template <>
+ struct node_wrapper<date> {
+ using type = value<date>;
+ };
+ template <>
+ struct node_wrapper<time> {
+ using type = value<time>;
+ };
+ template <>
+ struct node_wrapper<date_time> {
+ using type = value<date_time>;
+ };
+ template <typename T>
+ using wrap_node = typename node_wrapper<std::remove_reference_t<T>>::type;
+
+ // nodes => native value types
+ template <typename T>
+ struct node_unwrapper {
+ using type = T;
+ };
+ template <typename T>
+ struct node_unwrapper<value<T>> {
+ using type = T;
+ };
+ template <typename T>
+ struct node_unwrapper<const value<T>> {
+ using type = std::add_const_t<T>;
+ };
+ template <typename T>
+ struct node_unwrapper<volatile value<T>> {
+ using type = std::add_volatile_t<T>;
+ };
+ template <typename T>
+ struct node_unwrapper<const volatile value<T>> {
+ using type = std::add_volatile_t<std::add_const_t<T>>;
+ };
+ template <typename T>
+ using unwrap_node = typename node_unwrapper<std::remove_reference_t<T>>::type;
+
+ template <typename T>
+ struct node_type_getter {
+ static constexpr auto value = value_traits<T>::type;
+ };
+ template <>
+ struct node_type_getter<table> {
+ static constexpr auto value = node_type::table;
+ };
+ template <>
+ struct node_type_getter<array> {
+ static constexpr auto value = node_type::array;
+ };
+ template <>
+ struct node_type_getter<void> {
+ static constexpr auto value = node_type::none;
+ };
+ template <typename T>
+ inline constexpr node_type node_type_of = node_type_getter<unwrap_node<remove_cvref<T>>>::value;
+
+ template <typename T, typename ConvertFrom>
+ inline constexpr bool is_constructible_or_convertible =
+ std::is_constructible_v<T, ConvertFrom> //
+ || std::is_convertible_v<ConvertFrom, T>;
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::table.
- template <typename T>
- inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>, table>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::array.
- template <typename T>
- inline constexpr bool is_array = std::is_same_v<impl::remove_cvref<T>, array>;
-
- /// \brief Metafunction for determining if a type satisfies either toml::is_table or toml::is_array.
- template <typename T>
- inline constexpr bool is_container = is_table<T> || is_array<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a std::string or toml::value<std::string>.
- template <typename T>
- inline constexpr bool is_string = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<std::string>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
- template <typename T>
- inline constexpr bool is_integer = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<int64_t>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a double or toml::value<double>.
- template <typename T>
- inline constexpr bool is_floating_point = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<double>>;
-
- /// \brief Metafunction for determining if a type satisfies either toml::is_integer or toml::is_floating_point.
- template <typename T>
- inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a bool or toml::value<bool>.
- template <typename T>
- inline constexpr bool is_boolean = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<bool>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date or toml::value<date>.
- template <typename T>
- inline constexpr bool is_date = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<date>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::time or toml::value<time>.
- template <typename T>
- inline constexpr bool is_time = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<time>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date_time or toml::value<date_time>.
- template <typename T>
- inline constexpr bool is_date_time = std::is_same_v< //
- impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
- value<date_time>>;
-
- /// \brief Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time or toml::is_date_time.
- template <typename T>
- inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, any of the toml value types. Excludes tables and arrays.
- template <typename T>
- inline constexpr bool is_value = is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one of its subclasses).
- template <typename T>
- inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
- || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
- template <typename T>
- inline constexpr bool is_node_view = impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
+TOML_NAMESPACE_START {
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::table.
+ template <typename T>
+ inline constexpr bool is_table = std::is_same_v<impl::remove_cvref<T>, table>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::array.
+ template <typename T>
+ inline constexpr bool is_array = std::is_same_v<impl::remove_cvref<T>, array>;
+
+ /// \brief Metafunction for determining if a type satisfies either toml::is_table or
+ /// toml::is_array.
+ template <typename T>
+ inline constexpr bool is_container = is_table<T> || is_array<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a std::string or
+ /// toml::value<std::string>.
+ template <typename T>
+ inline constexpr bool is_string = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<std::string>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a int64_t or
+ /// toml::value<int64_t>.
+ template <typename T>
+ inline constexpr bool is_integer = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<int64_t>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a double or
+ /// toml::value<double>.
+ template <typename T>
+ inline constexpr bool is_floating_point = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<double>>;
+
+ /// \brief Metafunction for determining if a type satisfies either toml::is_integer or
+ /// toml::is_floating_point.
+ template <typename T>
+ inline constexpr bool is_number = is_integer<T> || is_floating_point<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a bool or
+ /// toml::value<bool>.
+ template <typename T>
+ inline constexpr bool is_boolean = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<bool>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date or
+ /// toml::value<date>.
+ template <typename T>
+ inline constexpr bool is_date = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<date>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::time or
+ /// toml::value<time>.
+ template <typename T>
+ inline constexpr bool is_time = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<time>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::date_time or
+ /// toml::value<date_time>.
+ template <typename T>
+ inline constexpr bool is_date_time = std::is_same_v< //
+ impl::remove_cvref<impl::wrap_node<impl::remove_cvref<T>>>, //
+ value<date_time>>;
+
+ /// \brief Metafunction for determining if a type satisfies any of toml::is_date, toml::is_time
+ /// or toml::is_date_time.
+ template <typename T>
+ inline constexpr bool is_chronological = is_date<T> || is_time<T> || is_date_time<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, any of the toml value
+ /// types. Excludes tables and arrays.
+ template <typename T>
+ inline constexpr bool is_value =
+ is_string<T> || is_number<T> || is_boolean<T> || is_chronological<T>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node (or one
+ /// of its subclasses).
+ template <typename T>
+ inline constexpr bool is_node = std::is_same_v<toml::node, impl::remove_cvref<T>> //
+ || std::is_base_of_v<toml::node, impl::remove_cvref<T>>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::node_view.
+ template <typename T>
+ inline constexpr bool is_node_view =
+ impl::is_one_of<impl::remove_cvref<T>, node_view<node>, node_view<const node>>;
}
TOML_NAMESPACE_END;
-//#---------------------------------------------------------------------------------------------------------------------
-//# INTERNAL HELPERS
-//#---------------------------------------------------------------------------------------------------------------------
+// #---------------------------------------------------------------------------------------------------------------------
+// # INTERNAL HELPERS
+// #---------------------------------------------------------------------------------------------------------------------
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- TOML_CONST_INLINE_GETTER
- constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept
- {
- return static_cast<std::underlying_type_t<T>>(val);
- }
-
- // Q: "why not use std::fpclassify?"
- // A: Because it gets broken by -ffast-math and friends
- enum class TOML_CLOSED_ENUM fp_class : unsigned
- {
- ok,
- neg_inf,
- pos_inf,
- nan
- };
-
- TOML_PURE_GETTER
- inline fp_class fpclassify(const double& val) noexcept
- {
- static_assert(sizeof(uint64_t) == sizeof(double));
-
- static constexpr uint64_t sign = 0b1000000000000000000000000000000000000000000000000000000000000000ull;
- static constexpr uint64_t exponent = 0b0111111111110000000000000000000000000000000000000000000000000000ull;
- static constexpr uint64_t mantissa = 0b0000000000001111111111111111111111111111111111111111111111111111ull;
-
- uint64_t val_bits;
- std::memcpy(&val_bits, &val, sizeof(val));
- if ((val_bits & exponent) != exponent)
- return fp_class::ok;
- if ((val_bits & mantissa))
- return fp_class::nan;
- return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
- }
-
- // Q: "why not use std::find and std::min?"
- // A: Because <algorithm> is _huge_ and these would be the only things I used from it.
- // I don't want to impose such a heavy compile-time burden on users.
-
- template <typename Iterator, typename T>
- TOML_PURE_GETTER
- inline auto find(Iterator start, Iterator end, const T& needle) noexcept //
- ->decltype(&(*start))
- {
- for (; start != end; start++)
- if (*start == needle)
- return &(*start);
- return nullptr;
- }
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- constexpr const T& min(const T& a, const T& b) noexcept //
- {
- return a < b ? a : b;
- }
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ TOML_CONST_INLINE_GETTER constexpr std::underlying_type_t<T> unwrap_enum(T val) noexcept {
+ return static_cast<std::underlying_type_t<T>>(val);
+ }
+
+ // Q: "why not use std::fpclassify?"
+ // A: Because it gets broken by -ffast-math and friends
+ enum class TOML_CLOSED_ENUM fp_class : unsigned { ok, neg_inf, pos_inf, nan };
+
+ TOML_PURE_GETTER
+ inline fp_class fpclassify(const double& val) noexcept {
+ static_assert(sizeof(uint64_t) == sizeof(double));
+
+ static constexpr uint64_t sign =
+ 0b1000000000000000000000000000000000000000000000000000000000000000ull;
+ static constexpr uint64_t exponent =
+ 0b0111111111110000000000000000000000000000000000000000000000000000ull;
+ static constexpr uint64_t mantissa =
+ 0b0000000000001111111111111111111111111111111111111111111111111111ull;
+
+ uint64_t val_bits;
+ std::memcpy(&val_bits, &val, sizeof(val));
+ if ((val_bits & exponent) != exponent) return fp_class::ok;
+ if ((val_bits & mantissa)) return fp_class::nan;
+ return (val_bits & sign) ? fp_class::neg_inf : fp_class::pos_inf;
+ }
+
+ // Q: "why not use std::find and std::min?"
+ // A: Because <algorithm> is _huge_ and these would be the only things I used from it.
+ // I don't want to impose such a heavy compile-time burden on users.
+
+ template <typename Iterator, typename T>
+ TOML_PURE_GETTER inline auto find(Iterator start, Iterator end, const T& needle) noexcept //
+ -> decltype(&(*start)) {
+ for (; start != end; start++)
+ if (*start == needle) return &(*start);
+ return nullptr;
+ }
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER constexpr const T& min(const T& a, const T& b) noexcept //
+ {
+ return a < b ? a : b;
+ }
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
diff --git a/vendor/toml++/impl/header_end.hpp b/vendor/toml++/impl/header_end.hpp
index ff0462d..df011a3 100644
--- a/vendor/toml++/impl/header_end.hpp
+++ b/vendor/toml++/impl/header_end.hpp
@@ -1,8 +1,8 @@
-//# {{
+// # {{
#ifdef __INTELLISENSE__
#include "preprocessor.hpp"
#endif
-//# }}
+// # }}
#ifdef _MSC_VER
#pragma pop_macro("min")
#pragma pop_macro("max")
diff --git a/vendor/toml++/impl/header_start.hpp b/vendor/toml++/impl/header_start.hpp
index 6e1bb41..789d757 100644
--- a/vendor/toml++/impl/header_start.hpp
+++ b/vendor/toml++/impl/header_start.hpp
@@ -1,8 +1,8 @@
-//# {{
+// # {{
#ifdef __INTELLISENSE__
#include "preprocessor.hpp"
#endif
-//# }}
+// # }}
TOML_PUSH_WARNINGS;
#ifdef _MSC_VER
#ifndef __clang__
diff --git a/vendor/toml++/impl/json_formatter.hpp b/vendor/toml++/impl/json_formatter.hpp
index ca3776a..d403287 100644
--- a/vendor/toml++/impl/json_formatter.hpp
+++ b/vendor/toml++/impl/json_formatter.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
@@ -10,133 +10,128 @@
#include "formatter.hpp"
#include "header_start.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A wrapper for printing TOML objects out to a stream as formatted JSON.
- ///
- /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
- ///
- /// \detail \cpp
- /// auto some_toml = toml::parse(R"(
- /// [fruit]
- /// apple.color = "red"
- /// apple.taste.sweet = true
- ///
- /// [fruit.apple.texture]
- /// smooth = true
- /// )"sv);
- /// std::cout << toml::json_formatter{ some_toml } << "\n";
- /// \ecpp
- ///
- /// \out
- /// {
- /// "fruit" : {
- /// "apple" : {
- /// "color" : "red",
- /// "taste" : {
- /// "sweet" : true
- /// },
- /// "texture" : {
- /// "smooth" : true
- /// }
- /// }
- /// }
- /// }
- /// \eout
- class TOML_EXPORTED_CLASS json_formatter : impl::formatter
- {
- private:
- /// \cond
-
- using base = impl::formatter;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::table&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::array&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print();
-
- static constexpr impl::formatter_constants constants = {
- format_flags::quote_dates_and_times, // mandatory
- format_flags::allow_literal_strings | format_flags::allow_multi_line_strings, // ignored
- "Infinity"sv,
- "-Infinity"sv,
- "NaN"sv,
- "true"sv,
- "false"sv
- };
-
- /// \endcond
-
- public:
- /// \brief The default flags for a json_formatter.
- static constexpr format_flags default_flags = constants.mandatory_flags //
- | format_flags::quote_infinities_and_nans //
- | format_flags::allow_unicode_strings //
- | format_flags::indentation;
-
- /// \brief Constructs a JSON formatter and binds it to a TOML object.
- ///
- /// \param source The source TOML object.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
- : base{ &source, nullptr, constants, { flags, " "sv } }
- {}
+TOML_NAMESPACE_START {
+ /// \brief A wrapper for printing TOML objects out to a stream as formatted JSON.
+ ///
+ /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ ///
+ /// \detail \cpp
+ /// auto some_toml = toml::parse(R"(
+ /// [fruit]
+ /// apple.color = "red"
+ /// apple.taste.sweet = true
+ ///
+ /// [fruit.apple.texture]
+ /// smooth = true
+ /// )"sv);
+ /// std::cout << toml::json_formatter{ some_toml } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// {
+ /// "fruit" : {
+ /// "apple" : {
+ /// "color" : "red",
+ /// "taste" : {
+ /// "sweet" : true
+ /// },
+ /// "texture" : {
+ /// "smooth" : true
+ /// }
+ /// }
+ /// }
+ /// }
+ /// \eout
+ class TOML_EXPORTED_CLASS json_formatter : impl::formatter {
+ private:
+ /// \cond
+
+ using base = impl::formatter;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::table&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::array&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print();
+
+ static constexpr impl::formatter_constants constants = {
+ format_flags::quote_dates_and_times, // mandatory
+ format_flags::allow_literal_strings | format_flags::allow_multi_line_strings, // ignored
+ "Infinity"sv,
+ "-Infinity"sv,
+ "NaN"sv,
+ "true"sv,
+ "false"sv};
+
+ /// \endcond
+
+ public:
+ /// \brief The default flags for a json_formatter.
+ static constexpr format_flags default_flags = constants.mandatory_flags //
+ | format_flags::quote_infinities_and_nans //
+ | format_flags::allow_unicode_strings //
+ | format_flags::indentation;
+
+ /// \brief Constructs a JSON formatter and binds it to a TOML object.
+ ///
+ /// \param source The source TOML object.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit json_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
+ : base{&source, nullptr, constants, {flags, " "sv}} {}
#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
- /// \brief Constructs a JSON formatter and binds it to a toml::parse_result.
- ///
- /// \availability This constructor is only available when exceptions are disabled.
- ///
- /// \attention Formatting a failed parse result will simply dump the error message out as-is.
- /// This will not be valid JSON, but at least gives you something to log or show up in diagnostics:
- /// \cpp
- /// std::cout << toml::json_formatter{ toml::parse("a = 'b'"sv) } // ok
- /// << "\n\n"
- /// << toml::json_formatter{ toml::parse("a = "sv) } // malformed
- /// << "\n";
- /// \ecpp
- /// \out
- /// {
- /// "a" : "b"
- /// }
- ///
- /// Error while parsing key-value pair: encountered end-of-file
- /// (error occurred at line 1, column 5)
- /// \eout
- /// Use the library with exceptions if you want to avoid this scenario.
- ///
- /// \param result The parse result.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit json_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
- : base{ nullptr, &result, constants, { flags, " "sv } }
- {}
+ /// \brief Constructs a JSON formatter and binds it to a toml::parse_result.
+ ///
+ /// \availability This constructor is only available when exceptions are disabled.
+ ///
+ /// \attention Formatting a failed parse result will simply dump the error message out as-is.
+ /// This will not be valid JSON, but at least gives you something to log or show up in
+ ///diagnostics:
+ /// \cpp
+ /// std::cout << toml::json_formatter{ toml::parse("a = 'b'"sv) } // ok
+ /// << "\n\n"
+ /// << toml::json_formatter{ toml::parse("a = "sv) } // malformed
+ /// << "\n";
+ /// \ecpp
+ /// \out
+ /// {
+ /// "a" : "b"
+ /// }
+ ///
+ /// Error while parsing key-value pair: encountered end-of-file
+ /// (error occurred at line 1, column 5)
+ /// \eout
+ /// Use the library with exceptions if you want to avoid this scenario.
+ ///
+ /// \param result The parse result.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit json_formatter(const toml::parse_result& result,
+ format_flags flags = default_flags) noexcept
+ : base{nullptr, &result, constants, {flags, " "sv}} {}
#endif
- /// \brief Prints the bound TOML object out to the stream as JSON.
- friend std::ostream& operator<<(std::ostream& lhs, json_formatter& rhs)
- {
- rhs.attach(lhs);
- rhs.print();
- rhs.detach();
- return lhs;
- }
-
- /// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
- friend std::ostream& operator<<(std::ostream& lhs, json_formatter&& rhs)
- {
- return lhs << rhs; // as lvalue
- }
- };
+ /// \brief Prints the bound TOML object out to the stream as JSON.
+ friend std::ostream& operator<<(std::ostream& lhs, json_formatter& rhs) {
+ rhs.attach(lhs);
+ rhs.print();
+ rhs.detach();
+ return lhs;
+ }
+
+ /// \brief Prints the bound TOML object out to the stream as JSON (rvalue overload).
+ friend std::ostream& operator<<(std::ostream& lhs, json_formatter&& rhs) {
+ return lhs << rhs; // as lvalue
+ }
+ };
}
TOML_NAMESPACE_END;
#include "header_end.hpp"
-#endif // TOML_ENABLE_FORMATTERS
+#endif // TOML_ENABLE_FORMATTERS
diff --git a/vendor/toml++/impl/key.hpp b/vendor/toml++/impl/key.hpp
index 575017a..ccfd72e 100644
--- a/vendor/toml++/impl/key.hpp
+++ b/vendor/toml++/impl/key.hpp
@@ -1,334 +1,257 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
+#include "header_start.hpp"
+#include "print_to_stream.hpp"
#include "source_region.hpp"
#include "std_utility.hpp"
-#include "print_to_stream.hpp"
-#include "header_start.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A key parsed from a TOML document.
- ///
- /// \detail These are used as the internal keys for a toml::table: \cpp
- /// const toml::table tbl = R"(
- /// a = 1
- /// b = 2
- /// c = 3
- /// )"_toml;
- ///
- /// for (auto&& [k, v] : tbl)
- /// std::cout << "key '"sv << k << "' defined at "sv << k.source() << "\n";
- /// \ecpp
- /// \out
- /// key 'a' defined at line 2, column 5
- /// key 'b' defined at line 3, column 7
- /// key 'c' defined at line 4, column 9
- /// \eout
- class key
- {
- private:
- std::string key_;
- source_region source_;
-
- public:
- /// \brief Default constructor.
- TOML_NODISCARD_CTOR
- key() noexcept = default;
-
- /// \brief Constructs a key from a string view and source region.
- TOML_NODISCARD_CTOR
- explicit key(std::string_view k, source_region&& src = {}) //
- : key_{ k },
- source_{ std::move(src) }
- {}
-
- /// \brief Constructs a key from a string view and source region.
- TOML_NODISCARD_CTOR
- explicit key(std::string_view k, const source_region& src) //
- : key_{ k },
- source_{ src }
- {}
-
- /// \brief Constructs a key from a string and source region.
- TOML_NODISCARD_CTOR
- explicit key(std::string&& k, source_region&& src = {}) noexcept //
- : key_{ std::move(k) },
- source_{ std::move(src) }
- {}
-
- /// \brief Constructs a key from a string and source region.
- TOML_NODISCARD_CTOR
- explicit key(std::string&& k, const source_region& src) noexcept //
- : key_{ std::move(k) },
- source_{ src }
- {}
-
- /// \brief Constructs a key from a c-string and source region.
- TOML_NODISCARD_CTOR
- explicit key(const char* k, source_region&& src = {}) //
- : key_{ k },
- source_{ std::move(src) }
- {}
-
- /// \brief Constructs a key from a c-string view and source region.
- TOML_NODISCARD_CTOR
- explicit key(const char* k, const source_region& src) //
- : key_{ k },
- source_{ src }
- {}
+TOML_NAMESPACE_START {
+ /// \brief A key parsed from a TOML document.
+ ///
+ /// \detail These are used as the internal keys for a toml::table: \cpp
+ /// const toml::table tbl = R"(
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ /// )"_toml;
+ ///
+ /// for (auto&& [k, v] : tbl)
+ /// std::cout << "key '"sv << k << "' defined at "sv << k.source() << "\n";
+ /// \ecpp
+ /// \out
+ /// key 'a' defined at line 2, column 5
+ /// key 'b' defined at line 3, column 7
+ /// key 'c' defined at line 4, column 9
+ /// \eout
+ class key {
+ private:
+ std::string key_;
+ source_region source_;
+
+ public:
+ /// \brief Default constructor.
+ TOML_NODISCARD_CTOR
+ key() noexcept = default;
+
+ /// \brief Constructs a key from a string view and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(std::string_view k, source_region&& src = {}) //
+ : key_{k}, source_{std::move(src)} {}
+
+ /// \brief Constructs a key from a string view and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(std::string_view k, const source_region& src) //
+ : key_{k}, source_{src} {}
+
+ /// \brief Constructs a key from a string and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(std::string&& k, source_region&& src = {}) noexcept //
+ : key_{std::move(k)}, source_{std::move(src)} {}
+
+ /// \brief Constructs a key from a string and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(std::string&& k, const source_region& src) noexcept //
+ : key_{std::move(k)}, source_{src} {}
+
+ /// \brief Constructs a key from a c-string and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(const char* k, source_region&& src = {}) //
+ : key_{k}, source_{std::move(src)} {}
+
+ /// \brief Constructs a key from a c-string view and source region.
+ TOML_NODISCARD_CTOR
+ explicit key(const char* k, const source_region& src) //
+ : key_{k}, source_{src} {}
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Constructs a key from a wide string view and source region.
- ///
- /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD_CTOR
- explicit key(std::wstring_view k, source_region&& src = {}) //
- : key_{ impl::narrow(k) },
- source_{ std::move(src) }
- {}
-
- /// \brief Constructs a key from a wide string and source region.
- ///
- /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD_CTOR
- explicit key(std::wstring_view k, const source_region& src) //
- : key_{ impl::narrow(k) },
- source_{ src }
- {}
+ /// \brief Constructs a key from a wide string view and source region.
+ ///
+ /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is
+ /// enabled.
+ TOML_NODISCARD_CTOR
+ explicit key(std::wstring_view k, source_region&& src = {}) //
+ : key_{impl::narrow(k)}, source_{std::move(src)} {}
+
+ /// \brief Constructs a key from a wide string and source region.
+ ///
+ /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is
+ /// enabled.
+ TOML_NODISCARD_CTOR
+ explicit key(std::wstring_view k, const source_region& src) //
+ : key_{impl::narrow(k)}, source_{src} {}
#endif
- /// \name String operations
- /// @{
-
- /// \brief Returns a view of the key's underlying string.
- TOML_PURE_INLINE_GETTER
- std::string_view str() const noexcept
- {
- return std::string_view{ key_ };
- }
-
- /// \brief Returns a view of the key's underlying string.
- TOML_PURE_INLINE_GETTER
- /*implicit*/ operator std::string_view() const noexcept
- {
- return str();
- }
-
- /// \brief Returns true if the key's underlying string is empty.
- TOML_PURE_INLINE_GETTER
- bool empty() const noexcept
- {
- return key_.empty();
- }
-
- /// \brief Returns a pointer to the start of the key's underlying string.
- TOML_PURE_INLINE_GETTER
- const char* data() const noexcept
- {
- return key_.data();
- }
-
- /// \brief Returns the length of the key's underlying string.
- TOML_PURE_INLINE_GETTER
- size_t length() const noexcept
- {
- return key_.length();
- }
-
- /// @}
-
- /// \name Metadata
- /// @{
-
- /// \brief Returns the source region responsible for specifying this key during parsing.
- TOML_PURE_INLINE_GETTER
- const source_region& source() const noexcept
- {
- return source_;
- }
-
- /// @}
-
- /// \name Equality and Comparison
- /// \attention These operations only compare the underlying strings; source regions are ignored for the purposes of all comparison!
- /// @{
-
- /// \brief Returns true if `lhs.str() == rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ == rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() != rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ != rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() < rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ < rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() <= rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<=(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ <= rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() > rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ > rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() >= rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>=(const key& lhs, const key& rhs) noexcept
- {
- return lhs.key_ >= rhs.key_;
- }
-
- /// \brief Returns true if `lhs.str() == rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ == rhs;
- }
-
- /// \brief Returns true if `lhs.str() != rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ != rhs;
- }
-
- /// \brief Returns true if `lhs.str() < rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ < rhs;
- }
-
- /// \brief Returns true if `lhs.str() <= rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<=(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ <= rhs;
- }
-
- /// \brief Returns true if `lhs.str() > rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ > rhs;
- }
-
- /// \brief Returns true if `lhs.str() >= rhs`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>=(const key& lhs, std::string_view rhs) noexcept
- {
- return lhs.key_ >= rhs;
- }
-
- /// \brief Returns true if `lhs == rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator==(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs == rhs.key_;
- }
-
- /// \brief Returns true if `lhs != rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs != rhs.key_;
- }
-
- /// \brief Returns true if `lhs < rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs < rhs.key_;
- }
-
- /// \brief Returns true if `lhs <= rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator<=(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs <= rhs.key_;
- }
-
- /// \brief Returns true if `lhs > rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs > rhs.key_;
- }
-
- /// \brief Returns true if `lhs >= rhs.str()`.
- TOML_PURE_INLINE_GETTER
- friend bool operator>=(std::string_view lhs, const key& rhs) noexcept
- {
- return lhs >= rhs.key_;
- }
-
- /// @}
-
- /// \name Iteration
- /// @{
-
- /// \brief A const iterator for iterating over the characters in the key.
- using const_iterator = const char*;
-
- /// \brief A const iterator for iterating over the characters in the key.
- using iterator = const_iterator;
-
- /// \brief Returns an iterator to the first character in the key's backing string.
- TOML_PURE_INLINE_GETTER
- const_iterator begin() const noexcept
- {
- return key_.data();
- }
-
- /// \brief Returns an iterator to one-past-the-last character in the key's backing string.
- TOML_PURE_INLINE_GETTER
- const_iterator end() const noexcept
- {
- return key_.data() + key_.length();
- }
-
- /// @}
-
- /// \brief Prints the key's underlying string out to the stream.
- friend std::ostream& operator<<(std::ostream& lhs, const key& rhs)
- {
- impl::print_to_stream(lhs, rhs.key_);
- return lhs;
- }
- };
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key.
- template <typename T>
- inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>;
-
- /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key,
- /// or is implicitly or explicitly convertible to one.
- template <typename T>
- inline constexpr bool is_key_or_convertible = is_key<T> //
- || impl::is_constructible_or_convertible<toml::key, T>;
+ /// \name String operations
+ /// @{
+
+ /// \brief Returns a view of the key's underlying string.
+ TOML_PURE_INLINE_GETTER
+ std::string_view str() const noexcept { return std::string_view{key_}; }
+
+ /// \brief Returns a view of the key's underlying string.
+ TOML_PURE_INLINE_GETTER
+ /*implicit*/ operator std::string_view() const noexcept { return str(); }
+
+ /// \brief Returns true if the key's underlying string is empty.
+ TOML_PURE_INLINE_GETTER
+ bool empty() const noexcept { return key_.empty(); }
+
+ /// \brief Returns a pointer to the start of the key's underlying string.
+ TOML_PURE_INLINE_GETTER
+ const char* data() const noexcept { return key_.data(); }
+
+ /// \brief Returns the length of the key's underlying string.
+ TOML_PURE_INLINE_GETTER
+ size_t length() const noexcept { return key_.length(); }
+
+ /// @}
+
+ /// \name Metadata
+ /// @{
+
+ /// \brief Returns the source region responsible for specifying this key during parsing.
+ TOML_PURE_INLINE_GETTER
+ const source_region& source() const noexcept { return source_; }
+
+ /// @}
+
+ /// \name Equality and Comparison
+ /// \attention These operations only compare the underlying strings; source regions are ignored
+ /// for the purposes of all comparison!
+ /// @{
+
+ /// \brief Returns true if `lhs.str() == rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const key& lhs, const key& rhs) noexcept { return lhs.key_ == rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() != rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const key& lhs, const key& rhs) noexcept { return lhs.key_ != rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() < rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<(const key& lhs, const key& rhs) noexcept { return lhs.key_ < rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() <= rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<=(const key& lhs, const key& rhs) noexcept { return lhs.key_ <= rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() > rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>(const key& lhs, const key& rhs) noexcept { return lhs.key_ > rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() >= rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>=(const key& lhs, const key& rhs) noexcept { return lhs.key_ >= rhs.key_; }
+
+ /// \brief Returns true if `lhs.str() == rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const key& lhs, std::string_view rhs) noexcept {
+ return lhs.key_ == rhs;
+ }
+
+ /// \brief Returns true if `lhs.str() != rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const key& lhs, std::string_view rhs) noexcept {
+ return lhs.key_ != rhs;
+ }
+
+ /// \brief Returns true if `lhs.str() < rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<(const key& lhs, std::string_view rhs) noexcept { return lhs.key_ < rhs; }
+
+ /// \brief Returns true if `lhs.str() <= rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<=(const key& lhs, std::string_view rhs) noexcept {
+ return lhs.key_ <= rhs;
+ }
+
+ /// \brief Returns true if `lhs.str() > rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>(const key& lhs, std::string_view rhs) noexcept { return lhs.key_ > rhs; }
+
+ /// \brief Returns true if `lhs.str() >= rhs`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>=(const key& lhs, std::string_view rhs) noexcept {
+ return lhs.key_ >= rhs;
+ }
+
+ /// \brief Returns true if `lhs == rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(std::string_view lhs, const key& rhs) noexcept {
+ return lhs == rhs.key_;
+ }
+
+ /// \brief Returns true if `lhs != rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(std::string_view lhs, const key& rhs) noexcept {
+ return lhs != rhs.key_;
+ }
+
+ /// \brief Returns true if `lhs < rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<(std::string_view lhs, const key& rhs) noexcept { return lhs < rhs.key_; }
+
+ /// \brief Returns true if `lhs <= rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator<=(std::string_view lhs, const key& rhs) noexcept {
+ return lhs <= rhs.key_;
+ }
+
+ /// \brief Returns true if `lhs > rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>(std::string_view lhs, const key& rhs) noexcept { return lhs > rhs.key_; }
+
+ /// \brief Returns true if `lhs >= rhs.str()`.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator>=(std::string_view lhs, const key& rhs) noexcept {
+ return lhs >= rhs.key_;
+ }
+
+ /// @}
+
+ /// \name Iteration
+ /// @{
+
+ /// \brief A const iterator for iterating over the characters in the key.
+ using const_iterator = const char*;
+
+ /// \brief A const iterator for iterating over the characters in the key.
+ using iterator = const_iterator;
+
+ /// \brief Returns an iterator to the first character in the key's backing string.
+ TOML_PURE_INLINE_GETTER
+ const_iterator begin() const noexcept { return key_.data(); }
+
+ /// \brief Returns an iterator to one-past-the-last character in the key's backing string.
+ TOML_PURE_INLINE_GETTER
+ const_iterator end() const noexcept { return key_.data() + key_.length(); }
+
+ /// @}
+
+ /// \brief Prints the key's underlying string out to the stream.
+ friend std::ostream& operator<<(std::ostream& lhs, const key& rhs) {
+ impl::print_to_stream(lhs, rhs.key_);
+ return lhs;
+ }
+ };
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key.
+ template <typename T>
+ inline constexpr bool is_key = std::is_same_v<impl::remove_cvref<T>, toml::key>;
+
+ /// \brief Metafunction for determining if a type is, or is a reference to, a toml::key,
+ /// or is implicitly or explicitly convertible to one.
+ template <typename T>
+ inline constexpr bool is_key_or_convertible =
+ is_key<T> //
+ || impl::is_constructible_or_convertible<toml::key, T>;
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/make_node.hpp b/vendor/toml++/impl/make_node.hpp
index 69a566a..4debabf 100644
--- a/vendor/toml++/impl/make_node.hpp
+++ b/vendor/toml++/impl/make_node.hpp
@@ -1,181 +1,156 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "forward_declarations.hpp"
#include "header_start.hpp"
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T>
- TOML_NODISCARD
- TOML_ATTR(returns_nonnull)
- auto* make_node_impl_specialized(T && val, [[maybe_unused]] value_flags flags)
- {
- using unwrapped_type = unwrap_node<remove_cvref<T>>;
- static_assert(!std::is_same_v<unwrapped_type, node>);
- static_assert(!is_node_view<unwrapped_type>);
-
- // arrays + tables - invoke copy/move ctor
- if constexpr (is_one_of<unwrapped_type, array, table>)
- {
- return new unwrapped_type(static_cast<T&&>(val));
- }
-
- // values
- else
- {
- using native_type = native_type_of<unwrapped_type>;
- using value_type = value<native_type>;
-
- value_type* out;
-
- // copy/move ctor
- if constexpr (std::is_same_v<remove_cvref<T>, value_type>)
- {
- out = new value_type{ static_cast<T&&>(val), flags };
- }
-
- // creating from raw value
- else
- {
- static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Instantiating values from wide-character strings is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (!is_losslessly_convertible_to_native<unwrapped_type>)
- {
- if constexpr (std::is_same_v<native_type, int64_t>)
- static_assert(always_false<T>,
- "Integral value initializers must be losslessly convertible to int64_t");
- else if constexpr (std::is_same_v<native_type, double>)
- static_assert(always_false<T>,
- "Floating-point value initializers must be losslessly convertible to double");
- else
- static_assert(
- always_false<T>,
- "Value initializers must be losslessly convertible to one of the TOML value types");
- }
-
- if constexpr (is_wide_string<T>)
- {
+TOML_IMPL_NAMESPACE_START {
+ template <typename T>
+ TOML_NODISCARD TOML_ATTR(returns_nonnull) auto* make_node_impl_specialized(
+ T && val, [[maybe_unused]] value_flags flags) {
+ using unwrapped_type = unwrap_node<remove_cvref<T>>;
+ static_assert(!std::is_same_v<unwrapped_type, node>);
+ static_assert(!is_node_view<unwrapped_type>);
+
+ // arrays + tables - invoke copy/move ctor
+ if constexpr (is_one_of<unwrapped_type, array, table>) {
+ return new unwrapped_type(static_cast<T&&>(val));
+ }
+
+ // values
+ else {
+ using native_type = native_type_of<unwrapped_type>;
+ using value_type = value<native_type>;
+
+ value_type* out;
+
+ // copy/move ctor
+ if constexpr (std::is_same_v<remove_cvref<T>, value_type>) {
+ out = new value_type{static_cast<T&&>(val), flags};
+ }
+
+ // creating from raw value
+ else {
+ static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Instantiating values from wide-character strings is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (!is_losslessly_convertible_to_native<unwrapped_type>) {
+ if constexpr (std::is_same_v<native_type, int64_t>)
+ static_assert(always_false<T>,
+ "Integral value initializers must be losslessly convertible to int64_t");
+ else if constexpr (std::is_same_v<native_type, double>)
+ static_assert(
+ always_false<T>,
+ "Floating-point value initializers must be losslessly convertible to double");
+ else
+ static_assert(
+ always_false<T>,
+ "Value initializers must be losslessly convertible to one of the TOML value types");
+ }
+
+ if constexpr (is_wide_string<T>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- out = new value_type{ narrow(static_cast<T&&>(val)) };
+ out = new value_type{narrow(static_cast<T&&>(val))};
#else
- static_assert(always_false<T>, "Evaluated unreachable branch!");
+ static_assert(always_false<T>, "Evaluated unreachable branch!");
#endif
- }
- else
- out = new value_type{ static_cast<T&&>(val) };
-
- if (flags != preserve_source_value_flags)
- out->flags(flags);
- }
-
- return out;
- }
- }
-
- template <typename T>
- TOML_NODISCARD
- auto* make_node_impl(T && val, value_flags flags = preserve_source_value_flags)
- {
- using unwrapped_type = unwrap_node<remove_cvref<T>>;
- if constexpr (std::is_same_v<unwrapped_type, node> || is_node_view<unwrapped_type>)
- {
- if constexpr (is_node_view<unwrapped_type>)
- {
- if (!val)
- return static_cast<toml::node*>(nullptr);
- }
-
- return static_cast<T&&>(val).visit(
- [flags](auto&& concrete) {
- return static_cast<toml::node*>(
- make_node_impl_specialized(static_cast<decltype(concrete)&&>(concrete), flags));
- });
- }
- else
- return make_node_impl_specialized(static_cast<T&&>(val), flags);
- }
-
- template <typename T>
- TOML_NODISCARD
- auto* make_node_impl(inserter<T> && val, value_flags flags = preserve_source_value_flags)
- {
- return make_node_impl(static_cast<T&&>(val.value), flags);
- }
-
- template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> || can_partially_represent_native<T>)>
- struct inserted_type_of_
- {
- using type = std::remove_pointer_t<decltype(make_node_impl(std::declval<T>()))>;
- };
-
- template <typename T>
- struct inserted_type_of_<inserter<T>, false>
- {
- using type = typename inserted_type_of_<remove_cvref<T>>::type;
- };
-
- template <typename T>
- struct inserted_type_of_<T, false>
- {
- using type = void;
- };
-
- template <typename T>
- TOML_NODISCARD
- node_ptr make_node(T && val, value_flags flags = preserve_source_value_flags)
- {
- return node_ptr{ make_node_impl(static_cast<T&&>(val), flags) };
- }
-
- template <typename... T>
- struct emplaced_type_of_
- {
- using type = void;
- };
-
- template <typename T>
- struct emplaced_type_of_<T>
- {
- using type = std::conditional_t<is_one_of<T, node, node_view<node>, node_view<const node>>,
- void,
- typename inserted_type_of_<T>::type>;
- };
-
- template <typename T>
- struct emplaced_type_of_<inserter<T>>
- {
- using type = typename emplaced_type_of_<remove_cvref<T>>::type;
- };
-
- template <typename... T>
- using emplaced_type_of = typename emplaced_type_of_<remove_cvref<T>...>::type;
+ } else
+ out = new value_type{static_cast<T&&>(val)};
+
+ if (flags != preserve_source_value_flags) out->flags(flags);
+ }
+
+ return out;
+ }
+ }
+
+ template <typename T>
+ TOML_NODISCARD auto* make_node_impl(T && val, value_flags flags = preserve_source_value_flags) {
+ using unwrapped_type = unwrap_node<remove_cvref<T>>;
+ if constexpr (std::is_same_v<unwrapped_type, node> || is_node_view<unwrapped_type>) {
+ if constexpr (is_node_view<unwrapped_type>) {
+ if (!val) return static_cast<toml::node*>(nullptr);
+ }
+
+ return static_cast<T&&>(val).visit([flags](auto&& concrete) {
+ return static_cast<toml::node*>(
+ make_node_impl_specialized(static_cast<decltype(concrete)&&>(concrete), flags));
+ });
+ } else
+ return make_node_impl_specialized(static_cast<T&&>(val), flags);
+ }
+
+ template <typename T>
+ TOML_NODISCARD auto* make_node_impl(inserter<T> && val,
+ value_flags flags = preserve_source_value_flags) {
+ return make_node_impl(static_cast<T&&>(val.value), flags);
+ }
+
+ template <typename T, bool = (is_node<T> || is_node_view<T> || is_value<T> ||
+ can_partially_represent_native<T>)>
+ struct inserted_type_of_ {
+ using type = std::remove_pointer_t<decltype(make_node_impl(std::declval<T>()))>;
+ };
+
+ template <typename T>
+ struct inserted_type_of_<inserter<T>, false> {
+ using type = typename inserted_type_of_<remove_cvref<T>>::type;
+ };
+
+ template <typename T>
+ struct inserted_type_of_<T, false> {
+ using type = void;
+ };
+
+ template <typename T>
+ TOML_NODISCARD node_ptr make_node(T && val, value_flags flags = preserve_source_value_flags) {
+ return node_ptr{make_node_impl(static_cast<T&&>(val), flags)};
+ }
+
+ template <typename... T>
+ struct emplaced_type_of_ {
+ using type = void;
+ };
+
+ template <typename T>
+ struct emplaced_type_of_<T> {
+ using type = std::conditional_t<is_one_of<T, node, node_view<node>, node_view<const node>>,
+ void, typename inserted_type_of_<T>::type>;
+ };
+
+ template <typename T>
+ struct emplaced_type_of_<inserter<T>> {
+ using type = typename emplaced_type_of_<remove_cvref<T>>::type;
+ };
+
+ template <typename... T>
+ using emplaced_type_of = typename emplaced_type_of_<remove_cvref<T>...>::type;
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief Metafunction for determining which node type would be constructed
- /// if an object of this type was inserted into a toml::table or toml::array.
- ///
- /// \detail \cpp
- /// static_assert(std::is_same_v<toml::inserted_type_of<const char*>, toml::value<std::string>);
- /// static_assert(std::is_same_v<toml::inserted_type_of<int>, toml::value<int64_t>);
- /// static_assert(std::is_same_v<toml::inserted_type_of<float>, toml::value<double>);
- /// static_assert(std::is_same_v<toml::inserted_type_of<bool>, toml::value<bool>);
- /// \ecpp
- ///
- /// \note This will return toml::node for nodes and node_views, even though a more specific node subclass
- /// would actually be inserted. There is no way around this in a compile-time metafunction.
- template <typename T>
- using inserted_type_of = POXY_IMPLEMENTATION_DETAIL(typename impl::inserted_type_of_<impl::remove_cvref<T>>::type);
+TOML_NAMESPACE_START {
+ /// \brief Metafunction for determining which node type would be constructed
+ /// if an object of this type was inserted into a toml::table or toml::array.
+ ///
+ /// \detail \cpp
+ /// static_assert(std::is_same_v<toml::inserted_type_of<const char*>, toml::value<std::string>);
+ /// static_assert(std::is_same_v<toml::inserted_type_of<int>, toml::value<int64_t>);
+ /// static_assert(std::is_same_v<toml::inserted_type_of<float>, toml::value<double>);
+ /// static_assert(std::is_same_v<toml::inserted_type_of<bool>, toml::value<bool>);
+ /// \ecpp
+ ///
+ /// \note This will return toml::node for nodes and node_views, even though a more specific node
+ /// subclass
+ /// would actually be inserted. There is no way around this in a compile-time metafunction.
+ template <typename T>
+ using inserted_type_of =
+ POXY_IMPLEMENTATION_DETAIL(typename impl::inserted_type_of_<impl::remove_cvref<T>>::type);
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/node.hpp b/vendor/toml++/impl/node.hpp
index e4e316a..3ed1429 100644
--- a/vendor/toml++/impl/node.hpp
+++ b/vendor/toml++/impl/node.hpp
@@ -1,754 +1,733 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_utility.hpp"
#include "forward_declarations.hpp"
-#include "source_region.hpp"
#include "header_start.hpp"
+#include "source_region.hpp"
+#include "std_utility.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A TOML node.
- ///
- /// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
- /// This type is the base of each of those, providing a lot of the polymorphic plumbing.
- class TOML_ABSTRACT_INTERFACE TOML_EXPORTED_CLASS node
- {
- private:
- /// \cond
-
- friend class TOML_PARSER_TYPENAME;
- source_region source_{};
-
- template <typename T>
- TOML_NODISCARD
- decltype(auto) get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
-
- template <typename T, typename N>
- using ref_type_ = std::conditional_t< //
- std::is_reference_v<T>, //
- impl::copy_ref<impl::copy_cv<impl::unwrap_node<T>, std::remove_reference_t<N>>, T>, //
- impl::copy_cvref<impl::unwrap_node<T>, N> //
- >;
-
- template <typename T, typename N>
- using ref_type = std::conditional_t< //
- std::is_reference_v<N>, //
- ref_type_<T, N>, //
- ref_type_<T, std::add_lvalue_reference_t<N>> //
- >;
-
- template <typename T, typename N>
- TOML_PURE_GETTER
- static ref_type<T, N&&> do_ref(N&& n) noexcept
- {
- using unwrapped_type = impl::unwrap_node<T>;
- static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
- "The template type argument of node::ref() must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- TOML_ASSERT_ASSUME(
- n.template is<unwrapped_type>()
- && "template type argument provided to toml::node::ref() didn't match the node's actual type");
-
- using node_ref = std::remove_volatile_t<std::remove_reference_t<N>>&;
- using val_type = std::remove_volatile_t<unwrapped_type>;
- using out_ref = ref_type<T, N&&>;
- static_assert(std::is_reference_v<out_ref>);
-
- if constexpr (toml::is_value<unwrapped_type>)
- return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>().get());
- else
- return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>());
- }
-
- protected:
- TOML_EXPORTED_MEMBER_FUNCTION
- node() noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- node(const node&) noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- node(node&&) noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- node& operator=(const node&) noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- node& operator=(node&&) noexcept;
-
- template <typename T, typename N>
- using ref_cast_type_ = std::conditional_t< //
- std::is_reference_v<T>, //
- impl::copy_ref<impl::copy_cv<impl::wrap_node<T>, std::remove_reference_t<N>>, T>, //
- impl::copy_cvref<impl::wrap_node<T>, N> //
- >;
-
- template <typename T, typename N>
- using ref_cast_type = std::conditional_t< //
- std::is_reference_v<N>, //
- ref_cast_type_<T, N>, //
- ref_cast_type_<T, std::add_lvalue_reference_t<N>> //
- >;
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- ref_cast_type<T, node&> ref_cast() & noexcept
- {
- using out_ref = ref_cast_type<T, node&>;
- using out_type = std::remove_reference_t<out_ref>;
- return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
- }
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- ref_cast_type<T, node&&> ref_cast() && noexcept
- {
- using out_ref = ref_cast_type<T, node&&>;
- using out_type = std::remove_reference_t<out_ref>;
- return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
- }
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- ref_cast_type<T, const node&> ref_cast() const& noexcept
- {
- using out_ref = ref_cast_type<T, const node&>;
- using out_type = std::remove_reference_t<out_ref>;
- return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
- }
-
- template <typename T>
- TOML_PURE_INLINE_GETTER
- ref_cast_type<T, const node&&> ref_cast() const&& noexcept
- {
- using out_ref = ref_cast_type<T, const node&&>;
- using out_type = std::remove_reference_t<out_ref>;
- return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
- }
-
- /// \endcond
-
- public:
- TOML_EXPORTED_MEMBER_FUNCTION
- virtual ~node() noexcept;
-
- /// \name Type checks
- /// @{
-
- /// \brief Checks if a node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
- /// toml::array& arr = *cfg["arr"].as_array();
- ///
- /// toml::node* nonmatch{};
- /// if (arr.is_homogeneous(toml::node_type::integer, nonmatch))
- /// std::cout << "array was homogeneous"sv << "\n";
- /// else
- /// std::cout << "array was not homogeneous!\n"
- /// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
- /// \ecpp
- ///
- /// \out
- /// array was not homogeneous!
- /// first non-match was a floating-point at line 1, column 18
- /// \eout
- ///
- /// \param ntype A TOML node type. <br>
- /// \conditional_return{toml::node_type::none}
- /// "is every element the same type?"
- /// \conditional_return{Anything else}
- /// "is every element one of these?"
- ///
- /// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
- /// will be stored if the return value is false.
- ///
- /// \returns True if the node was homogeneous.
- ///
- /// \remarks Always returns `false` for empty tables and arrays.
- TOML_PURE_GETTER
- virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
-
- /// \brief Checks if a node contains values/elements of only one type (const overload).
- TOML_PURE_GETTER
- virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
-
- /// \brief Checks if the node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// 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";
- /// \ecpp
- ///
- /// \out
- /// homogeneous: true
- /// all floats: false
- /// all arrays: false
- /// all ints: true
- /// \eout
- ///
- /// \param ntype A TOML node type. <br>
- /// \conditional_return{toml::node_type::none}
- /// "is every element the same type?"
- /// \conditional_return{Anything else}
- /// "is every element one of these?"
- ///
- /// \returns True if the node was homogeneous.
- ///
- /// \remarks Always returns `false` for empty tables and arrays.
- TOML_PURE_GETTER
- virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
-
- /// \brief Checks if the node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto arr = toml::array{ 1, 2, 3 };
- /// 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";
- /// \ecpp
- ///
- /// \out
- /// homogeneous: true
- /// all floats: false
- /// all arrays: false
- /// all ints: true
- /// \eout
- ///
- /// \tparam ElemType A TOML node or value type. <br>
- /// \conditional_return{Left as `void`}
- /// "is every element the same type?" <br>
- /// \conditional_return{Explicitly specified}
- /// "is every element a T?"
- ///
- /// \returns True if the node was homogeneous.
- ///
- /// \remarks Always returns `false` for empty tables and arrays.
- template <typename ElemType = void>
- TOML_PURE_GETTER
- bool is_homogeneous() const noexcept
- {
- using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
- static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
- "The template type argument of node::is_homogeneous() must be void or one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- return is_homogeneous(impl::node_type_of<type>);
- }
-
- /// \brief Returns the node's type identifier.
- TOML_PURE_GETTER
- virtual node_type type() const noexcept = 0;
-
- /// \brief Returns true if this node is a table.
- TOML_PURE_GETTER
- virtual bool is_table() const noexcept = 0;
-
- /// \brief Returns true if this node is an array.
- TOML_PURE_GETTER
- virtual bool is_array() const noexcept = 0;
-
- /// \brief Returns true if this node is an array containing only tables.
- TOML_PURE_GETTER
- virtual bool is_array_of_tables() const noexcept = 0;
-
- /// \brief Returns true if this node is a value.
- TOML_PURE_GETTER
- virtual bool is_value() const noexcept = 0;
-
- /// \brief Returns true if this node is a string value.
- TOML_PURE_GETTER
- virtual bool is_string() const noexcept = 0;
-
- /// \brief Returns true if this node is an integer value.
- TOML_PURE_GETTER
- virtual bool is_integer() const noexcept = 0;
-
- /// \brief Returns true if this node is an floating-point value.
- TOML_PURE_GETTER
- virtual bool is_floating_point() const noexcept = 0;
-
- /// \brief Returns true if this node is an integer or floating-point value.
- TOML_PURE_GETTER
- virtual bool is_number() const noexcept = 0;
-
- /// \brief Returns true if this node is a boolean value.
- TOML_PURE_GETTER
- virtual bool is_boolean() const noexcept = 0;
-
- /// \brief Returns true if this node is a local date value.
- TOML_PURE_GETTER
- virtual bool is_date() const noexcept = 0;
-
- /// \brief Returns true if this node is a local time value.
- TOML_PURE_GETTER
- virtual bool is_time() const noexcept = 0;
-
- /// \brief Returns true if this node is a date-time value.
- TOML_PURE_GETTER
- virtual bool is_date_time() const noexcept = 0;
-
- /// \brief Checks if a node is a specific type.
- ///
- /// \tparam T A TOML node or value type.
- ///
- /// \returns Returns true if this node is an instance of the specified type.
- template <typename T>
- TOML_PURE_INLINE_GETTER
- bool is() const noexcept
- {
- using type = impl::remove_cvref<impl::unwrap_node<T>>;
- static_assert(toml::is_value<type> || toml::is_container<type>,
- "The template type argument of node::is() must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- if constexpr (std::is_same_v<type, table>)
- return is_table();
- else if constexpr (std::is_same_v<type, array>)
- return is_array();
- else if constexpr (std::is_same_v<type, std::string>)
- return is_string();
- else if constexpr (std::is_same_v<type, int64_t>)
- return is_integer();
- else if constexpr (std::is_same_v<type, double>)
- return is_floating_point();
- else if constexpr (std::is_same_v<type, bool>)
- return is_boolean();
- else if constexpr (std::is_same_v<type, date>)
- return is_date();
- else if constexpr (std::is_same_v<type, time>)
- return is_time();
- else if constexpr (std::is_same_v<type, date_time>)
- return is_date_time();
- }
-
- /// @}
-
- /// \name Type casts
- /// @{
-
- /// \brief Returns a pointer to the node as a toml::table, if it is one.
- TOML_PURE_GETTER
- virtual table* as_table() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::array, if it is one.
- TOML_PURE_GETTER
- virtual array* as_array() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<std::string>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<std::string>* as_string() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<int64_t>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<int64_t>* as_integer() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<double>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<double>* as_floating_point() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<bool>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<bool>* as_boolean() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<toml::date>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<date>* as_date() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<toml::time>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<time>* as_time() noexcept = 0;
-
- /// \brief Returns a pointer to the node as a toml::value<toml::date_time>, if it is one.
- TOML_PURE_GETTER
- virtual toml::value<date_time>* as_date_time() noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::table, if it is one.
- TOML_PURE_GETTER
- virtual const table* as_table() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::array, if it is one.
- TOML_PURE_GETTER
- virtual const array* as_array() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<std::string>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<std::string>* as_string() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<int64_t>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<int64_t>* as_integer() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<double>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<double>* as_floating_point() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<bool>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<bool>* as_boolean() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::date>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<date>* as_date() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::time>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<time>* as_time() const noexcept = 0;
-
- /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::date_time>, if it is one.
- TOML_PURE_GETTER
- virtual const toml::value<date_time>* as_date_time() const noexcept = 0;
-
- /// \brief Gets a pointer to the node as a more specific node type.
- ///
- /// \details \cpp
- ///
- /// toml::value<int64_t>* int_value = node->as<int64_t>();
- /// toml::table* tbl = node->as<toml::table>();
- /// if (int_value)
- /// std::cout << "Node is a value<int64_t>\n";
- /// else if (tbl)
- /// std::cout << "Node is a table\n";
- ///
- /// // fully-qualified value node types also work (useful for template code):
- /// toml::value<int64_t>* int_value2 = node->as<toml::value<int64_t>>();
- /// if (int_value2)
- /// std::cout << "Node is a value<int64_t>\n";
- /// \ecpp
- ///
- /// \tparam T The node type or TOML value type to cast to.
- ///
- /// \returns A pointer to the node as the given type, or nullptr if it was a different type.
- template <typename T>
- TOML_PURE_INLINE_GETTER
- impl::wrap_node<T>* as() noexcept
- {
- using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
- static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
- "The template type argument of node::as() must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- if constexpr (std::is_same_v<unwrapped_type, table>)
- return as_table();
- else if constexpr (std::is_same_v<unwrapped_type, array>)
- return as_array();
- else if constexpr (std::is_same_v<unwrapped_type, std::string>)
- return as_string();
- else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
- return as_integer();
- else if constexpr (std::is_same_v<unwrapped_type, double>)
- return as_floating_point();
- else if constexpr (std::is_same_v<unwrapped_type, bool>)
- return as_boolean();
- else if constexpr (std::is_same_v<unwrapped_type, date>)
- return as_date();
- else if constexpr (std::is_same_v<unwrapped_type, time>)
- return as_time();
- else if constexpr (std::is_same_v<unwrapped_type, date_time>)
- return as_date_time();
- }
-
- /// \brief Gets a pointer to the node as a more specific node type (const overload).
- template <typename T>
- TOML_PURE_INLINE_GETTER
- const impl::wrap_node<T>* as() const noexcept
- {
- using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
- static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
- "The template type argument of node::as() must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- if constexpr (std::is_same_v<unwrapped_type, table>)
- return as_table();
- else if constexpr (std::is_same_v<unwrapped_type, array>)
- return as_array();
- else if constexpr (std::is_same_v<unwrapped_type, std::string>)
- return as_string();
- else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
- return as_integer();
- else if constexpr (std::is_same_v<unwrapped_type, double>)
- return as_floating_point();
- else if constexpr (std::is_same_v<unwrapped_type, bool>)
- return as_boolean();
- else if constexpr (std::is_same_v<unwrapped_type, date>)
- return as_date();
- else if constexpr (std::is_same_v<unwrapped_type, time>)
- return as_time();
- else if constexpr (std::is_same_v<unwrapped_type, date_time>)
- return as_date_time();
- }
-
- /// @}
-
- /// \name Value retrieval
- /// @{
-
- /// \brief Gets the value contained by this node.
- ///
- /// \detail This function has 'exact' retrieval semantics; the only return value types allowed are the
- /// TOML native value types, or types that can losslessly represent a native value type (e.g.
- /// std::wstring on Windows).
- ///
- /// \tparam T One of the native TOML value types, or a type capable of losslessly representing one.
- ///
- /// \returns The underlying value if the node was a value of the
- /// matching type (or losslessly convertible to it), or an empty optional.
- ///
- /// \see node::value()
- template <typename T>
- TOML_NODISCARD
- optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
-
- /// \brief Gets the value contained by this node.
- ///
- /// \detail This function has 'permissive' retrieval semantics; some value types are allowed
- /// to convert to others (e.g. retrieving a boolean as an integer), and the specified return value
- /// type can be any type where a reasonable conversion from a native TOML value exists
- /// (e.g. std::wstring on Windows). If the source value cannot be represented by
- /// the destination type, an empty optional is returned.
- ///
- /// \godbolt{zzG81K}
- ///
- /// \cpp
- /// auto tbl = toml::parse(R"(
- /// int = -10
- /// flt = 25.0
- /// pi = 3.14159
- /// bool = false
- /// huge = 9223372036854775807
- /// str = "foo"
- /// )"sv);
- ///
- /// const auto print_value_with_typename =
- /// [&](std::string_view key, std::string_view type_name, auto* dummy)
- /// {
- /// std::cout << "- " << std::setw(18) << std::left << type_name;
- /// using type = std::remove_pointer_t<decltype(dummy)>;
- /// if (auto val = tbl.get(key)->value<type>(); val)
- /// std::cout << *val << "\n";
- /// else
- /// std::cout << "n/a\n";
- /// };
- ///
- /// #define print_value(key, T) print_value_with_typename(key, #T, (T*)nullptr)
- ///
- /// for (auto key : { "int", "flt", "pi", "bool", "huge", "str" })
- /// {
- /// std::cout << tbl[key].type() << " value '" << key << "' as:\n";
- /// print_value(key, bool);
- /// print_value(key, int);
- /// print_value(key, unsigned int);
- /// print_value(key, long long);
- /// print_value(key, float);
- /// print_value(key, double);
- /// print_value(key, std::string);
- /// print_value(key, std::string_view);
- /// print_value(key, const char*);
- /// std::cout << "\n";
- /// }
- /// \ecpp
- ///
- /// \out
- /// integer value 'int' as:
- /// - bool true
- /// - int -10
- /// - unsigned int n/a
- /// - long long -10
- /// - float -10
- /// - double -10
- /// - std::string n/a
- /// - std::string_view n/a
- /// - const char* n/a
- ///
- /// floating-point value 'flt' as:
- /// - bool n/a
- /// - int 25
- /// - unsigned int 25
- /// - long long 25
- /// - float 25
- /// - double 25
- /// - std::string n/a
- /// - std::string_view n/a
- /// - const char* n/a
- ///
- /// floating-point value 'pi' as:
- /// - bool n/a
- /// - int n/a
- /// - unsigned int n/a
- /// - long long n/a
- /// - float 3.14159
- /// - double 3.14159
- /// - std::string n/a
- /// - std::string_view n/a
- /// - const char* n/a
- ///
- /// boolean value 'bool' as:
- /// - bool false
- /// - int 0
- /// - unsigned int 0
- /// - long long 0
- /// - float n/a
- /// - double n/a
- /// - std::string n/a
- /// - std::string_view n/a
- /// - const char* n/a
- ///
- /// integer value 'huge' as:
- /// - bool true
- /// - int n/a
- /// - unsigned int n/a
- /// - long long 9223372036854775807
- /// - float n/a
- /// - double n/a
- /// - std::string n/a
- /// - std::string_view n/a
- /// - const char* n/a
- ///
- /// string value 'str' as:
- /// - bool n/a
- /// - int n/a
- /// - unsigned int n/a
- /// - long long n/a
- /// - float n/a
- /// - double n/a
- /// - std::string foo
- /// - std::string_view foo
- /// - const char* foo
- /// \eout
- ///
- /// \tparam T One of the native TOML value types, or a type capable of converting to one.
- ///
- /// \returns The underlying value if the node was a value of the matching type (or convertible to it)
- /// and within the range of the output type, or an empty optional.
- ///
- /// \note If you want strict value retrieval semantics that do not allow for any type conversions,
- /// use node::value_exact() instead.
- ///
- /// \see node::value_exact()
- template <typename T>
- TOML_NODISCARD
- optional<T> value() const noexcept(impl::value_retrieval_is_nothrow<T>);
-
- /// \brief Gets the raw value contained by this node, or a default.
- ///
- /// \tparam T Default value type. Must be one of the native TOML value types,
- /// or convertible to it.
- /// \param default_value The default value to return if the node wasn't a value, wasn't the
- /// correct type, or no conversion was possible.
- ///
- /// \returns The underlying value if the node was a value of the matching type (or convertible to it)
- /// and within the range of the output type, or the provided default.
- ///
- /// \note This function has the same permissive retrieval semantics as node::value(). If you want strict
- /// value retrieval semantics that do not allow for any type conversions, use node::value_exact()
- /// instead.
- ///
- /// \see
- /// - node::value()
- /// - node::value_exact()
- template <typename T>
- TOML_NODISCARD
- auto value_or(T&& default_value) const noexcept(impl::value_retrieval_is_nothrow<T>);
-
- /// \brief Gets a raw reference to a node's underlying data.
- ///
- /// \warning This function is dangerous if used carelessly and **WILL** break your code if the
- /// chosen value type doesn't match the node's actual type. In debug builds an assertion
- /// will fire when invalid accesses are attempted: \cpp
- ///
- /// auto tbl = toml::parse(R"(
- /// min = 32
- /// max = 45
- /// )"sv);
- ///
- /// int64_t& min_ref = tbl.at("min").ref<int64_t>(); // matching type
- /// double& max_ref = tbl.at("max").ref<double>(); // mismatched type, hits assert()
- /// \ecpp
- ///
- /// \note Specifying explicit ref qualifiers acts as an explicit ref-category cast,
- /// whereas specifying explicit cv-ref qualifiers merges them with whatever
- /// the cv qualification of the node is (to ensure cv-correctness is propagated), e.g.:
- /// | node | T | return type |
- /// |-------------|------------------------|------------------------------|
- /// | node& | std::string | std::string& |
- /// | node& | std::string&& | std::string&& |
- /// | const node& | volatile std::string | const volatile std::string& |
- /// | const node& | volatile std::string&& | const volatile std::string&& |
- ///
- /// \tparam T toml::table, toml::array, or one of the TOML value types.
- ///
- /// \returns A reference to the underlying data.
- template <typename T>
- TOML_PURE_GETTER
- decltype(auto) ref() & noexcept
- {
- return do_ref<T>(*this);
- }
-
- /// \brief Gets a raw reference to a node's underlying data (rvalue overload).
- template <typename T>
- TOML_PURE_GETTER
- decltype(auto) ref() && noexcept
- {
- return do_ref<T>(std::move(*this));
- }
-
- /// \brief Gets a raw reference to a node's underlying data (const lvalue overload).
- template <typename T>
- TOML_PURE_GETTER
- decltype(auto) ref() const& noexcept
- {
- return do_ref<T>(*this);
- }
-
- /// \brief Gets a raw reference to a node's underlying data (const rvalue overload).
- template <typename T>
- TOML_PURE_GETTER
- decltype(auto) ref() const&& noexcept
- {
- return do_ref<T>(std::move(*this));
- }
-
- /// @}
-
- /// \name Metadata
- /// @{
-
- /// \brief Returns the source region responsible for generating this node during parsing.
- TOML_PURE_INLINE_GETTER
- const source_region& source() const noexcept
- {
- return source_;
- }
-
- /// @}
-
- private:
- /// \cond
-
- template <typename Func, typename Node, typename T>
- static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
-
- template <typename Func, typename Node, typename T>
- static constexpr bool can_visit_nothrow = std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
-
- template <typename Func, typename Node>
- static constexpr bool can_visit_any = can_visit<Func, Node, table> //
- || can_visit<Func, Node, array> //
- || can_visit<Func, Node, std::string> //
- || can_visit<Func, Node, int64_t> //
- || can_visit<Func, Node, double> //
- || can_visit<Func, Node, bool> //
- || can_visit<Func, Node, date> //
- || can_visit<Func, Node, time> //
- || can_visit<Func, Node, date_time>;
-
- // clang-format off
+TOML_NAMESPACE_START {
+ /// \brief A TOML node.
+ ///
+ /// \detail A parsed TOML document forms a tree made up of tables, arrays and values.
+ /// This type is the base of each of those, providing a lot of the polymorphic plumbing.
+ class TOML_ABSTRACT_INTERFACE TOML_EXPORTED_CLASS node {
+ private:
+ /// \cond
+
+ friend class TOML_PARSER_TYPENAME;
+ source_region source_{};
+
+ template <typename T>
+ TOML_NODISCARD decltype(auto) get_value_exact() const
+ noexcept(impl::value_retrieval_is_nothrow<T>);
+
+ template <typename T, typename N>
+ using ref_type_ = std::conditional_t< //
+ std::is_reference_v<T>, //
+ impl::copy_ref<impl::copy_cv<impl::unwrap_node<T>, std::remove_reference_t<N>>, T>, //
+ impl::copy_cvref<impl::unwrap_node<T>, N> //
+ >;
+
+ template <typename T, typename N>
+ using ref_type = std::conditional_t< //
+ std::is_reference_v<N>, //
+ ref_type_<T, N>, //
+ ref_type_<T, std::add_lvalue_reference_t<N>> //
+ >;
+
+ template <typename T, typename N>
+ TOML_PURE_GETTER static ref_type<T, N&&> do_ref(N&& n) noexcept {
+ using unwrapped_type = impl::unwrap_node<T>;
+ static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
+ "The template type argument of node::ref() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ TOML_ASSERT_ASSUME(n.template is<unwrapped_type>() &&
+ "template type argument provided to toml::node::ref() didn't match the "
+ "node's actual type");
+
+ using node_ref = std::remove_volatile_t<std::remove_reference_t<N>>&;
+ using val_type = std::remove_volatile_t<unwrapped_type>;
+ using out_ref = ref_type<T, N&&>;
+ static_assert(std::is_reference_v<out_ref>);
+
+ if constexpr (toml::is_value<unwrapped_type>)
+ return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>().get());
+ else
+ return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>());
+ }
+
+ protected:
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node() noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node(const node&) noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node(node&&) noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node& operator=(const node&) noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node& operator=(node&&) noexcept;
+
+ template <typename T, typename N>
+ using ref_cast_type_ = std::conditional_t< //
+ std::is_reference_v<T>, //
+ impl::copy_ref<impl::copy_cv<impl::wrap_node<T>, std::remove_reference_t<N>>, T>, //
+ impl::copy_cvref<impl::wrap_node<T>, N> //
+ >;
+
+ template <typename T, typename N>
+ using ref_cast_type = std::conditional_t< //
+ std::is_reference_v<N>, //
+ ref_cast_type_<T, N>, //
+ ref_cast_type_<T, std::add_lvalue_reference_t<N>> //
+ >;
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER ref_cast_type<T, node&> ref_cast() & noexcept {
+ using out_ref = ref_cast_type<T, node&>;
+ using out_type = std::remove_reference_t<out_ref>;
+ return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
+ }
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER ref_cast_type<T, node&&> ref_cast() && noexcept {
+ using out_ref = ref_cast_type<T, node&&>;
+ using out_type = std::remove_reference_t<out_ref>;
+ return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
+ }
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER ref_cast_type<T, const node&> ref_cast() const& noexcept {
+ using out_ref = ref_cast_type<T, const node&>;
+ using out_type = std::remove_reference_t<out_ref>;
+ return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
+ }
+
+ template <typename T>
+ TOML_PURE_INLINE_GETTER ref_cast_type<T, const node&&> ref_cast() const&& noexcept {
+ using out_ref = ref_cast_type<T, const node&&>;
+ using out_type = std::remove_reference_t<out_ref>;
+ return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
+ }
+
+ /// \endcond
+
+ public:
+ TOML_EXPORTED_MEMBER_FUNCTION
+ virtual ~node() noexcept;
+
+ /// \name Type checks
+ /// @{
+
+ /// \brief Checks if a node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
+ /// toml::array& arr = *cfg["arr"].as_array();
+ ///
+ /// toml::node* nonmatch{};
+ /// if (arr.is_homogeneous(toml::node_type::integer, nonmatch))
+ /// std::cout << "array was homogeneous"sv << "\n";
+ /// else
+ /// std::cout << "array was not homogeneous!\n"
+ /// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// array was not homogeneous!
+ /// first non-match was a floating-point at line 1, column 18
+ /// \eout
+ ///
+ /// \param ntype A TOML node type. <br>
+ /// \conditional_return{toml::node_type::none}
+ /// "is every element the same type?"
+ /// \conditional_return{Anything else}
+ /// "is every element one of these?"
+ ///
+ /// \param first_nonmatch Reference to a pointer in which the address of the first non-matching
+ /// element will be stored if the return value is false.
+ ///
+ /// \returns True if the node was homogeneous.
+ ///
+ /// \remarks Always returns `false` for empty tables and arrays.
+ TOML_PURE_GETTER
+ virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
+
+ /// \brief Checks if a node contains values/elements of only one type (const overload).
+ TOML_PURE_GETTER
+ virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
+
+ /// \brief Checks if the node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// 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";
+ /// \ecpp
+ ///
+ /// \out
+ /// homogeneous: true
+ /// all floats: false
+ /// all arrays: false
+ /// all ints: true
+ /// \eout
+ ///
+ /// \param ntype A TOML node type. <br>
+ /// \conditional_return{toml::node_type::none}
+ /// "is every element the same type?"
+ /// \conditional_return{Anything else}
+ /// "is every element one of these?"
+ ///
+ /// \returns True if the node was homogeneous.
+ ///
+ /// \remarks Always returns `false` for empty tables and arrays.
+ TOML_PURE_GETTER
+ virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
+
+ /// \brief Checks if the node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto arr = toml::array{ 1, 2, 3 };
+ /// 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";
+ /// \ecpp
+ ///
+ /// \out
+ /// homogeneous: true
+ /// all floats: false
+ /// all arrays: false
+ /// all ints: true
+ /// \eout
+ ///
+ /// \tparam ElemType A TOML node or value type. <br>
+ /// \conditional_return{Left as `void`}
+ /// "is every element the same type?" <br>
+ /// \conditional_return{Explicitly specified}
+ /// "is every element a T?"
+ ///
+ /// \returns True if the node was homogeneous.
+ ///
+ /// \remarks Always returns `false` for empty tables and arrays.
+ template <typename ElemType = void>
+ TOML_PURE_GETTER bool is_homogeneous() const noexcept {
+ using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
+ static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
+ "The template type argument of node::is_homogeneous() must be void or one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ return is_homogeneous(impl::node_type_of<type>);
+ }
+
+ /// \brief Returns the node's type identifier.
+ TOML_PURE_GETTER
+ virtual node_type type() const noexcept = 0;
+
+ /// \brief Returns true if this node is a table.
+ TOML_PURE_GETTER
+ virtual bool is_table() const noexcept = 0;
+
+ /// \brief Returns true if this node is an array.
+ TOML_PURE_GETTER
+ virtual bool is_array() const noexcept = 0;
+
+ /// \brief Returns true if this node is an array containing only tables.
+ TOML_PURE_GETTER
+ virtual bool is_array_of_tables() const noexcept = 0;
+
+ /// \brief Returns true if this node is a value.
+ TOML_PURE_GETTER
+ virtual bool is_value() const noexcept = 0;
+
+ /// \brief Returns true if this node is a string value.
+ TOML_PURE_GETTER
+ virtual bool is_string() const noexcept = 0;
+
+ /// \brief Returns true if this node is an integer value.
+ TOML_PURE_GETTER
+ virtual bool is_integer() const noexcept = 0;
+
+ /// \brief Returns true if this node is an floating-point value.
+ TOML_PURE_GETTER
+ virtual bool is_floating_point() const noexcept = 0;
+
+ /// \brief Returns true if this node is an integer or floating-point value.
+ TOML_PURE_GETTER
+ virtual bool is_number() const noexcept = 0;
+
+ /// \brief Returns true if this node is a boolean value.
+ TOML_PURE_GETTER
+ virtual bool is_boolean() const noexcept = 0;
+
+ /// \brief Returns true if this node is a local date value.
+ TOML_PURE_GETTER
+ virtual bool is_date() const noexcept = 0;
+
+ /// \brief Returns true if this node is a local time value.
+ TOML_PURE_GETTER
+ virtual bool is_time() const noexcept = 0;
+
+ /// \brief Returns true if this node is a date-time value.
+ TOML_PURE_GETTER
+ virtual bool is_date_time() const noexcept = 0;
+
+ /// \brief Checks if a node is a specific type.
+ ///
+ /// \tparam T A TOML node or value type.
+ ///
+ /// \returns Returns true if this node is an instance of the specified type.
+ template <typename T>
+ TOML_PURE_INLINE_GETTER bool is() const noexcept {
+ using type = impl::remove_cvref<impl::unwrap_node<T>>;
+ static_assert(toml::is_value<type> || toml::is_container<type>,
+ "The template type argument of node::is() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ if constexpr (std::is_same_v<type, table>)
+ return is_table();
+ else if constexpr (std::is_same_v<type, array>)
+ return is_array();
+ else if constexpr (std::is_same_v<type, std::string>)
+ return is_string();
+ else if constexpr (std::is_same_v<type, int64_t>)
+ return is_integer();
+ else if constexpr (std::is_same_v<type, double>)
+ return is_floating_point();
+ else if constexpr (std::is_same_v<type, bool>)
+ return is_boolean();
+ else if constexpr (std::is_same_v<type, date>)
+ return is_date();
+ else if constexpr (std::is_same_v<type, time>)
+ return is_time();
+ else if constexpr (std::is_same_v<type, date_time>)
+ return is_date_time();
+ }
+
+ /// @}
+
+ /// \name Type casts
+ /// @{
+
+ /// \brief Returns a pointer to the node as a toml::table, if it is one.
+ TOML_PURE_GETTER
+ virtual table* as_table() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::array, if it is one.
+ TOML_PURE_GETTER
+ virtual array* as_array() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<std::string>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<std::string>* as_string() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<int64_t>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<int64_t>* as_integer() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<double>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<double>* as_floating_point() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<bool>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<bool>* as_boolean() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<toml::date>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<date>* as_date() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<toml::time>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<time>* as_time() noexcept = 0;
+
+ /// \brief Returns a pointer to the node as a toml::value<toml::date_time>, if it is one.
+ TOML_PURE_GETTER
+ virtual toml::value<date_time>* as_date_time() noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::table, if it is one.
+ TOML_PURE_GETTER
+ virtual const table* as_table() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::array, if it is one.
+ TOML_PURE_GETTER
+ virtual const array* as_array() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<std::string>, if it
+ /// is one.
+ TOML_PURE_GETTER
+ virtual const toml::value<std::string>* as_string() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<int64_t>, if it is
+ /// one.
+ TOML_PURE_GETTER
+ virtual const toml::value<int64_t>* as_integer() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<double>, if it is
+ /// one.
+ TOML_PURE_GETTER
+ virtual const toml::value<double>* as_floating_point() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<bool>, if it is one.
+ TOML_PURE_GETTER
+ virtual const toml::value<bool>* as_boolean() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::date>, if it is
+ /// one.
+ TOML_PURE_GETTER
+ virtual const toml::value<date>* as_date() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::time>, if it is
+ /// one.
+ TOML_PURE_GETTER
+ virtual const toml::value<time>* as_time() const noexcept = 0;
+
+ /// \brief Returns a const-qualified pointer to the node as a toml::value<toml::date_time>, if
+ /// it is one.
+ TOML_PURE_GETTER
+ virtual const toml::value<date_time>* as_date_time() const noexcept = 0;
+
+ /// \brief Gets a pointer to the node as a more specific node type.
+ ///
+ /// \details \cpp
+ ///
+ /// toml::value<int64_t>* int_value = node->as<int64_t>();
+ /// toml::table* tbl = node->as<toml::table>();
+ /// if (int_value)
+ /// std::cout << "Node is a value<int64_t>\n";
+ /// else if (tbl)
+ /// std::cout << "Node is a table\n";
+ ///
+ /// // fully-qualified value node types also work (useful for template code):
+ /// toml::value<int64_t>* int_value2 = node->as<toml::value<int64_t>>();
+ /// if (int_value2)
+ /// std::cout << "Node is a value<int64_t>\n";
+ /// \ecpp
+ ///
+ /// \tparam T The node type or TOML value type to cast to.
+ ///
+ /// \returns A pointer to the node as the given type, or nullptr if it was a different type.
+ template <typename T>
+ TOML_PURE_INLINE_GETTER impl::wrap_node<T>* as() noexcept {
+ using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
+ static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
+ "The template type argument of node::as() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ if constexpr (std::is_same_v<unwrapped_type, table>)
+ return as_table();
+ else if constexpr (std::is_same_v<unwrapped_type, array>)
+ return as_array();
+ else if constexpr (std::is_same_v<unwrapped_type, std::string>)
+ return as_string();
+ else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
+ return as_integer();
+ else if constexpr (std::is_same_v<unwrapped_type, double>)
+ return as_floating_point();
+ else if constexpr (std::is_same_v<unwrapped_type, bool>)
+ return as_boolean();
+ else if constexpr (std::is_same_v<unwrapped_type, date>)
+ return as_date();
+ else if constexpr (std::is_same_v<unwrapped_type, time>)
+ return as_time();
+ else if constexpr (std::is_same_v<unwrapped_type, date_time>)
+ return as_date_time();
+ }
+
+ /// \brief Gets a pointer to the node as a more specific node type (const overload).
+ template <typename T>
+ TOML_PURE_INLINE_GETTER const impl::wrap_node<T>* as() const noexcept {
+ using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
+ static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
+ "The template type argument of node::as() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ if constexpr (std::is_same_v<unwrapped_type, table>)
+ return as_table();
+ else if constexpr (std::is_same_v<unwrapped_type, array>)
+ return as_array();
+ else if constexpr (std::is_same_v<unwrapped_type, std::string>)
+ return as_string();
+ else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
+ return as_integer();
+ else if constexpr (std::is_same_v<unwrapped_type, double>)
+ return as_floating_point();
+ else if constexpr (std::is_same_v<unwrapped_type, bool>)
+ return as_boolean();
+ else if constexpr (std::is_same_v<unwrapped_type, date>)
+ return as_date();
+ else if constexpr (std::is_same_v<unwrapped_type, time>)
+ return as_time();
+ else if constexpr (std::is_same_v<unwrapped_type, date_time>)
+ return as_date_time();
+ }
+
+ /// @}
+
+ /// \name Value retrieval
+ /// @{
+
+ /// \brief Gets the value contained by this node.
+ ///
+ /// \detail This function has 'exact' retrieval semantics; the only return value types allowed
+ /// are the TOML native value types, or types that can losslessly represent a native value type
+ /// (e.g. std::wstring on Windows).
+ ///
+ /// \tparam T One of the native TOML value types, or a type capable of losslessly representing
+ /// one.
+ ///
+ /// \returns The underlying value if the node was a value of the
+ /// matching type (or losslessly convertible to it), or an empty optional.
+ ///
+ /// \see node::value()
+ template <typename T>
+ TOML_NODISCARD optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
+
+ /// \brief Gets the value contained by this node.
+ ///
+ /// \detail This function has 'permissive' retrieval semantics; some value types are allowed
+ /// to convert to others (e.g. retrieving a boolean as an integer), and the specified return
+ /// value type can be any type where a reasonable conversion from a native TOML value exists
+ /// (e.g. std::wstring on Windows). If the source value cannot be represented by
+ /// the destination type, an empty optional is returned.
+ ///
+ /// \godbolt{zzG81K}
+ ///
+ /// \cpp
+ /// auto tbl = toml::parse(R"(
+ /// int = -10
+ /// flt = 25.0
+ /// pi = 3.14159
+ /// bool = false
+ /// huge = 9223372036854775807
+ /// str = "foo"
+ /// )"sv);
+ ///
+ /// const auto print_value_with_typename =
+ /// [&](std::string_view key, std::string_view type_name, auto* dummy)
+ /// {
+ /// std::cout << "- " << std::setw(18) << std::left << type_name;
+ /// using type = std::remove_pointer_t<decltype(dummy)>;
+ /// if (auto val = tbl.get(key)->value<type>(); val)
+ /// std::cout << *val << "\n";
+ /// else
+ /// std::cout << "n/a\n";
+ /// };
+ ///
+ /// #define print_value(key, T) print_value_with_typename(key, #T, (T*)nullptr)
+ ///
+ /// for (auto key : { "int", "flt", "pi", "bool", "huge", "str" })
+ /// {
+ /// std::cout << tbl[key].type() << " value '" << key << "' as:\n";
+ /// print_value(key, bool);
+ /// print_value(key, int);
+ /// print_value(key, unsigned int);
+ /// print_value(key, long long);
+ /// print_value(key, float);
+ /// print_value(key, double);
+ /// print_value(key, std::string);
+ /// print_value(key, std::string_view);
+ /// print_value(key, const char*);
+ /// std::cout << "\n";
+ /// }
+ /// \ecpp
+ ///
+ /// \out
+ /// integer value 'int' as:
+ /// - bool true
+ /// - int -10
+ /// - unsigned int n/a
+ /// - long long -10
+ /// - float -10
+ /// - double -10
+ /// - std::string n/a
+ /// - std::string_view n/a
+ /// - const char* n/a
+ ///
+ /// floating-point value 'flt' as:
+ /// - bool n/a
+ /// - int 25
+ /// - unsigned int 25
+ /// - long long 25
+ /// - float 25
+ /// - double 25
+ /// - std::string n/a
+ /// - std::string_view n/a
+ /// - const char* n/a
+ ///
+ /// floating-point value 'pi' as:
+ /// - bool n/a
+ /// - int n/a
+ /// - unsigned int n/a
+ /// - long long n/a
+ /// - float 3.14159
+ /// - double 3.14159
+ /// - std::string n/a
+ /// - std::string_view n/a
+ /// - const char* n/a
+ ///
+ /// boolean value 'bool' as:
+ /// - bool false
+ /// - int 0
+ /// - unsigned int 0
+ /// - long long 0
+ /// - float n/a
+ /// - double n/a
+ /// - std::string n/a
+ /// - std::string_view n/a
+ /// - const char* n/a
+ ///
+ /// integer value 'huge' as:
+ /// - bool true
+ /// - int n/a
+ /// - unsigned int n/a
+ /// - long long 9223372036854775807
+ /// - float n/a
+ /// - double n/a
+ /// - std::string n/a
+ /// - std::string_view n/a
+ /// - const char* n/a
+ ///
+ /// string value 'str' as:
+ /// - bool n/a
+ /// - int n/a
+ /// - unsigned int n/a
+ /// - long long n/a
+ /// - float n/a
+ /// - double n/a
+ /// - std::string foo
+ /// - std::string_view foo
+ /// - const char* foo
+ /// \eout
+ ///
+ /// \tparam T One of the native TOML value types, or a type capable of converting to one.
+ ///
+ /// \returns The underlying value if the node was a value of the matching type (or convertible
+ /// to it) and within the range of the output type, or an empty optional.
+ ///
+ /// \note If you want strict value retrieval semantics that do not allow for any type
+ /// conversions, use node::value_exact() instead.
+ ///
+ /// \see node::value_exact()
+ template <typename T>
+ TOML_NODISCARD optional<T> value() const noexcept(impl::value_retrieval_is_nothrow<T>);
+
+ /// \brief Gets the raw value contained by this node, or a default.
+ ///
+ /// \tparam T Default value type. Must be one of the native TOML value types,
+ /// or convertible to it.
+ /// \param default_value The default value to return if the node wasn't a value, wasn't the
+ /// correct type, or no conversion was possible.
+ ///
+ /// \returns The underlying value if the node was a value of the matching type (or convertible
+ /// to it) and within the range of the output type, or the provided default.
+ ///
+ /// \note This function has the same permissive retrieval semantics as node::value(). If you
+ /// want strict value retrieval semantics that do not allow for any type conversions, use
+ /// node::value_exact() instead.
+ ///
+ /// \see
+ /// - node::value()
+ /// - node::value_exact()
+ template <typename T>
+ TOML_NODISCARD auto value_or(T&& default_value) const
+ noexcept(impl::value_retrieval_is_nothrow<T>);
+
+ /// \brief Gets a raw reference to a node's underlying data.
+ ///
+ /// \warning This function is dangerous if used carelessly and **WILL** break your code if the
+ /// chosen value type doesn't match the node's actual type. In debug builds an assertion
+ /// will fire when invalid accesses are attempted: \cpp
+ ///
+ /// auto tbl = toml::parse(R"(
+ /// min = 32
+ /// max = 45
+ /// )"sv);
+ ///
+ /// int64_t& min_ref = tbl.at("min").ref<int64_t>(); // matching type
+ /// double& max_ref = tbl.at("max").ref<double>(); // mismatched type, hits assert()
+ /// \ecpp
+ ///
+ /// \note Specifying explicit ref qualifiers acts as an explicit ref-category cast,
+ /// whereas specifying explicit cv-ref qualifiers merges them with whatever
+ /// the cv qualification of the node is (to ensure cv-correctness is propagated), e.g.:
+ /// | node | T | return type |
+ /// |-------------|------------------------|------------------------------|
+ /// | node& | std::string | std::string& |
+ /// | node& | std::string&& | std::string&& |
+ /// | const node& | volatile std::string | const volatile std::string& |
+ /// | const node& | volatile std::string&& | const volatile std::string&& |
+ ///
+ /// \tparam T toml::table, toml::array, or one of the TOML value types.
+ ///
+ /// \returns A reference to the underlying data.
+ template <typename T>
+ TOML_PURE_GETTER decltype(auto) ref() & noexcept {
+ return do_ref<T>(*this);
+ }
+
+ /// \brief Gets a raw reference to a node's underlying data (rvalue overload).
+ template <typename T>
+ TOML_PURE_GETTER decltype(auto) ref() && noexcept {
+ return do_ref<T>(std::move(*this));
+ }
+
+ /// \brief Gets a raw reference to a node's underlying data (const lvalue overload).
+ template <typename T>
+ TOML_PURE_GETTER decltype(auto) ref() const& noexcept {
+ return do_ref<T>(*this);
+ }
+
+ /// \brief Gets a raw reference to a node's underlying data (const rvalue overload).
+ template <typename T>
+ TOML_PURE_GETTER decltype(auto) ref() const&& noexcept {
+ return do_ref<T>(std::move(*this));
+ }
+
+ /// @}
+
+ /// \name Metadata
+ /// @{
+
+ /// \brief Returns the source region responsible for generating this node during parsing.
+ TOML_PURE_INLINE_GETTER
+ const source_region& source() const noexcept { return source_; }
+
+ /// @}
+
+ private:
+ /// \cond
+
+ template <typename Func, typename Node, typename T>
+ static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
+
+ template <typename Func, typename Node, typename T>
+ static constexpr bool can_visit_nothrow =
+ std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
+
+ template <typename Func, typename Node>
+ static constexpr bool can_visit_any = can_visit<Func, Node, table> //
+ || can_visit<Func, Node, array> //
+ || can_visit<Func, Node, std::string> //
+ || can_visit<Func, Node, int64_t> //
+ || can_visit<Func, Node, double> //
+ || can_visit<Func, Node, bool> //
+ || can_visit<Func, Node, date> //
+ || can_visit<Func, Node, time> //
+ || can_visit<Func, Node, date_time>;
+
+ // clang-format off
template <typename Func, typename Node>
static constexpr bool can_visit_all = can_visit<Func, Node, table> //
@@ -775,86 +754,87 @@ TOML_NAMESPACE_START
&& visit_is_nothrow_one<Func, Node, time> //
&& visit_is_nothrow_one<Func, Node, date_time>;
- // clang-format on
-
- template <typename Func, typename Node, typename T, bool = can_visit<Func, Node, T>>
- struct visit_return_type_
- {
- using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
- };
- template <typename Func, typename Node, typename T>
- struct visit_return_type_<Func, Node, T, false>
- {
- using type = void;
- };
-
- template <typename Func, typename Node, typename T>
- using visit_return_type = typename visit_return_type_<Func, Node, T>::type;
-
- template <typename A, typename B>
- using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
-
- template <typename Func, typename Node>
- static decltype(auto) do_visit(Func&& visitor, Node&& n) noexcept(visit_is_nothrow<Func&&, Node&&>)
- {
- static_assert(can_visit_any<Func&&, Node&&>,
- "TOML node visitors must be invocable for at least one of the toml::node "
- "specializations:" TOML_SA_NODE_TYPE_LIST);
-
- switch (n.type())
- {
- case node_type::table:
- if constexpr (can_visit<Func&&, Node&&, table>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<table>());
- break;
-
- case node_type::array:
- if constexpr (can_visit<Func&&, Node&&, array>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<array>());
- break;
-
- case node_type::string:
- if constexpr (can_visit<Func&&, Node&&, std::string>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<std::string>());
- break;
-
- case node_type::integer:
- if constexpr (can_visit<Func&&, Node&&, int64_t>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<int64_t>());
- break;
-
- case node_type::floating_point:
- if constexpr (can_visit<Func&&, Node&&, double>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<double>());
- break;
-
- case node_type::boolean:
- if constexpr (can_visit<Func&&, Node&&, bool>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<bool>());
- break;
-
- case node_type::date:
- if constexpr (can_visit<Func&&, Node&&, date>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date>());
- break;
-
- case node_type::time:
- if constexpr (can_visit<Func&&, Node&&, time>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<time>());
- break;
-
- case node_type::date_time:
- if constexpr (can_visit<Func&&, Node&&, date_time>)
- return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date_time>());
- break;
-
- case node_type::none: TOML_UNREACHABLE;
- default: TOML_UNREACHABLE;
- }
-
- if constexpr (!can_visit_all<Func&&, Node&&>)
- {
- // clang-format off
+ // clang-format on
+
+ template <typename Func, typename Node, typename T, bool = can_visit<Func, Node, T>>
+ struct visit_return_type_ {
+ using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
+ };
+ template <typename Func, typename Node, typename T>
+ struct visit_return_type_<Func, Node, T, false> {
+ using type = void;
+ };
+
+ template <typename Func, typename Node, typename T>
+ using visit_return_type = typename visit_return_type_<Func, Node, T>::type;
+
+ template <typename A, typename B>
+ using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
+
+ template <typename Func, typename Node>
+ static decltype(auto) do_visit(Func&& visitor,
+ Node&& n) noexcept(visit_is_nothrow<Func&&, Node&&>) {
+ static_assert(can_visit_any<Func&&, Node&&>,
+ "TOML node visitors must be invocable for at least one of the toml::node "
+ "specializations:" TOML_SA_NODE_TYPE_LIST);
+
+ switch (n.type()) {
+ case node_type::table:
+ if constexpr (can_visit<Func&&, Node&&, table>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<table>());
+ break;
+
+ case node_type::array:
+ if constexpr (can_visit<Func&&, Node&&, array>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<array>());
+ break;
+
+ case node_type::string:
+ if constexpr (can_visit<Func&&, Node&&, std::string>)
+ return static_cast<Func&&>(visitor)(
+ static_cast<Node&&>(n).template ref_cast<std::string>());
+ break;
+
+ case node_type::integer:
+ if constexpr (can_visit<Func&&, Node&&, int64_t>)
+ return static_cast<Func&&>(visitor)(
+ static_cast<Node&&>(n).template ref_cast<int64_t>());
+ break;
+
+ case node_type::floating_point:
+ if constexpr (can_visit<Func&&, Node&&, double>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<double>());
+ break;
+
+ case node_type::boolean:
+ if constexpr (can_visit<Func&&, Node&&, bool>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<bool>());
+ break;
+
+ case node_type::date:
+ if constexpr (can_visit<Func&&, Node&&, date>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date>());
+ break;
+
+ case node_type::time:
+ if constexpr (can_visit<Func&&, Node&&, time>)
+ return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<time>());
+ break;
+
+ case node_type::date_time:
+ if constexpr (can_visit<Func&&, Node&&, date_time>)
+ return static_cast<Func&&>(visitor)(
+ static_cast<Node&&>(n).template ref_cast<date_time>());
+ break;
+
+ case node_type::none:
+ TOML_UNREACHABLE;
+ default:
+ TOML_UNREACHABLE;
+ }
+
+ if constexpr (!can_visit_all<Func&&, Node&&>) {
+ // clang-format off
using return_type =
nonvoid<visit_return_type<Func&&, Node&&, table>,
@@ -868,246 +848,244 @@ TOML_NAMESPACE_START
visit_return_type<Func&&, Node&&, date_time>
>>>>>>>>;
- // clang-format on
-
- if constexpr (!std::is_void_v<return_type>)
- {
- static_assert(std::is_default_constructible_v<return_type>,
- "Non-exhaustive visitors must return a default-constructible type, or void");
- return return_type{};
- }
- }
- }
-
- /// \endcond
-
- public:
- /// \name Visitation
- /// @{
-
- /// \brief Invokes a visitor on the node based on the node's concrete type.
- ///
- /// \details Visitation is useful when you expect
- /// a node to be one of a set number of types and need
- /// to handle these types differently. Using `visit()` allows
- /// you to eliminate some of the casting/conversion boilerplate: \cpp
- ///
- /// node.visit([](auto&& n)
- /// {
- /// if constexpr (toml::is_string<decltype(n)>)
- /// do_something_with_a_string(*n)); //n is a toml::value<std::string>
- /// else if constexpr (toml::is_integer<decltype(n)>)
- /// do_something_with_an_int(*n); //n is a toml::value<int64_t>
- /// });
- /// \ecpp
- ///
- /// Visitor functions need not be generic; specifying a concrete node type as the input argument type
- /// effectively acts a 'filter', only invoking the visitor if the concrete type is compatible.
- /// Thus the example above can be re-written as: \cpp
- /// node.visit([](toml::value<std::string>& s) { do_something_with_a_string(*s)); });
- /// node.visit([](toml::value<int64_t>& i) { do_something_with_an_int(*i)); });
- /// \ecpp
- ///
- /// \tparam Func A callable type invocable with one or more of the toml++ node types.
- ///
- /// \param visitor The visitor object.
- ///
- /// \returns The return value of the visitor.
- /// Can be void. Non-exhaustive visitors must return a default-constructible type.
- ///
- /// \see https://en.wikipedia.org/wiki/Visitor_pattern
- template <typename Func>
- decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>)
- {
- return do_visit(static_cast<Func&&>(visitor), *this);
- }
-
- /// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
- template <typename Func>
- decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>)
- {
- return do_visit(static_cast<Func&&>(visitor), static_cast<node&&>(*this));
- }
-
- /// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue overload).
- template <typename Func>
- decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>)
- {
- return do_visit(static_cast<Func&&>(visitor), *this);
- }
-
- /// \brief Invokes a visitor on the node based on the node's concrete type (const rvalue overload).
- template <typename Func>
- decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>)
- {
- return do_visit(static_cast<Func&&>(visitor), static_cast<const node&&>(*this));
- }
-
- /// @}
-
- /// \name Node views
- /// @{
-
- /// \brief Creates a node_view pointing to this node.
- TOML_NODISCARD
- explicit operator node_view<node>() noexcept;
-
- /// \brief Creates a node_view pointing to this node (const overload).
- TOML_NODISCARD
- explicit operator node_view<const node>() const noexcept;
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \detail \cpp
- /// auto config = toml::parse(R"(
- ///
- /// [foo]
- /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- ///
- /// )"sv);
- ///
- /// std::cout << config.at_path("foo.bar[2]") << "\n";
- /// std::cout << config.at_path("foo.bar[3][0]") << "\n";
- /// std::cout << config.at_path("foo.bar[4].kek") << "\n";
- /// \ecpp
- ///
- /// \out
- /// 2
- /// 3
- /// 4
- /// \eout
- ///
- ///
- /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
- /// \cpp
- /// config.at_path( "foo.bar") // same as node_view{ config }["foo"]["bar"]
- /// config.at_path( "foo. bar") // same as node_view{ config }["foo"][" bar"]
- /// config.at_path( "foo..bar") // same as node_view{ config }["foo"][""]["bar"]
- /// config.at_path( ".foo.bar") // same as node_view{ config }[""]["foo"]["bar"]
- /// \ecpp
- /// <br>
- /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
- /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
- /// If you have periods in your table keys, first consider:
- /// 1. Not doing that
- /// 2. Using node_view::operator[] instead.
- ///
- /// \param path The "TOML path" to traverse.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<node> at_path(std::string_view path) noexcept;
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #at_path(std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<const node> at_path(std::string_view path) const noexcept;
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \detail \cpp
- /// auto config = toml::parse(R"(
- ///
- /// [foo]
- /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- ///
- /// )"sv);
- ///
- /// toml::path path1("foo.bar[2]");
- /// toml::path path2("foo.bar[4].kek");
- /// std::cout << config.at_path(path1) << "\n";
- /// std::cout << config.at_path(path1.parent_path()) << "\n";
- /// std::cout << config.at_path(path2) << "\n";
- /// std::cout << config.at_path(path2.parent_path()) << "\n";
- /// \ecpp
- ///
- /// \out
- /// 2
- /// [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- /// 4
- /// { kek = 4 }
- /// \eout
- ///
- ///
- /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
- /// \cpp
- /// config.at_path(toml::path("foo.bar")) // same as node_view{ config }["foo"]["bar"]
- /// config.at_path(toml::path("foo. bar")) // same as node_view{ config }["foo"][" bar"]
- /// config.at_path(toml::path("foo..bar")) // same as node_view{ config }["foo"][""]["bar"]
- /// config.at_path(toml::path(".foo.bar")) // same as node_view{ config }[""]["foo"]["bar"]
- /// \ecpp
- /// <br>
- /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
- /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
- ///
- /// \param path The "TOML path" to traverse.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<node> at_path(const toml::path& path) noexcept;
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #at_path(const toml::path&)
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<const node> at_path(const toml::path& path) const noexcept;
+ // clang-format on
+
+ if constexpr (!std::is_void_v<return_type>) {
+ static_assert(
+ std::is_default_constructible_v<return_type>,
+ "Non-exhaustive visitors must return a default-constructible type, or void");
+ return return_type{};
+ }
+ }
+ }
+
+ /// \endcond
+
+ public:
+ /// \name Visitation
+ /// @{
+
+ /// \brief Invokes a visitor on the node based on the node's concrete type.
+ ///
+ /// \details Visitation is useful when you expect
+ /// a node to be one of a set number of types and need
+ /// to handle these types differently. Using `visit()` allows
+ /// you to eliminate some of the casting/conversion boilerplate: \cpp
+ ///
+ /// node.visit([](auto&& n)
+ /// {
+ /// if constexpr (toml::is_string<decltype(n)>)
+ /// do_something_with_a_string(*n)); //n is a toml::value<std::string>
+ /// else if constexpr (toml::is_integer<decltype(n)>)
+ /// do_something_with_an_int(*n); //n is a toml::value<int64_t>
+ /// });
+ /// \ecpp
+ ///
+ /// Visitor functions need not be generic; specifying a concrete node type as the input argument
+ /// type effectively acts a 'filter', only invoking the visitor if the concrete type is
+ /// compatible. Thus the example above can be re-written as: \cpp
+ /// node.visit([](toml::value<std::string>& s) { do_something_with_a_string(*s)); });
+ /// node.visit([](toml::value<int64_t>& i) { do_something_with_an_int(*i)); });
+ /// \ecpp
+ ///
+ /// \tparam Func A callable type invocable with one or more of the toml++ node types.
+ ///
+ /// \param visitor The visitor object.
+ ///
+ /// \returns The return value of the visitor.
+ /// Can be void. Non-exhaustive visitors must return a default-constructible type.
+ ///
+ /// \see https://en.wikipedia.org/wiki/Visitor_pattern
+ template <typename Func>
+ decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>) {
+ return do_visit(static_cast<Func&&>(visitor), *this);
+ }
+
+ /// \brief Invokes a visitor on the node based on the node's concrete type (rvalue overload).
+ template <typename Func>
+ decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>) {
+ return do_visit(static_cast<Func&&>(visitor), static_cast<node&&>(*this));
+ }
+
+ /// \brief Invokes a visitor on the node based on the node's concrete type (const lvalue
+ /// overload).
+ template <typename Func>
+ decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>) {
+ return do_visit(static_cast<Func&&>(visitor), *this);
+ }
+
+ /// \brief Invokes a visitor on the node based on the node's concrete type (const rvalue
+ /// overload).
+ template <typename Func>
+ decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>) {
+ return do_visit(static_cast<Func&&>(visitor), static_cast<const node&&>(*this));
+ }
+
+ /// @}
+
+ /// \name Node views
+ /// @{
+
+ /// \brief Creates a node_view pointing to this node.
+ TOML_NODISCARD
+ explicit operator node_view<node>() noexcept;
+
+ /// \brief Creates a node_view pointing to this node (const overload).
+ TOML_NODISCARD
+ explicit operator node_view<const node>() const noexcept;
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \detail \cpp
+ /// auto config = toml::parse(R"(
+ ///
+ /// [foo]
+ /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ ///
+ /// )"sv);
+ ///
+ /// std::cout << config.at_path("foo.bar[2]") << "\n";
+ /// std::cout << config.at_path("foo.bar[3][0]") << "\n";
+ /// std::cout << config.at_path("foo.bar[4].kek") << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 2
+ /// 3
+ /// 4
+ /// \eout
+ ///
+ ///
+ /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
+ /// \cpp
+ /// config.at_path( "foo.bar") // same as node_view{ config }["foo"]["bar"]
+ /// config.at_path( "foo. bar") // same as node_view{ config }["foo"][" bar"]
+ /// config.at_path( "foo..bar") // same as node_view{ config }["foo"][""]["bar"]
+ /// config.at_path( ".foo.bar") // same as node_view{ config }[""]["foo"]["bar"]
+ /// \ecpp
+ /// <br>
+ /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted
+ /// strings. This function makes no allowance for this, instead treating all period characters
+ /// as sub-table delimiters. If you have periods in your table keys, first consider:
+ /// 1. Not doing that
+ /// 2. Using node_view::operator[] instead.
+ ///
+ /// \param path The "TOML path" to traverse.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<node> at_path(std::string_view path) noexcept;
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #at_path(std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<const node> at_path(std::string_view path) const noexcept;
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \detail \cpp
+ /// auto config = toml::parse(R"(
+ ///
+ /// [foo]
+ /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ ///
+ /// )"sv);
+ ///
+ /// toml::path path1("foo.bar[2]");
+ /// toml::path path2("foo.bar[4].kek");
+ /// std::cout << config.at_path(path1) << "\n";
+ /// std::cout << config.at_path(path1.parent_path()) << "\n";
+ /// std::cout << config.at_path(path2) << "\n";
+ /// std::cout << config.at_path(path2.parent_path()) << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 2
+ /// [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ /// 4
+ /// { kek = 4 }
+ /// \eout
+ ///
+ ///
+ /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
+ /// \cpp
+ /// config.at_path(toml::path("foo.bar")) // same as node_view{ config }["foo"]["bar"]
+ /// config.at_path(toml::path("foo. bar")) // same as node_view{ config }["foo"][" bar"]
+ /// config.at_path(toml::path("foo..bar")) // same as node_view{ config }["foo"][""]["bar"]
+ /// config.at_path(toml::path(".foo.bar")) // same as node_view{ config }[""]["foo"]["bar"]
+ /// \ecpp
+ /// <br>
+ /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted
+ /// strings. This function makes no allowance for this, instead treating all period characters
+ /// as sub-table delimiters.
+ ///
+ /// \param path The "TOML path" to traverse.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<node> at_path(const toml::path& path) noexcept;
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #at_path(const toml::path&)
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<const node> at_path(const toml::path& path) const noexcept;
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #at_path(std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<node> at_path(std::wstring_view path);
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #at_path(std::string_view)
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<const node> at_path(std::wstring_view path) const;
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \param path The "TOML path" to the desired child.
- ///
- /// \returns A view of the child node at the given path if one existed, or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<node> operator[](const toml::path& path) noexcept;
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \param path The "TOML path" to the desired child.
- ///
- /// \returns A view of the child node at the given path if one existed, or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node_view<const node> operator[](const toml::path& path) const noexcept;
-
- /// @}
- };
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #at_path(std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<node> at_path(std::wstring_view path);
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #at_path(std::string_view)
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<const node> at_path(std::wstring_view path) const;
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \param path The "TOML path" to the desired child.
+ ///
+ /// \returns A view of the child node at the given path if one existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<node> operator[](const toml::path& path) noexcept;
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \param path The "TOML path" to the desired child.
+ ///
+ /// \returns A view of the child node at the given path if one existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node_view<const node> operator[](const toml::path& path) const noexcept;
+
+ /// @}
+ };
}
TOML_NAMESPACE_END;
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- TOML_PURE_GETTER
- TOML_EXPORTED_FREE_FUNCTION
- bool TOML_CALLCONV node_deep_equality(const node*, const node*) noexcept;
+TOML_IMPL_NAMESPACE_START {
+ TOML_PURE_GETTER
+ TOML_EXPORTED_FREE_FUNCTION
+ bool TOML_CALLCONV node_deep_equality(const node*, const node*) noexcept;
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
diff --git a/vendor/toml++/impl/node_view.hpp b/vendor/toml++/impl/node_view.hpp
index fb63025..54599e1 100644
--- a/vendor/toml++/impl/node_view.hpp
+++ b/vendor/toml++/impl/node_view.hpp
@@ -1,837 +1,717 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_vector.hpp"
-#include "std_initializer_list.hpp"
-#include "print_to_stream.hpp"
-#include "node.hpp"
#include "header_start.hpp"
+#include "node.hpp"
+#include "print_to_stream.hpp"
+#include "std_initializer_list.hpp"
+#include "std_vector.hpp"
TOML_DISABLE_ARITHMETIC_WARNINGS;
-TOML_NAMESPACE_START
-{
- /// \brief A view of a node.
- ///
- /// \detail A node_view is like a std::optional<toml::node&> (if such a construct were legal), with lots of
- /// toml-specific stuff built-in. It _may_ represent a node, and allows you to do many of the
- /// same operations that you'd do on nodes directly, as well as easily traversing the node tree by creating
- /// subviews (via node_view::operator[]). \cpp
- ///
- /// auto tbl = toml::parse(R"(
- ///
- /// title = "my hardware store"
- ///
- /// [[products]]
- /// name = "Hammer"
- /// sku = 738594937
- /// keywords = [ "hammer", "construction", "build" ]
- ///
- /// [[products]]
- /// name = "Nail"
- /// sku = 284758393
- /// color = "gray"
- ///
- /// )"sv);
- ///
- /// std::cout << tbl["title"] << "\n";
- /// std::cout << tbl["products"][0]["name"] << "\n";
- /// std::cout << tbl["products"][0]["keywords"] << "\n";
- /// std::cout << tbl["products"][0]["keywords"][2] << "\n";
- ///
- /// tbl["products"][0]["keywords"].as_array()->push_back("heavy");
- /// std::cout << tbl["products"][0]["keywords"] << "\n";
- /// std::cout << "has product[2]: "sv << !!tbl["products"][2] << "\n";
- /// std::cout << "product[2]: "sv << tbl["products"][2] << "\n";
- /// \ecpp
- ///
- /// \out
- /// "my hardware store"
- /// "Hammer"
- /// [ "hammer", "construction", "build" ]
- /// "build"
- /// [ "hammer", "construction", "build", "heavy" ]
- /// has product[2]: false
- /// product[2]:
- /// \eout
- template <typename ViewedType>
- class TOML_TRIVIAL_ABI node_view
- {
- static_assert(impl::is_one_of<ViewedType, toml::node, const toml::node>,
- "A toml::node_view<> must wrap toml::node or const toml::node.");
-
- public:
- /// \brief The node type being viewed - either `node` or `const node`.
- using viewed_type = ViewedType;
-
- private:
- template <typename T>
- friend class node_view;
-
- mutable viewed_type* node_ = nullptr;
-
- public:
- /// \brief Constructs an empty node view.
- TOML_NODISCARD_CTOR
- node_view() noexcept = default;
-
- /// \brief Constructs node_view of a specific node.
- TOML_NODISCARD_CTOR
- explicit node_view(viewed_type* node) noexcept //
- : node_{ node }
- {}
-
- /// \brief Constructs node_view of a specific node.
- TOML_NODISCARD_CTOR
- explicit node_view(viewed_type& node) noexcept //
- : node_{ &node }
- {}
-
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- node_view(const node_view&) noexcept = default;
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- node_view(node_view&&) noexcept = default;
-
- /// \brief Copy-assignment operator.
- node_view& operator=(const node_view&) & noexcept = default;
-
- /// \brief Move-assignment operator.
- node_view& operator=(node_view&&) & noexcept = default;
-
- /// \brief Returns true if the view references a node.
- TOML_PURE_INLINE_GETTER
- explicit operator bool() const noexcept
- {
- return node_ != nullptr;
- }
-
- /// \brief Returns the node that's being referenced by the view.
- TOML_PURE_INLINE_GETTER
- viewed_type* node() const noexcept
- {
- return node_;
- }
-
- /// \name Type checks
- /// @{
-
- /// \brief Returns the type identifier for the viewed node.
- TOML_PURE_GETTER
- node_type type() const noexcept
- {
- return node_ ? node_->type() : node_type::none;
- }
-
- /// \brief Returns true if the viewed node is a toml::table.
- TOML_PURE_GETTER
- bool is_table() const noexcept
- {
- return node_ && node_->is_table();
- }
-
- /// \brief Returns true if the viewed node is a toml::array.
- TOML_PURE_GETTER
- bool is_array() const noexcept
- {
- return node_ && node_->is_array();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<>.
- TOML_PURE_GETTER
- bool is_value() const noexcept
- {
- return node_ && node_->is_value();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<string>.
- TOML_PURE_GETTER
- bool is_string() const noexcept
- {
- return node_ && node_->is_string();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<int64_t>.
- TOML_PURE_GETTER
- bool is_integer() const noexcept
- {
- return node_ && node_->is_integer();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<double>.
- TOML_PURE_GETTER
- bool is_floating_point() const noexcept
- {
- return node_ && node_->is_floating_point();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<int64_t> or toml::value<double>.
- TOML_PURE_GETTER
- bool is_number() const noexcept
- {
- return node_ && node_->is_number();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<bool>.
- TOML_PURE_GETTER
- bool is_boolean() const noexcept
- {
- return node_ && node_->is_boolean();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<date>.
- TOML_PURE_GETTER
- bool is_date() const noexcept
- {
- return node_ && node_->is_date();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<time>.
- TOML_PURE_GETTER
- bool is_time() const noexcept
- {
- return node_ && node_->is_time();
- }
-
- /// \brief Returns true if the viewed node is a toml::value<date_time>.
- TOML_PURE_GETTER
- bool is_date_time() const noexcept
- {
- return node_ && node_->is_date_time();
- }
-
- /// \brief Returns true if the viewed node is a toml::array that contains only tables.
- TOML_PURE_GETTER
- bool is_array_of_tables() const noexcept
- {
- return node_ && node_->is_array_of_tables();
- }
-
- /// \brief Checks if this view references a node of a specific type.
- ///
- /// \tparam T A TOML node or value type.
- ///
- /// \returns Returns true if the viewed node is an instance of the specified type.
- ///
- /// \see toml::node::is()
- template <typename T>
- TOML_PURE_GETTER
- bool is() const noexcept
- {
- return node_ ? node_->template is<impl::unwrap_node<impl::remove_cvref<T>>>() : false;
- }
-
- /// \brief Checks if the viewed node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
- ///
- /// toml::node* nonmatch{};
- /// if (cfg["arr"].is_homogeneous(toml::node_type::integer, nonmatch))
- /// std::cout << "array was homogeneous"sv << "\n";
- /// else
- /// std::cout << "array was not homogeneous!\n"
- /// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
- /// \ecpp
- ///
- /// \out
- /// array was not homogeneous!
- /// first non-match was a floating-point at line 1, column 18
- /// \eout
- ///
- /// \param ntype A TOML node type. <br>
- /// \conditional_return{toml::node_type::none} "is every element the same type?"
- /// \conditional_return{Anything else} "is every element one of these?"
- ///
- /// \param first_nonmatch Reference to a pointer in which the address of the first non-matching element
- /// will be stored if the return value is false.
- ///
- /// \returns True if the viewed node was homogeneous.
- ///
- /// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
- /// an empty table or array.
- TOML_NODISCARD
- bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch) const noexcept
- {
- if (!node_)
- {
- first_nonmatch = {};
- return false;
- }
- return node_->is_homogeneous(ntype, first_nonmatch);
- }
-
- /// \brief Checks if the viewed node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
- /// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous(toml::node_type::none) << "\n";
- /// std::cout << "all floats: "sv << cfg["arr"].is_homogeneous(toml::node_type::floating_point) << "\n";
- /// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous(toml::node_type::array) << "\n";
- /// std::cout << "all ints: "sv << cfg["arr"].is_homogeneous(toml::node_type::integer) << "\n";
- /// \ecpp
- ///
- /// \out
- /// homogeneous: true
- /// all floats: false
- /// all arrays: false
- /// all ints: true
- /// \eout
- ///
- /// \param ntype A TOML node type. <br>
- /// \conditional_return{toml::node_type::none} "is every element the same type?"
- /// \conditional_return{Anything else} "is every element one of these?"
- ///
- /// \returns True if the viewed node was homogeneous.
- ///
- /// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
- /// an empty table or array.
- TOML_NODISCARD
- bool is_homogeneous(node_type ntype) const noexcept
- {
- return node_ ? node_->is_homogeneous(ntype) : false;
- }
-
- /// \brief Checks if the viewed node contains values/elements of only one type.
- ///
- /// \detail \cpp
- /// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
- /// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous() << "\n";
- /// std::cout << "all doubles: "sv << cfg["arr"].is_homogeneous<double>() << "\n";
- /// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous<toml::array>() << "\n";
- /// std::cout << "all integers: "sv << cfg["arr"].is_homogeneous<int64_t>() << "\n";
- /// \ecpp
- ///
- /// \out
- /// homogeneous: true
- /// all floats: false
- /// all arrays: false
- /// all ints: true
- /// \eout
- ///
- /// \tparam ElemType A TOML node or value type. <br>
- /// \conditional_return{Left as `void`} "is every element the same type?" <br>
- /// \conditional_return{Explicitly specified} "is every element a T?"
- ///
- /// \returns True if the viewed node was homogeneous.
- ///
- /// \remarks Always returns `false` if the view does not reference a node, or if the viewed node is
- /// an empty table or array.
- template <typename ElemType = void>
- TOML_PURE_GETTER
- bool is_homogeneous() const noexcept
- {
- return node_ ? node_->template is_homogeneous<impl::unwrap_node<impl::remove_cvref<ElemType>>>() : false;
- }
-
- /// @}
-
- /// \name Type casts
- /// @{
-
- /// \brief Gets a pointer to the viewed node as a more specific node type.
- ///
- /// \tparam T The node type or TOML value type to cast to.
- ///
- /// \returns A pointer to the node as the given type, or nullptr if it was a different type.
- ///
- /// \see toml::node::as()
- template <typename T>
- TOML_PURE_GETTER
- auto* as() const noexcept
- {
- return node_ ? node_->template as<T>() : nullptr;
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::table, if it is one.
- TOML_PURE_GETTER
- auto* as_table() const noexcept
- {
- return as<table>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::array, if it is one.
- TOML_PURE_GETTER
- auto* as_array() const noexcept
- {
- return as<array>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<string>, if it is one.
- TOML_PURE_GETTER
- auto* as_string() const noexcept
- {
- return as<std::string>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<int64_t>, if it is one.
- TOML_PURE_GETTER
- auto* as_integer() const noexcept
- {
- return as<int64_t>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<double>, if it is one.
- TOML_PURE_GETTER
- auto* as_floating_point() const noexcept
- {
- return as<double>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<bool>, if it is one.
- TOML_PURE_GETTER
- auto* as_boolean() const noexcept
- {
- return as<bool>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<date>, if it is one.
- TOML_PURE_GETTER
- auto* as_date() const noexcept
- {
- return as<date>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<time>, if it is one.
- TOML_PURE_GETTER
- auto* as_time() const noexcept
- {
- return as<time>();
- }
-
- /// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
- TOML_PURE_GETTER
- auto* as_date_time() const noexcept
- {
- return as<date_time>();
- }
-
- /// @}
-
- /// \name Value retrieval
- /// @{
-
- /// \brief Gets the value contained by the referenced node.
- ///
- /// \detail This function has 'exact' retrieval semantics; the only return value types allowed are the
- /// TOML native value types, or types that can losslessly represent a native value type (e.g.
- /// std::wstring on Windows).
- ///
- /// \tparam T One of the native TOML value types, or a type capable of losslessly representing one.
- ///
- /// \returns The underlying value if the node was a value of the
- /// matching type (or losslessly convertible to it), or an empty optional.
- ///
- /// \see node_view::value()
- template <typename T>
- TOML_NODISCARD
- optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- if (node_)
- return node_->template value_exact<T>();
- return {};
- }
-
- /// \brief Gets the value contained by the referenced node.
- ///
- /// \detail This function has 'permissive' retrieval semantics; some value types are allowed
- /// to convert to others (e.g. retrieving a boolean as an integer), and the specified return value
- /// type can be any type where a reasonable conversion from a native TOML value exists
- /// (e.g. std::wstring on Windows). If the source value cannot be represented by
- /// the destination type, an empty optional is returned. See node::value() for examples.
- ///
- /// \tparam T One of the native TOML value types, or a type capable of convertible to one.
- ///
- /// \returns The underlying value if the node was a value of the matching type (or convertible to it)
- /// and within the range of the output type, or an empty optional.
- ///
- /// \note If you want strict value retrieval semantics that do not allow for any type conversions,
- /// use node_view::value_exact() instead.
- ///
- /// \see
- /// - node_view::value()
- /// - node_view::value_exact()
- template <typename T>
- TOML_NODISCARD
- optional<T> value() const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- if (node_)
- return node_->template value<T>();
- return {};
- }
-
- /// \brief Gets the raw value contained by the referenced node, or a default.
- ///
- /// \tparam T Default value type. Must be one of the native TOML value types,
- /// or convertible to it.
- /// \param default_value The default value to return if the node wasn't a value, wasn't the
- /// correct type, or no conversion was possible.
- ///
- /// \returns The underlying value if the node was a value of the matching type (or convertible to it)
- /// and within the range of the output type, or the provided default.
- ///
- /// \note This function has the same permissive retrieval semantics as node::value(). If you want strict
- /// value retrieval semantics that do not allow for any type conversions, use node_view::value_exact()
- /// instead.
- ///
- /// \see
- /// - node_view::value()
- /// - node_view::value_exact()
- template <typename T>
- TOML_NODISCARD
- auto value_or(T&& default_value) const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- using namespace ::toml::impl;
-
- static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Retrieving values as wide-character strings is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (is_wide_string<T>)
- {
+TOML_NAMESPACE_START {
+ /// \brief A view of a node.
+ ///
+ /// \detail A node_view is like a std::optional<toml::node&> (if such a construct were legal),
+ /// with lots of
+ /// toml-specific stuff built-in. It _may_ represent a node, and allows you to do many of the
+ /// same operations that you'd do on nodes directly, as well as easily traversing the node
+ ///tree by creating
+ /// subviews (via node_view::operator[]). \cpp
+ ///
+ /// auto tbl = toml::parse(R"(
+ ///
+ /// title = "my hardware store"
+ ///
+ /// [[products]]
+ /// name = "Hammer"
+ /// sku = 738594937
+ /// keywords = [ "hammer", "construction", "build" ]
+ ///
+ /// [[products]]
+ /// name = "Nail"
+ /// sku = 284758393
+ /// color = "gray"
+ ///
+ /// )"sv);
+ ///
+ /// std::cout << tbl["title"] << "\n";
+ /// std::cout << tbl["products"][0]["name"] << "\n";
+ /// std::cout << tbl["products"][0]["keywords"] << "\n";
+ /// std::cout << tbl["products"][0]["keywords"][2] << "\n";
+ ///
+ /// tbl["products"][0]["keywords"].as_array()->push_back("heavy");
+ /// std::cout << tbl["products"][0]["keywords"] << "\n";
+ /// std::cout << "has product[2]: "sv << !!tbl["products"][2] << "\n";
+ /// std::cout << "product[2]: "sv << tbl["products"][2] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// "my hardware store"
+ /// "Hammer"
+ /// [ "hammer", "construction", "build" ]
+ /// "build"
+ /// [ "hammer", "construction", "build", "heavy" ]
+ /// has product[2]: false
+ /// product[2]:
+ /// \eout
+ template <typename ViewedType>
+ class TOML_TRIVIAL_ABI node_view {
+ static_assert(impl::is_one_of<ViewedType, toml::node, const toml::node>,
+ "A toml::node_view<> must wrap toml::node or const toml::node.");
+
+ public:
+ /// \brief The node type being viewed - either `node` or `const node`.
+ using viewed_type = ViewedType;
+
+ private:
+ template <typename T>
+ friend class node_view;
+
+ mutable viewed_type* node_ = nullptr;
+
+ public:
+ /// \brief Constructs an empty node view.
+ TOML_NODISCARD_CTOR
+ node_view() noexcept = default;
+
+ /// \brief Constructs node_view of a specific node.
+ TOML_NODISCARD_CTOR
+ explicit node_view(viewed_type* node) noexcept //
+ : node_{node} {}
+
+ /// \brief Constructs node_view of a specific node.
+ TOML_NODISCARD_CTOR
+ explicit node_view(viewed_type& node) noexcept //
+ : node_{&node} {}
+
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ node_view(const node_view&) noexcept = default;
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ node_view(node_view&&) noexcept = default;
+
+ /// \brief Copy-assignment operator.
+ node_view& operator=(const node_view&) & noexcept = default;
+
+ /// \brief Move-assignment operator.
+ node_view& operator=(node_view&&) & noexcept = default;
+
+ /// \brief Returns true if the view references a node.
+ TOML_PURE_INLINE_GETTER
+ explicit operator bool() const noexcept { return node_ != nullptr; }
+
+ /// \brief Returns the node that's being referenced by the view.
+ TOML_PURE_INLINE_GETTER
+ viewed_type* node() const noexcept { return node_; }
+
+ /// \name Type checks
+ /// @{
+
+ /// \brief Returns the type identifier for the viewed node.
+ TOML_PURE_GETTER
+ node_type type() const noexcept { return node_ ? node_->type() : node_type::none; }
+
+ /// \brief Returns true if the viewed node is a toml::table.
+ TOML_PURE_GETTER
+ bool is_table() const noexcept { return node_ && node_->is_table(); }
+
+ /// \brief Returns true if the viewed node is a toml::array.
+ TOML_PURE_GETTER
+ bool is_array() const noexcept { return node_ && node_->is_array(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<>.
+ TOML_PURE_GETTER
+ bool is_value() const noexcept { return node_ && node_->is_value(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<string>.
+ TOML_PURE_GETTER
+ bool is_string() const noexcept { return node_ && node_->is_string(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<int64_t>.
+ TOML_PURE_GETTER
+ bool is_integer() const noexcept { return node_ && node_->is_integer(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<double>.
+ TOML_PURE_GETTER
+ bool is_floating_point() const noexcept { return node_ && node_->is_floating_point(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<int64_t> or toml::value<double>.
+ TOML_PURE_GETTER
+ bool is_number() const noexcept { return node_ && node_->is_number(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<bool>.
+ TOML_PURE_GETTER
+ bool is_boolean() const noexcept { return node_ && node_->is_boolean(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<date>.
+ TOML_PURE_GETTER
+ bool is_date() const noexcept { return node_ && node_->is_date(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<time>.
+ TOML_PURE_GETTER
+ bool is_time() const noexcept { return node_ && node_->is_time(); }
+
+ /// \brief Returns true if the viewed node is a toml::value<date_time>.
+ TOML_PURE_GETTER
+ bool is_date_time() const noexcept { return node_ && node_->is_date_time(); }
+
+ /// \brief Returns true if the viewed node is a toml::array that contains only tables.
+ TOML_PURE_GETTER
+ bool is_array_of_tables() const noexcept { return node_ && node_->is_array_of_tables(); }
+
+ /// \brief Checks if this view references a node of a specific type.
+ ///
+ /// \tparam T A TOML node or value type.
+ ///
+ /// \returns Returns true if the viewed node is an instance of the specified type.
+ ///
+ /// \see toml::node::is()
+ template <typename T>
+ TOML_PURE_GETTER bool is() const noexcept {
+ return node_ ? node_->template is<impl::unwrap_node<impl::remove_cvref<T>>>() : false;
+ }
+
+ /// \brief Checks if the viewed node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto cfg = toml::parse("arr = [ 1, 2, 3, 4.0 ]");
+ ///
+ /// toml::node* nonmatch{};
+ /// if (cfg["arr"].is_homogeneous(toml::node_type::integer, nonmatch))
+ /// std::cout << "array was homogeneous"sv << "\n";
+ /// else
+ /// std::cout << "array was not homogeneous!\n"
+ /// << "first non-match was a "sv << nonmatch->type() << " at " << nonmatch->source() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// array was not homogeneous!
+ /// first non-match was a floating-point at line 1, column 18
+ /// \eout
+ ///
+ /// \param ntype A TOML node type. <br>
+ /// \conditional_return{toml::node_type::none} "is every element the same type?"
+ /// \conditional_return{Anything else} "is every element one of these?"
+ ///
+ /// \param first_nonmatch Reference to a pointer in which the address of the first non-matching
+ /// element will be stored if the return value is false.
+ ///
+ /// \returns True if the viewed node was homogeneous.
+ ///
+ /// \remarks Always returns `false` if the view does not reference a node, or if the viewed
+ /// node is an empty table or array.
+ TOML_NODISCARD
+ bool is_homogeneous(node_type ntype, viewed_type*& first_nonmatch) const noexcept {
+ if (!node_) {
+ first_nonmatch = {};
+ return false;
+ }
+ return node_->is_homogeneous(ntype, first_nonmatch);
+ }
+
+ /// \brief Checks if the viewed node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
+ /// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous(toml::node_type::none) << "\n";
+ /// std::cout << "all floats: "sv << cfg["arr"].is_homogeneous(toml::node_type::floating_point)
+ /// << "\n"; std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous(toml::node_type::array)
+ /// << "\n"; std::cout << "all ints: "sv <<
+ /// cfg["arr"].is_homogeneous(toml::node_type::integer) << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// homogeneous: true
+ /// all floats: false
+ /// all arrays: false
+ /// all ints: true
+ /// \eout
+ ///
+ /// \param ntype A TOML node type. <br>
+ /// \conditional_return{toml::node_type::none} "is every element the same type?"
+ /// \conditional_return{Anything else} "is every element one of these?"
+ ///
+ /// \returns True if the viewed node was homogeneous.
+ ///
+ /// \remarks Always returns `false` if the view does not reference a node, or if the viewed
+ /// node is an empty table or array.
+ TOML_NODISCARD
+ bool is_homogeneous(node_type ntype) const noexcept {
+ return node_ ? node_->is_homogeneous(ntype) : false;
+ }
+
+ /// \brief Checks if the viewed node contains values/elements of only one type.
+ ///
+ /// \detail \cpp
+ /// auto cfg = toml::parse("arr = [ 1, 2, 3 ]");
+ /// std::cout << "homogenous: "sv << cfg["arr"].is_homogeneous() << "\n";
+ /// std::cout << "all doubles: "sv << cfg["arr"].is_homogeneous<double>() << "\n";
+ /// std::cout << "all arrays: "sv << cfg["arr"].is_homogeneous<toml::array>() << "\n";
+ /// std::cout << "all integers: "sv << cfg["arr"].is_homogeneous<int64_t>() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// homogeneous: true
+ /// all floats: false
+ /// all arrays: false
+ /// all ints: true
+ /// \eout
+ ///
+ /// \tparam ElemType A TOML node or value type. <br>
+ /// \conditional_return{Left as `void`} "is every element the same type?" <br>
+ /// \conditional_return{Explicitly specified} "is every element a T?"
+ ///
+ /// \returns True if the viewed node was homogeneous.
+ ///
+ /// \remarks Always returns `false` if the view does not reference a node, or if the viewed
+ /// node is an empty table or array.
+ template <typename ElemType = void>
+ TOML_PURE_GETTER bool is_homogeneous() const noexcept {
+ return node_
+ ? node_->template is_homogeneous<impl::unwrap_node<impl::remove_cvref<ElemType>>>()
+ : false;
+ }
+
+ /// @}
+
+ /// \name Type casts
+ /// @{
+
+ /// \brief Gets a pointer to the viewed node as a more specific node type.
+ ///
+ /// \tparam T The node type or TOML value type to cast to.
+ ///
+ /// \returns A pointer to the node as the given type, or nullptr if it was a different type.
+ ///
+ /// \see toml::node::as()
+ template <typename T>
+ TOML_PURE_GETTER auto* as() const noexcept {
+ return node_ ? node_->template as<T>() : nullptr;
+ }
+
+ /// \brief Returns a pointer to the viewed node as a toml::table, if it is one.
+ TOML_PURE_GETTER
+ auto* as_table() const noexcept { return as<table>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::array, if it is one.
+ TOML_PURE_GETTER
+ auto* as_array() const noexcept { return as<array>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<string>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_string() const noexcept { return as<std::string>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<int64_t>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_integer() const noexcept { return as<int64_t>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<double>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_floating_point() const noexcept { return as<double>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<bool>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_boolean() const noexcept { return as<bool>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<date>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_date() const noexcept { return as<date>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<time>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_time() const noexcept { return as<time>(); }
+
+ /// \brief Returns a pointer to the viewed node as a toml::value<date_time>, if it is one.
+ TOML_PURE_GETTER
+ auto* as_date_time() const noexcept { return as<date_time>(); }
+
+ /// @}
+
+ /// \name Value retrieval
+ /// @{
+
+ /// \brief Gets the value contained by the referenced node.
+ ///
+ /// \detail This function has 'exact' retrieval semantics; the only return value types allowed
+ /// are the TOML native value types, or types that can losslessly represent a native value type
+ /// (e.g. std::wstring on Windows).
+ ///
+ /// \tparam T One of the native TOML value types, or a type capable of losslessly representing
+ /// one.
+ ///
+ /// \returns The underlying value if the node was a value of the
+ /// matching type (or losslessly convertible to it), or an empty optional.
+ ///
+ /// \see node_view::value()
+ template <typename T>
+ TOML_NODISCARD optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ if (node_) return node_->template value_exact<T>();
+ return {};
+ }
+
+ /// \brief Gets the value contained by the referenced node.
+ ///
+ /// \detail This function has 'permissive' retrieval semantics; some value types are allowed
+ /// to convert to others (e.g. retrieving a boolean as an integer), and the specified return
+ /// value type can be any type where a reasonable conversion from a native TOML value exists
+ /// (e.g. std::wstring on Windows). If the source value cannot be represented by
+ /// the destination type, an empty optional is returned. See node::value() for examples.
+ ///
+ /// \tparam T One of the native TOML value types, or a type capable of convertible to one.
+ ///
+ /// \returns The underlying value if the node was a value of the matching type (or convertible
+ /// to it) and within the range of the output type, or an empty optional.
+ ///
+ /// \note If you want strict value retrieval semantics that do not allow for any type
+ /// conversions, use node_view::value_exact() instead.
+ ///
+ /// \see
+ /// - node_view::value()
+ /// - node_view::value_exact()
+ template <typename T>
+ TOML_NODISCARD optional<T> value() const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ if (node_) return node_->template value<T>();
+ return {};
+ }
+
+ /// \brief Gets the raw value contained by the referenced node, or a default.
+ ///
+ /// \tparam T Default value type. Must be one of the native TOML value types,
+ /// or convertible to it.
+ /// \param default_value The default value to return if the node wasn't a value, wasn't the
+ /// correct type, or no conversion was possible.
+ ///
+ /// \returns The underlying value if the node was a value of the matching type (or convertible
+ /// to it) and within the range of the output type, or the provided default.
+ ///
+ /// \note This function has the same permissive retrieval semantics as node::value(). If you
+ /// want strict value retrieval semantics that do not allow for any type conversions, use
+ /// node_view::value_exact() instead.
+ ///
+ /// \see
+ /// - node_view::value()
+ /// - node_view::value_exact()
+ template <typename T>
+ TOML_NODISCARD auto value_or(T&& default_value) const
+ noexcept(impl::value_retrieval_is_nothrow<T>) {
+ using namespace ::toml::impl;
+
+ static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Retrieving values as wide-character strings is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (is_wide_string<T>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- if (node_)
- return node_->value_or(static_cast<T&&>(default_value));
- return std::wstring{ static_cast<T&&>(default_value) };
+ if (node_) return node_->value_or(static_cast<T&&>(default_value));
+ return std::wstring{static_cast<T&&>(default_value)};
#else
- static_assert(impl::always_false<T>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<T>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- using value_type =
- std::conditional_t<std::is_pointer_v<std::decay_t<T>>,
- std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
- std::decay_t<T>>;
-
- if (node_)
- return node_->value_or(static_cast<T&&>(default_value));
- if constexpr (std::is_pointer_v<value_type>)
- return value_type{ default_value };
- else
- return static_cast<T&&>(default_value);
- }
- }
-
- /// \brief Gets a raw reference to the viewed node's underlying data.
- ///
- /// \warning This function is dangerous if used carelessly and **WILL** break your code if the
- /// node_view didn't reference a node, or the chosen value type doesn't match the node's
- /// actual type. In debug builds an assertion will fire when invalid accesses are attempted: \cpp
- ///
- /// auto tbl = toml::parse(R"(
- /// min = 32
- /// max = 45
- /// )"sv);
- ///
- /// int64_t& min_ref = tbl["min"].ref<int64_t>(); // matching type
- /// double& max_ref = tbl["max"].ref<double>(); // mismatched type, hits assert()
- /// int64_t& foo_ref = tbl["foo"].ref<int64_t>(); // nonexistent key, hits assert()
- /// \ecpp
- ///
- /// \note Specifying explicit ref qualifiers acts as an explicit ref-category cast,
- /// whereas specifying explicit cv-ref qualifiers merges them with whatever
- /// the cv qualification of the viewed node is (to ensure cv-correctness is propagated), e.g.:
- /// | node_view | T | return type |
- /// |-----------------------|------------------------|------------------------------|
- /// | node_view<node> | std::string | std::string& |
- /// | node_view<node> | std::string&& | std::string&& |
- /// | node_view<const node> | volatile std::string | const volatile std::string& |
- /// | node_view<const node> | volatile std::string&& | const volatile std::string&& |
- ///
- ///
- /// \tparam T One of the TOML value types.
- ///
- /// \returns A reference to the underlying data.
- template <typename T>
- TOML_PURE_INLINE_GETTER
- decltype(auto) ref() const noexcept
- {
- TOML_ASSERT_ASSUME(node_ && "toml::node_view::ref() called on a node_view that did not reference a node");
- return node_->template ref<T>();
- }
-
- /// @}
-
- /// \name Visitation
- /// @{
-
- private:
- /// \cond
- template <typename Func>
- static constexpr bool visit_is_nothrow = noexcept(std::declval<viewed_type*>()->visit(std::declval<Func>()));
- /// \endcond
-
- public:
- /// \brief Invokes a visitor on the viewed node based on its concrete type.
- ///
- /// \remarks Has no effect if the view does not reference a node.
- ///
- /// \see node::visit()
- template <typename Func>
- decltype(auto) visit(Func&& visitor) const noexcept(visit_is_nothrow<Func&&>)
- {
- using return_type = decltype(node_->visit(static_cast<Func&&>(visitor)));
- if (node_)
- return node_->visit(static_cast<Func&&>(visitor));
- if constexpr (!std::is_void_v<return_type>)
- return return_type{};
- }
-
- /// @}
-
- /// \name Equality
- /// @{
-
- public:
- /// \brief Returns true if the two views refer to nodes of the same type and value.
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator==(const node_view& lhs, const node_view<T>& rhs) noexcept
- {
- return impl::node_deep_equality(lhs.node_, rhs.node_);
- }
-
- /// \brief Returns true if the two views do not refer to nodes of the same type and value.
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator!=(const node_view& lhs, const node_view<T>& rhs) noexcept
- {
- return !impl::node_deep_equality(lhs.node_, rhs.node_);
- }
-
- /// \brief Returns true if the viewed node is a table with the same contents as RHS.
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs, const table& rhs) noexcept
- {
- if (lhs.node_ == &rhs)
- return true;
- const auto tbl = lhs.as<table>();
- return tbl && *tbl == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const table&, );
-
- /// \brief Returns true if the viewed node is an array with the same contents as RHS.
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs, const array& rhs) noexcept
- {
- if (lhs.node_ == &rhs)
- return true;
- const auto arr = lhs.as<array>();
- return arr && *arr == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const array&, );
-
- /// \brief Returns true if the viewed node is a value with the same value as RHS.
- template <typename T>
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs, const toml::value<T>& rhs) noexcept
- {
- if (lhs.node_ == &rhs)
- return true;
- const auto val = lhs.as<T>();
- return val && *val == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const toml::value<T>&, template <typename T>);
-
- /// \brief Returns true if the viewed node is a value with the same value as RHS.
- TOML_CONSTRAINED_TEMPLATE(impl::is_losslessly_convertible_to_native<T>, typename T)
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs, const T& rhs) noexcept(!impl::is_wide_string<T>)
- {
- static_assert(!impl::is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Comparison with wide-character strings is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (impl::is_wide_string<T>)
- {
+ } else {
+ using value_type = std::conditional_t<
+ std::is_pointer_v<std::decay_t<T>>,
+ std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
+ std::decay_t<T>>;
+
+ if (node_) return node_->value_or(static_cast<T&&>(default_value));
+ if constexpr (std::is_pointer_v<value_type>)
+ return value_type{default_value};
+ else
+ return static_cast<T&&>(default_value);
+ }
+ }
+
+ /// \brief Gets a raw reference to the viewed node's underlying data.
+ ///
+ /// \warning This function is dangerous if used carelessly and **WILL** break your code if the
+ /// node_view didn't reference a node, or the chosen value type doesn't match the node's
+ /// actual type. In debug builds an assertion will fire when invalid accesses are
+ /// attempted: \cpp
+ ///
+ /// auto tbl = toml::parse(R"(
+ /// min = 32
+ /// max = 45
+ /// )"sv);
+ ///
+ /// int64_t& min_ref = tbl["min"].ref<int64_t>(); // matching type
+ /// double& max_ref = tbl["max"].ref<double>(); // mismatched type, hits assert()
+ /// int64_t& foo_ref = tbl["foo"].ref<int64_t>(); // nonexistent key, hits assert()
+ /// \ecpp
+ ///
+ /// \note Specifying explicit ref qualifiers acts as an explicit ref-category cast,
+ /// whereas specifying explicit cv-ref qualifiers merges them with whatever
+ /// the cv qualification of the viewed node is (to ensure cv-correctness is propagated),
+ ///e.g.: | node_view | T | return type |
+ /// |-----------------------|------------------------|------------------------------|
+ /// | node_view<node> | std::string | std::string& |
+ /// | node_view<node> | std::string&& | std::string&& |
+ /// | node_view<const node> | volatile std::string | const volatile std::string& |
+ /// | node_view<const node> | volatile std::string&& | const volatile std::string&& |
+ ///
+ ///
+ /// \tparam T One of the TOML value types.
+ ///
+ /// \returns A reference to the underlying data.
+ template <typename T>
+ TOML_PURE_INLINE_GETTER decltype(auto) ref() const noexcept {
+ TOML_ASSERT_ASSUME(
+ node_ && "toml::node_view::ref() called on a node_view that did not reference a node");
+ return node_->template ref<T>();
+ }
+
+ /// @}
+
+ /// \name Visitation
+ /// @{
+
+ private:
+ /// \cond
+ template <typename Func>
+ static constexpr bool visit_is_nothrow =
+ noexcept(std::declval<viewed_type*>()->visit(std::declval<Func>()));
+ /// \endcond
+
+ public:
+ /// \brief Invokes a visitor on the viewed node based on its concrete type.
+ ///
+ /// \remarks Has no effect if the view does not reference a node.
+ ///
+ /// \see node::visit()
+ template <typename Func>
+ decltype(auto) visit(Func&& visitor) const noexcept(visit_is_nothrow<Func&&>) {
+ using return_type = decltype(node_->visit(static_cast<Func&&>(visitor)));
+ if (node_) return node_->visit(static_cast<Func&&>(visitor));
+ if constexpr (!std::is_void_v<return_type>) return return_type{};
+ }
+
+ /// @}
+
+ /// \name Equality
+ /// @{
+
+ public:
+ /// \brief Returns true if the two views refer to nodes of the same type and value.
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator==(const node_view& lhs,
+ const node_view<T>& rhs) noexcept {
+ return impl::node_deep_equality(lhs.node_, rhs.node_);
+ }
+
+ /// \brief Returns true if the two views do not refer to nodes of the same type and value.
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator!=(const node_view& lhs,
+ const node_view<T>& rhs) noexcept {
+ return !impl::node_deep_equality(lhs.node_, rhs.node_);
+ }
+
+ /// \brief Returns true if the viewed node is a table with the same contents as RHS.
+ TOML_NODISCARD
+ friend bool operator==(const node_view& lhs, const table& rhs) noexcept {
+ if (lhs.node_ == &rhs) return true;
+ const auto tbl = lhs.as<table>();
+ return tbl && *tbl == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const table&, );
+
+ /// \brief Returns true if the viewed node is an array with the same contents as RHS.
+ TOML_NODISCARD
+ friend bool operator==(const node_view& lhs, const array& rhs) noexcept {
+ if (lhs.node_ == &rhs) return true;
+ const auto arr = lhs.as<array>();
+ return arr && *arr == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const array&, );
+
+ /// \brief Returns true if the viewed node is a value with the same value as RHS.
+ template <typename T>
+ TOML_NODISCARD friend bool operator==(const node_view& lhs,
+ const toml::value<T>& rhs) noexcept {
+ if (lhs.node_ == &rhs) return true;
+ const auto val = lhs.as<T>();
+ return val && *val == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const toml::value<T>&, template <typename T>);
+
+ /// \brief Returns true if the viewed node is a value with the same value as RHS.
+ TOML_CONSTRAINED_TEMPLATE(impl::is_losslessly_convertible_to_native<T>, typename T)
+ TOML_NODISCARD
+ friend bool operator==(const node_view& lhs, const T& rhs) noexcept(!impl::is_wide_string<T>) {
+ static_assert(!impl::is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Comparison with wide-character strings is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (impl::is_wide_string<T>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return lhs == impl::narrow(rhs);
+ return lhs == impl::narrow(rhs);
#else
- static_assert(impl::always_false<T>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<T>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- const auto val = lhs.as<impl::native_type_of<T>>();
- return val && *val == rhs;
- }
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&,
- const T&,
- TOML_CONSTRAINED_TEMPLATE(impl::is_losslessly_convertible_to_native<T>,
- typename T));
-
- /// \brief Returns true if the viewed node is an array with the same contents as the RHS initializer list.
- template <typename T>
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs,
- const std::initializer_list<T>& rhs) noexcept(!impl::is_wide_string<T>)
- {
- const auto arr = lhs.as<array>();
- return arr && *arr == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::initializer_list<T>&, template <typename T>);
-
- /// \brief Returns true if the viewed node is an array with the same contents as the RHS vector.
- template <typename T>
- TOML_NODISCARD
- friend bool operator==(const node_view& lhs, const std::vector<T>& rhs) noexcept(!impl::is_wide_string<T>)
- {
- const auto arr = lhs.as<array>();
- return arr && *arr == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::vector<T>&, template <typename T>);
-
- /// @}
-
- /// \name Subviews
- /// @{
-
- /// \brief Returns a view of the selected subnode.
- ///
- /// \param key The key of the node to retrieve
- ///
- /// \returns A view of the selected node if this node represented a table and it contained a
- /// value at the given key, or an empty view.
- TOML_NODISCARD
- node_view operator[](std::string_view key) const noexcept
- {
- if (auto tbl = this->as_table())
- return node_view{ tbl->get(key) };
- return {};
- }
-
- /// \brief Returns a view of the selected subnode.
- ///
- /// \param path A "TOML path" to the desired subnode
- ///
- /// \returns A view of the selected node if this node represented a table and it contained a
- /// value at the given key, or an empty view.
- TOML_NODISCARD
- node_view operator[](const toml::path& path) const noexcept
- {
- return node_ ? node_->at_path(path) : node_view{};
- }
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view at_path(std::string_view path) const noexcept
- {
- return node_ ? node_->at_path(path) : node_view{};
- }
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(const toml::path&)
- TOML_NODISCARD
- node_view at_path(const toml::path& path) const noexcept
- {
- return node_ ? node_->at_path(path) : node_view{};
- }
+ } else {
+ const auto val = lhs.as<impl::native_type_of<T>>();
+ return val && *val == rhs;
+ }
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(
+ const node_view&, const T&,
+ TOML_CONSTRAINED_TEMPLATE(impl::is_losslessly_convertible_to_native<T>, typename T));
+
+ /// \brief Returns true if the viewed node is an array with the same contents as the RHS
+ /// initializer list.
+ template <typename T>
+ TOML_NODISCARD friend bool operator==(
+ const node_view& lhs,
+ const std::initializer_list<T>& rhs) noexcept(!impl::is_wide_string<T>) {
+ const auto arr = lhs.as<array>();
+ return arr && *arr == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::initializer_list<T>&,
+ template <typename T>);
+
+ /// \brief Returns true if the viewed node is an array with the same contents as the RHS
+ /// vector.
+ template <typename T>
+ TOML_NODISCARD friend bool operator==(const node_view& lhs, const std::vector<T>& rhs) noexcept(
+ !impl::is_wide_string<T>) {
+ const auto arr = lhs.as<array>();
+ return arr && *arr == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const node_view&, const std::vector<T>&, template <typename T>);
+
+ /// @}
+
+ /// \name Subviews
+ /// @{
+
+ /// \brief Returns a view of the selected subnode.
+ ///
+ /// \param key The key of the node to retrieve
+ ///
+ /// \returns A view of the selected node if this node represented a table and it contained a
+ /// value at the given key, or an empty view.
+ TOML_NODISCARD
+ node_view operator[](std::string_view key) const noexcept {
+ if (auto tbl = this->as_table()) return node_view{tbl->get(key)};
+ return {};
+ }
+
+ /// \brief Returns a view of the selected subnode.
+ ///
+ /// \param path A "TOML path" to the desired subnode
+ ///
+ /// \returns A view of the selected node if this node represented a table and it contained a
+ /// value at the given key, or an empty view.
+ TOML_NODISCARD
+ node_view operator[](const toml::path& path) const noexcept {
+ return node_ ? node_->at_path(path) : node_view{};
+ }
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view at_path(std::string_view path) const noexcept {
+ return node_ ? node_->at_path(path) : node_view{};
+ }
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(const toml::path&)
+ TOML_NODISCARD
+ node_view at_path(const toml::path& path) const noexcept {
+ return node_ ? node_->at_path(path) : node_view{};
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns a view of the selected subnode.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The key of the node to retrieve
- ///
- /// \returns A view of the selected node if this node represented a table and it contained a
- /// value at the given key, or an empty view.
- TOML_NODISCARD
- node_view operator[](std::wstring_view key) const
- {
- if (auto tbl = this->as_table())
- return node_view{ tbl->get(key) };
- return {};
- }
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view at_path(std::wstring_view path) const
- {
- return node_ ? node_->at_path(path) : node_view{};
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Returns a view of the selected subnode.
- ///
- /// \param index The index of the node to retrieve
- ///
- /// \returns A view of the selected node if this node represented an array and it contained a
- /// value at the given index, or an empty view.
- TOML_NODISCARD
- node_view operator[](size_t index) const noexcept
- {
- if (auto arr = this->as_array())
- return node_view{ arr->get(index) };
- return {};
- }
-
- /// @}
+ /// \brief Returns a view of the selected subnode.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The key of the node to retrieve
+ ///
+ /// \returns A view of the selected node if this node represented a table and it contained a
+ /// value at the given key, or an empty view.
+ TOML_NODISCARD
+ node_view operator[](std::wstring_view key) const {
+ if (auto tbl = this->as_table()) return node_view{tbl->get(key)};
+ return {};
+ }
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view at_path(std::wstring_view path) const {
+ return node_ ? node_->at_path(path) : node_view{};
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Returns a view of the selected subnode.
+ ///
+ /// \param index The index of the node to retrieve
+ ///
+ /// \returns A view of the selected node if this node represented an array and it contained a
+ /// value at the given index, or an empty view.
+ TOML_NODISCARD
+ node_view operator[](size_t index) const noexcept {
+ if (auto arr = this->as_array()) return node_view{arr->get(index)};
+ return {};
+ }
+
+ /// @}
#if TOML_ENABLE_FORMATTERS
- /// \brief Prints the viewed node out to a stream.
- ///
- /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
- friend std::ostream& operator<<(std::ostream& os, const node_view& nv)
- {
- if (nv.node_)
- nv.node_->visit([&os](const auto& n) { os << n; });
- return os;
- }
+ /// \brief Prints the viewed node out to a stream.
+ ///
+ /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ friend std::ostream& operator<<(std::ostream& os, const node_view& nv) {
+ if (nv.node_) nv.node_->visit([&os](const auto& n) { os << n; });
+ return os;
+ }
#endif
- };
+ };
- /// \cond
+ /// \cond
- template <typename T>
- node_view(const T&) -> node_view<const node>;
+ template <typename T>
+ node_view(const T&) -> node_view<const node>;
- template <typename T>
- node_view(const T*) -> node_view<const node>;
+ template <typename T>
+ node_view(const T*) -> node_view<const node>;
- template <typename T>
- node_view(T&) -> node_view<node>;
+ template <typename T>
+ node_view(T&) -> node_view<node>;
- template <typename T>
- node_view(T*) -> node_view<node>;
+ template <typename T>
+ node_view(T*) -> node_view<node>;
- /// \endcond
+ /// \endcond
}
TOML_NAMESPACE_END;
/// \cond
-TOML_NAMESPACE_START
-{
- inline node::operator node_view<node>() noexcept
- {
- return node_view<node>{ this };
- }
-
- inline node::operator node_view<const node>() const noexcept
- {
- return node_view<const node>{ this };
- }
+TOML_NAMESPACE_START {
+ inline node::operator node_view<node>() noexcept {
+ return node_view<node>{this};
+ }
+
+ inline node::operator node_view<const node>() const noexcept {
+ return node_view<const node>{this};
+ }
}
TOML_NAMESPACE_END;
/// \endcond
diff --git a/vendor/toml++/impl/parse_error.hpp b/vendor/toml++/impl/parse_error.hpp
index 05f2b6d..ef0a833 100644
--- a/vendor/toml++/impl/parse_error.hpp
+++ b/vendor/toml++/impl/parse_error.hpp
@@ -1,16 +1,16 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_ENABLE_PARSER
-#include "std_except.hpp"
-#include "source_region.hpp"
-#include "print_to_stream.hpp"
#include "header_start.hpp"
+#include "print_to_stream.hpp"
+#include "source_region.hpp"
+#include "std_except.hpp"
#if TOML_DOXYGEN || !TOML_EXCEPTIONS
#define TOML_PARSE_ERROR_BASE
@@ -18,122 +18,109 @@
#define TOML_PARSE_ERROR_BASE : public std::runtime_error
#endif
-TOML_NAMESPACE_START
-{
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
-
- /// \brief An error generated when parsing fails.
- ///
- /// \remarks This class inherits from std::runtime_error when exceptions are enabled.
- /// The public interface is the same regardless of exception mode.
- class parse_error TOML_PARSE_ERROR_BASE
- {
- private:
+TOML_NAMESPACE_START {
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
+
+ /// \brief An error generated when parsing fails.
+ ///
+ /// \remarks This class inherits from std::runtime_error when exceptions are enabled.
+ /// The public interface is the same regardless of exception mode.
+ class parse_error TOML_PARSE_ERROR_BASE {
+ private:
#if !TOML_EXCEPTIONS
- std::string description_;
+ std::string description_;
#endif
- source_region source_;
+ source_region source_;
- public:
+ public:
#if TOML_EXCEPTIONS
- TOML_NODISCARD_CTOR
- TOML_ATTR(nonnull)
- parse_error(const char* desc, source_region&& src) noexcept //
- : std::runtime_error{ desc },
- source_{ std::move(src) }
- {}
-
- TOML_NODISCARD_CTOR
- TOML_ATTR(nonnull)
- parse_error(const char* desc, const source_region& src) noexcept //
- : parse_error{ desc, source_region{ src } }
- {}
-
- TOML_NODISCARD_CTOR
- TOML_ATTR(nonnull)
- parse_error(const char* desc, const source_position& position, const source_path_ptr& path = {}) noexcept
- : parse_error{ desc, source_region{ position, position, path } }
- {}
+ TOML_NODISCARD_CTOR
+ TOML_ATTR(nonnull)
+ parse_error(const char* desc, source_region&& src) noexcept //
+ : std::runtime_error{desc}, source_{std::move(src)} {}
+
+ TOML_NODISCARD_CTOR
+ TOML_ATTR(nonnull)
+ parse_error(const char* desc, const source_region& src) noexcept //
+ : parse_error{desc, source_region{src}} {}
+
+ TOML_NODISCARD_CTOR
+ TOML_ATTR(nonnull)
+ parse_error(const char* desc, const source_position& position,
+ const source_path_ptr& path = {}) noexcept
+ : parse_error{desc, source_region{position, position, path}} {}
#else
- TOML_NODISCARD_CTOR
- parse_error(std::string&& desc, source_region&& src) noexcept //
- : description_{ std::move(desc) },
- source_{ std::move(src) }
- {}
+ TOML_NODISCARD_CTOR
+ parse_error(std::string&& desc, source_region&& src) noexcept //
+ : description_{std::move(desc)}, source_{std::move(src)} {}
- TOML_NODISCARD_CTOR
- parse_error(std::string&& desc, const source_region& src) noexcept //
- : parse_error{ std::move(desc), source_region{ src } }
- {}
+ TOML_NODISCARD_CTOR
+ parse_error(std::string&& desc, const source_region& src) noexcept //
+ : parse_error{std::move(desc), source_region{src}} {}
- TOML_NODISCARD_CTOR
- parse_error(std::string&& desc, const source_position& position, const source_path_ptr& path = {}) noexcept
- : parse_error{ std::move(desc), source_region{ position, position, path } }
- {}
+ TOML_NODISCARD_CTOR
+ parse_error(std::string&& desc, const source_position& position,
+ const source_path_ptr& path = {}) noexcept
+ : parse_error{std::move(desc), source_region{position, position, path}} {}
#endif
- /// \brief Returns a textual description of the error.
- /// \remark The backing string is guaranteed to be null-terminated.
- TOML_NODISCARD
- std::string_view description() const noexcept
- {
+ /// \brief Returns a textual description of the error.
+ /// \remark The backing string is guaranteed to be null-terminated.
+ TOML_NODISCARD
+ std::string_view description() const noexcept {
#if TOML_EXCEPTIONS
- return std::string_view{ what() };
+ return std::string_view{what()};
#else
- return description_;
+ return description_;
#endif
- }
-
- /// \brief Returns the region of the source document responsible for the error.
- TOML_NODISCARD
- const source_region& source() const noexcept
- {
- return source_;
- }
-
- /// \brief Prints a parse_error to a stream.
- ///
- /// \detail \cpp
- /// try
- /// {
- /// auto tbl = toml::parse("enabled = trUe"sv);
- /// }
- /// catch (const toml::parse_error & err)
- /// {
- /// std::cerr << "Parsing failed:\n"sv << err << "\n";
- /// }
- /// \ecpp
- ///
- /// \out
- /// Parsing failed:
- /// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
- /// (error occurred at line 1, column 13)
- /// \eout
- ///
- /// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
- /// \param lhs The stream.
- /// \param rhs The parse_error.
- ///
- /// \returns The input stream.
- friend std::ostream& operator<<(std::ostream& lhs, const parse_error& rhs)
- {
- impl::print_to_stream(lhs, rhs.description());
- impl::print_to_stream(lhs, "\n\t(error occurred at "sv);
- impl::print_to_stream(lhs, rhs.source());
- impl::print_to_stream(lhs, ")"sv);
- return lhs;
- }
- };
-
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ }
+
+ /// \brief Returns the region of the source document responsible for the error.
+ TOML_NODISCARD
+ const source_region& source() const noexcept { return source_; }
+
+ /// \brief Prints a parse_error to a stream.
+ ///
+ /// \detail \cpp
+ /// try
+ /// {
+ /// auto tbl = toml::parse("enabled = trUe"sv);
+ /// }
+ /// catch (const toml::parse_error & err)
+ /// {
+ /// std::cerr << "Parsing failed:\n"sv << err << "\n";
+ /// }
+ /// \ecpp
+ ///
+ /// \out
+ /// Parsing failed:
+ /// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
+ /// (error occurred at line 1, column 13)
+ /// \eout
+ ///
+ /// \tparam Char The output stream's underlying character type. Must be 1 byte in size.
+ /// \param lhs The stream.
+ /// \param rhs The parse_error.
+ ///
+ /// \returns The input stream.
+ friend std::ostream& operator<<(std::ostream& lhs, const parse_error& rhs) {
+ impl::print_to_stream(lhs, rhs.description());
+ impl::print_to_stream(lhs, "\n\t(error occurred at "sv);
+ impl::print_to_stream(lhs, rhs.source());
+ impl::print_to_stream(lhs, ")"sv);
+ return lhs;
+ }
+ };
+
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
}
TOML_NAMESPACE_END;
#undef TOML_PARSE_ERROR_BASE
#include "header_end.hpp"
-#endif // TOML_ENABLE_PARSER
+#endif // TOML_ENABLE_PARSER
diff --git a/vendor/toml++/impl/parse_result.hpp b/vendor/toml++/impl/parse_result.hpp
index 5837a0b..ca0e3f5 100644
--- a/vendor/toml++/impl/parse_result.hpp
+++ b/vendor/toml++/impl/parse_result.hpp
@@ -1,499 +1,431 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
-#include "table.hpp"
-#include "parse_error.hpp"
#include "header_start.hpp"
+#include "parse_error.hpp"
+#include "table.hpp"
-TOML_NAMESPACE_START
-{
- TOML_ABI_NAMESPACE_START(noex);
-
- /// \brief The result of a parsing operation.
- ///
- /// \availability <strong>This type only exists when exceptions are disabled.</strong>
- /// Otherwise parse_result is just an alias for toml::table: \cpp
- /// #if TOML_EXCEPTIONS
- /// using parse_result = table;
- /// #else
- /// class parse_result { // ...
- /// #endif
- /// \ecpp
- ///
- /// \detail A parse_result is effectively a discriminated union containing either a toml::table
- /// or a toml::parse_error. Most member functions assume a particular one of these two states,
- /// and calling them when in the wrong state will cause errors (e.g. attempting to access the
- /// error object when parsing was successful). \cpp
- /// toml::parse_result result = toml::parse_file("config.toml");
- /// if (result)
- /// do_stuff_with_a_table(result); //implicitly converts to table&
- /// else
- /// std::cerr << "Parse failed:\n"sv << result.error() << "\n";
- /// \ecpp
- ///
- /// \out
- /// example output:
- ///
- /// Parse failed:
- /// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
- /// (error occurred at line 1, column 13 of 'config.toml')
- /// \eout
- ///
- /// Getting node_views (`operator[]`, `at_path()`) and using the iterator accessor functions (`begin()`, `end()` etc.) are
- /// unconditionally safe; when parsing fails these just return 'empty' values. A ranged-for loop on a failed
- /// parse_result is also safe since `begin()` and `end()` return the same iterator and will not lead to any
- /// dereferences and iterations.
- class parse_result
- {
- private:
- struct storage_t
- {
- static constexpr size_t size =
- (sizeof(toml::table) < sizeof(parse_error) ? sizeof(parse_error) : sizeof(toml::table));
- static constexpr size_t align =
- (alignof(toml::table) < alignof(parse_error) ? alignof(parse_error) : alignof(toml::table));
-
- alignas(align) unsigned char bytes[size];
- };
-
- alignas(storage_t::align) mutable storage_t storage_;
- bool err_;
-
- template <typename Type>
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- static Type* get_as(storage_t& s) noexcept
- {
- return TOML_LAUNDER(reinterpret_cast<Type*>(s.bytes));
- }
-
- void destroy() noexcept
- {
- if (err_)
- get_as<parse_error>(storage_)->~parse_error();
- else
- get_as<toml::table>(storage_)->~table();
- }
-
- public:
- /// \brief Default constructs an 'error' result.
- TOML_NODISCARD_CTOR
- parse_result() noexcept //
- : err_{ true }
- {
- ::new (static_cast<void*>(storage_.bytes)) parse_error{ std::string{}, source_region{} };
- }
-
- TOML_NODISCARD_CTOR
- explicit parse_result(toml::table&& tbl) noexcept //
- : err_{ false }
- {
- ::new (static_cast<void*>(storage_.bytes)) toml::table{ std::move(tbl) };
- }
-
- TOML_NODISCARD_CTOR
- explicit parse_result(parse_error&& err) noexcept //
- : err_{ true }
- {
- ::new (static_cast<void*>(storage_.bytes)) parse_error{ std::move(err) };
- }
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- parse_result(parse_result&& res) noexcept //
- : err_{ res.err_ }
- {
- if (err_)
- ::new (static_cast<void*>(storage_.bytes)) parse_error{ std::move(res).error() };
- else
- ::new (static_cast<void*>(storage_.bytes)) toml::table{ std::move(res).table() };
- }
-
- /// \brief Move-assignment operator.
- parse_result& operator=(parse_result&& rhs) noexcept
- {
- if (err_ != rhs.err_)
- {
- destroy();
- err_ = rhs.err_;
- if (err_)
- ::new (static_cast<void*>(storage_.bytes)) parse_error{ std::move(rhs).error() };
- else
- ::new (static_cast<void*>(storage_.bytes)) toml::table{ std::move(rhs).table() };
- }
- else
- {
- if (err_)
- error() = std::move(rhs).error();
- else
- table() = std::move(rhs).table();
- }
- return *this;
- }
-
- /// \brief Destructor.
- ~parse_result() noexcept
- {
- destroy();
- }
-
- /// \name Result state
- /// @{
-
- /// \brief Returns true if parsing succeeeded.
- TOML_NODISCARD
- bool succeeded() const noexcept
- {
- return !err_;
- }
-
- /// \brief Returns true if parsing failed.
- TOML_NODISCARD
- bool failed() const noexcept
- {
- return err_;
- }
-
- /// \brief Returns true if parsing succeeded.
- TOML_NODISCARD
- explicit operator bool() const noexcept
- {
- return !err_;
- }
-
- /// @}
-
- /// \name Successful parses
- /// \warning It is undefined behaviour to call these functions when the result respresents a failed parse.
- /// Check #failed(), #succeeded or #operator bool() to determine the result's state.
- /// @{
-
- /// \brief Returns the internal toml::table.
- TOML_NODISCARD
- toml::table& table() & noexcept
- {
- TOML_ASSERT_ASSUME(!err_);
- return *get_as<toml::table>(storage_);
- }
-
- /// \brief Returns the internal toml::table (rvalue overload).
- TOML_NODISCARD
- toml::table&& table() && noexcept
- {
- TOML_ASSERT_ASSUME(!err_);
- return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
- }
-
- /// \brief Returns the internal toml::table (const lvalue overload).
- TOML_NODISCARD
- const toml::table& table() const& noexcept
- {
- TOML_ASSERT_ASSUME(!err_);
- return *get_as<const toml::table>(storage_);
- }
-
- /// \brief Returns the internal toml::table.
- TOML_NODISCARD
- /* implicit */ operator toml::table&() noexcept
- {
- return table();
- }
-
- /// \brief Returns the internal toml::table (rvalue overload).
- TOML_NODISCARD
- /* implicit */ operator toml::table&&() noexcept
- {
- return std::move(table());
- }
-
- /// \brief Returns the internal toml::table (const lvalue overload).
- TOML_NODISCARD
- /* implicit */ operator const toml::table&() const noexcept
- {
- return table();
- }
-
- /// @}
-
- /// \name Failed parses
- /// \warning It is undefined behaviour to call these functions when the result respresents a successful parse.
- /// Check #failed(), #succeeded or #operator bool() to determine the result's state.
- /// @{
-
- /// \brief Returns the internal toml::parse_error.
- TOML_NODISCARD
- parse_error& error() & noexcept
- {
- TOML_ASSERT_ASSUME(err_);
- return *get_as<parse_error>(storage_);
- }
-
- /// \brief Returns the internal toml::parse_error (rvalue overload).
- TOML_NODISCARD
- parse_error&& error() && noexcept
- {
- TOML_ASSERT_ASSUME(err_);
- return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
- }
-
- /// \brief Returns the internal toml::parse_error (const lvalue overload).
- TOML_NODISCARD
- const parse_error& error() const& noexcept
- {
- TOML_ASSERT_ASSUME(err_);
- return *get_as<const parse_error>(storage_);
- }
-
- /// \brief Returns the internal toml::parse_error.
- TOML_NODISCARD
- explicit operator parse_error&() noexcept
- {
- return error();
- }
-
- /// \brief Returns the internal toml::parse_error (rvalue overload).
- TOML_NODISCARD
- explicit operator parse_error&&() noexcept
- {
- return std::move(error());
- }
-
- /// \brief Returns the internal toml::parse_error (const lvalue overload).
- TOML_NODISCARD
- explicit operator const parse_error&() const noexcept
- {
- return error();
- }
-
- /// @}
-
- /// \name Iteration
- /// @{
-
- /// \brief A BidirectionalIterator for iterating over key-value pairs in a wrapped toml::table.
- using iterator = table_iterator;
-
- /// \brief A BidirectionalIterator for iterating over const key-value pairs in a wrapped toml::table.
- using const_iterator = const_table_iterator;
-
- /// \brief Returns an iterator to the first key-value pair in the wrapped table.
- /// \remarks Always returns the same value as #end() if parsing failed.
- TOML_NODISCARD
- table_iterator begin() noexcept
- {
- return err_ ? table_iterator{} : table().begin();
- }
-
- /// \brief Returns an iterator to the first key-value pair in the wrapped table.
- /// \remarks Always returns the same value as #end() if parsing failed.
- TOML_NODISCARD
- const_table_iterator begin() const noexcept
- {
- return err_ ? const_table_iterator{} : table().begin();
- }
-
- /// \brief Returns an iterator to the first key-value pair in the wrapped table.
- /// \remarks Always returns the same value as #cend() if parsing failed.
- TOML_NODISCARD
- const_table_iterator cbegin() const noexcept
- {
- return err_ ? const_table_iterator{} : table().cbegin();
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
- TOML_NODISCARD
- table_iterator end() noexcept
- {
- return err_ ? table_iterator{} : table().end();
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
- TOML_NODISCARD
- const_table_iterator end() const noexcept
- {
- return err_ ? const_table_iterator{} : table().end();
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
- TOML_NODISCARD
- const_table_iterator cend() const noexcept
- {
- return err_ ? const_table_iterator{} : table().cend();
- }
-
- /// @}
-
- /// \name Node views
- /// @{
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view<node> at_path(std::string_view path) noexcept
- {
- return err_ ? node_view<node>{} : table().at_path(path);
- }
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view<const node> at_path(std::string_view path) const noexcept
- {
- return err_ ? node_view<const node>{} : table().at_path(path);
- }
-
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(const toml::path&)
- TOML_NODISCARD
- node_view<node> at_path(const toml::path& path) noexcept
- {
- return err_ ? node_view<node>{} : table().at_path(path);
- }
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::at_path(const toml::path&)
- TOML_NODISCARD
- node_view<const node> at_path(const toml::path& path) const noexcept
- {
- return err_ ? node_view<const node>{} : table().at_path(path);
- }
+TOML_NAMESPACE_START {
+ TOML_ABI_NAMESPACE_START(noex);
+
+ /// \brief The result of a parsing operation.
+ ///
+ /// \availability <strong>This type only exists when exceptions are disabled.</strong>
+ /// Otherwise parse_result is just an alias for toml::table: \cpp
+ /// #if TOML_EXCEPTIONS
+ /// using parse_result = table;
+ /// #else
+ /// class parse_result { // ...
+ /// #endif
+ /// \ecpp
+ ///
+ /// \detail A parse_result is effectively a discriminated union containing either a toml::table
+ /// or a toml::parse_error. Most member functions assume a particular one of these two states,
+ /// and calling them when in the wrong state will cause errors (e.g. attempting to access the
+ /// error object when parsing was successful). \cpp
+ /// toml::parse_result result = toml::parse_file("config.toml");
+ /// if (result)
+ /// do_stuff_with_a_table(result); //implicitly converts to table&
+ /// else
+ /// std::cerr << "Parse failed:\n"sv << result.error() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// example output:
+ ///
+ /// Parse failed:
+ /// Encountered unexpected character while parsing boolean; expected 'true', saw 'trU'
+ /// (error occurred at line 1, column 13 of 'config.toml')
+ /// \eout
+ ///
+ /// Getting node_views (`operator[]`, `at_path()`) and using the iterator accessor functions
+ /// (`begin()`, `end()` etc.) are unconditionally safe; when parsing fails these just return
+ /// 'empty' values. A ranged-for loop on a failed parse_result is also safe since `begin()` and
+ /// `end()` return the same iterator and will not lead to any dereferences and iterations.
+ class parse_result {
+ private:
+ struct storage_t {
+ static constexpr size_t size =
+ (sizeof(toml::table) < sizeof(parse_error) ? sizeof(parse_error) : sizeof(toml::table));
+ static constexpr size_t align =
+ (alignof(toml::table) < alignof(parse_error) ? alignof(parse_error)
+ : alignof(toml::table));
+
+ alignas(align) unsigned char bytes[size];
+ };
+
+ alignas(storage_t::align) mutable storage_t storage_;
+ bool err_;
+
+ template <typename Type>
+ TOML_NODISCARD TOML_ALWAYS_INLINE static Type* get_as(storage_t& s) noexcept {
+ return TOML_LAUNDER(reinterpret_cast<Type*>(s.bytes));
+ }
+
+ void destroy() noexcept {
+ if (err_)
+ get_as<parse_error>(storage_)->~parse_error();
+ else
+ get_as<toml::table>(storage_)->~table();
+ }
+
+ public:
+ /// \brief Default constructs an 'error' result.
+ TOML_NODISCARD_CTOR
+ parse_result() noexcept //
+ : err_{true} {
+ ::new (static_cast<void*>(storage_.bytes)) parse_error{std::string{}, source_region{}};
+ }
+
+ TOML_NODISCARD_CTOR
+ explicit parse_result(toml::table&& tbl) noexcept //
+ : err_{false} {
+ ::new (static_cast<void*>(storage_.bytes)) toml::table{std::move(tbl)};
+ }
+
+ TOML_NODISCARD_CTOR
+ explicit parse_result(parse_error&& err) noexcept //
+ : err_{true} {
+ ::new (static_cast<void*>(storage_.bytes)) parse_error{std::move(err)};
+ }
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ parse_result(parse_result&& res) noexcept //
+ : err_{res.err_} {
+ if (err_)
+ ::new (static_cast<void*>(storage_.bytes)) parse_error{std::move(res).error()};
+ else
+ ::new (static_cast<void*>(storage_.bytes)) toml::table{std::move(res).table()};
+ }
+
+ /// \brief Move-assignment operator.
+ parse_result& operator=(parse_result&& rhs) noexcept {
+ if (err_ != rhs.err_) {
+ destroy();
+ err_ = rhs.err_;
+ if (err_)
+ ::new (static_cast<void*>(storage_.bytes)) parse_error{std::move(rhs).error()};
+ else
+ ::new (static_cast<void*>(storage_.bytes)) toml::table{std::move(rhs).table()};
+ } else {
+ if (err_)
+ error() = std::move(rhs).error();
+ else
+ table() = std::move(rhs).table();
+ }
+ return *this;
+ }
+
+ /// \brief Destructor.
+ ~parse_result() noexcept { destroy(); }
+
+ /// \name Result state
+ /// @{
+
+ /// \brief Returns true if parsing succeeeded.
+ TOML_NODISCARD
+ bool succeeded() const noexcept { return !err_; }
+
+ /// \brief Returns true if parsing failed.
+ TOML_NODISCARD
+ bool failed() const noexcept { return err_; }
+
+ /// \brief Returns true if parsing succeeded.
+ TOML_NODISCARD
+ explicit operator bool() const noexcept { return !err_; }
+
+ /// @}
+
+ /// \name Successful parses
+ /// \warning It is undefined behaviour to call these functions when the result respresents a
+ /// failed parse. Check #failed(), #succeeded or #operator bool() to determine the result's
+ /// state.
+ /// @{
+
+ /// \brief Returns the internal toml::table.
+ TOML_NODISCARD
+ toml::table& table() & noexcept {
+ TOML_ASSERT_ASSUME(!err_);
+ return *get_as<toml::table>(storage_);
+ }
+
+ /// \brief Returns the internal toml::table (rvalue overload).
+ TOML_NODISCARD
+ toml::table&& table() && noexcept {
+ TOML_ASSERT_ASSUME(!err_);
+ return static_cast<toml::table&&>(*get_as<toml::table>(storage_));
+ }
+
+ /// \brief Returns the internal toml::table (const lvalue overload).
+ TOML_NODISCARD
+ const toml::table& table() const& noexcept {
+ TOML_ASSERT_ASSUME(!err_);
+ return *get_as<const toml::table>(storage_);
+ }
+
+ /// \brief Returns the internal toml::table.
+ TOML_NODISCARD
+ /* implicit */ operator toml::table&() noexcept { return table(); }
+
+ /// \brief Returns the internal toml::table (rvalue overload).
+ TOML_NODISCARD
+ /* implicit */ operator toml::table&&() noexcept { return std::move(table()); }
+
+ /// \brief Returns the internal toml::table (const lvalue overload).
+ TOML_NODISCARD
+ /* implicit */ operator const toml::table&() const noexcept { return table(); }
+
+ /// @}
+
+ /// \name Failed parses
+ /// \warning It is undefined behaviour to call these functions when the result respresents a
+ /// successful parse. Check #failed(), #succeeded or #operator bool() to determine the result's
+ /// state.
+ /// @{
+
+ /// \brief Returns the internal toml::parse_error.
+ TOML_NODISCARD
+ parse_error& error() & noexcept {
+ TOML_ASSERT_ASSUME(err_);
+ return *get_as<parse_error>(storage_);
+ }
+
+ /// \brief Returns the internal toml::parse_error (rvalue overload).
+ TOML_NODISCARD
+ parse_error&& error() && noexcept {
+ TOML_ASSERT_ASSUME(err_);
+ return static_cast<parse_error&&>(*get_as<parse_error>(storage_));
+ }
+
+ /// \brief Returns the internal toml::parse_error (const lvalue overload).
+ TOML_NODISCARD
+ const parse_error& error() const& noexcept {
+ TOML_ASSERT_ASSUME(err_);
+ return *get_as<const parse_error>(storage_);
+ }
+
+ /// \brief Returns the internal toml::parse_error.
+ TOML_NODISCARD
+ explicit operator parse_error&() noexcept { return error(); }
+
+ /// \brief Returns the internal toml::parse_error (rvalue overload).
+ TOML_NODISCARD
+ explicit operator parse_error&&() noexcept { return std::move(error()); }
+
+ /// \brief Returns the internal toml::parse_error (const lvalue overload).
+ TOML_NODISCARD
+ explicit operator const parse_error&() const noexcept { return error(); }
+
+ /// @}
+
+ /// \name Iteration
+ /// @{
+
+ /// \brief A BidirectionalIterator for iterating over key-value pairs in a wrapped toml::table.
+ using iterator = table_iterator;
+
+ /// \brief A BidirectionalIterator for iterating over const key-value pairs in a wrapped
+ /// toml::table.
+ using const_iterator = const_table_iterator;
+
+ /// \brief Returns an iterator to the first key-value pair in the wrapped table.
+ /// \remarks Always returns the same value as #end() if parsing failed.
+ TOML_NODISCARD
+ table_iterator begin() noexcept { return err_ ? table_iterator{} : table().begin(); }
+
+ /// \brief Returns an iterator to the first key-value pair in the wrapped table.
+ /// \remarks Always returns the same value as #end() if parsing failed.
+ TOML_NODISCARD
+ const_table_iterator begin() const noexcept {
+ return err_ ? const_table_iterator{} : table().begin();
+ }
+
+ /// \brief Returns an iterator to the first key-value pair in the wrapped table.
+ /// \remarks Always returns the same value as #cend() if parsing failed.
+ TOML_NODISCARD
+ const_table_iterator cbegin() const noexcept {
+ return err_ ? const_table_iterator{} : table().cbegin();
+ }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
+ TOML_NODISCARD
+ table_iterator end() noexcept { return err_ ? table_iterator{} : table().end(); }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
+ TOML_NODISCARD
+ const_table_iterator end() const noexcept {
+ return err_ ? const_table_iterator{} : table().end();
+ }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair in the wrapped table.
+ TOML_NODISCARD
+ const_table_iterator cend() const noexcept {
+ return err_ ? const_table_iterator{} : table().cend();
+ }
+
+ /// @}
+
+ /// \name Node views
+ /// @{
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view<node> at_path(std::string_view path) noexcept {
+ return err_ ? node_view<node>{} : table().at_path(path);
+ }
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view<const node> at_path(std::string_view path) const noexcept {
+ return err_ ? node_view<const node>{} : table().at_path(path);
+ }
+
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(const toml::path&)
+ TOML_NODISCARD
+ node_view<node> at_path(const toml::path& path) noexcept {
+ return err_ ? node_view<node>{} : table().at_path(path);
+ }
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::at_path(const toml::path&)
+ TOML_NODISCARD
+ node_view<const node> at_path(const toml::path& path) const noexcept {
+ return err_ ? node_view<const node>{} : table().at_path(path);
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view<node> at_path(std::wstring_view path)
- {
- return err_ ? node_view<node>{} : table().at_path(path);
- }
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \see #toml::node::at_path(std::string_view)
- TOML_NODISCARD
- node_view<const node> at_path(std::wstring_view path) const
- {
- return err_ ? node_view<const node>{} : table().at_path(path);
- }
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view<node> at_path(std::wstring_view path) {
+ return err_ ? node_view<node>{} : table().at_path(path);
+ }
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \see #toml::node::at_path(std::string_view)
+ TOML_NODISCARD
+ node_view<const node> at_path(std::wstring_view path) const {
+ return err_ ? node_view<const node>{} : table().at_path(path);
+ }
#endif
- /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::operator[](const toml::path&)
- TOML_NODISCARD
- node_view<node> operator[](const toml::path& path) noexcept
- {
- return err_ ? node_view<node>{} : table()[path];
- }
-
- /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
- ///
- /// \see #toml::node::operator[](const toml::path&)
- TOML_NODISCARD
- node_view<const node> operator[](const toml::path& path) const noexcept
- {
- return err_ ? node_view<const node>{} : table()[path];
- }
-
- /// \brief Gets a node_view for the selected key-value pair in the wrapped table.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if parsing was successful and a matching key existed,
- /// or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<node> operator[](std::string_view key) noexcept
- {
- return err_ ? node_view<node>{} : table()[key];
- }
-
- /// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if parsing was successful and a matching key existed,
- /// or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<const node> operator[](std::string_view key) const noexcept
- {
- return err_ ? node_view<const node>{} : table()[key];
- }
+ /// \brief Returns a view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::operator[](const toml::path&)
+ TOML_NODISCARD
+ node_view<node> operator[](const toml::path& path) noexcept {
+ return err_ ? node_view<node>{} : table()[path];
+ }
+
+ /// \brief Returns a const view of the subnode matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::node::operator[](const toml::path&)
+ TOML_NODISCARD
+ node_view<const node> operator[](const toml::path& path) const noexcept {
+ return err_ ? node_view<const node>{} : table()[path];
+ }
+
+ /// \brief Gets a node_view for the selected key-value pair in the wrapped table.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if parsing was successful and a matching key
+ /// existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<node> operator[](std::string_view key) noexcept {
+ return err_ ? node_view<node>{} : table()[key];
+ }
+
+ /// \brief Gets a node_view for the selected key-value pair in the wrapped table (const
+ /// overload).
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if parsing was successful and a matching key
+ /// existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<const node> operator[](std::string_view key) const noexcept {
+ return err_ ? node_view<const node>{} : table()[key];
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets a node_view for the selected key-value pair in the wrapped table.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if parsing was successful and a matching key existed,
- /// or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<node> operator[](std::wstring_view key)
- {
- return err_ ? node_view<node>{} : table()[key];
- }
-
- /// \brief Gets a node_view for the selected key-value pair in the wrapped table (const overload).
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if parsing was successful and a matching key existed,
- /// or an empty node view.
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<const node> operator[](std::wstring_view key) const
- {
- return err_ ? node_view<const node>{} : table()[key];
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// @}
+ /// \brief Gets a node_view for the selected key-value pair in the wrapped table.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if parsing was successful and a matching key
+ /// existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<node> operator[](std::wstring_view key) {
+ return err_ ? node_view<node>{} : table()[key];
+ }
+
+ /// \brief Gets a node_view for the selected key-value pair in the wrapped table (const
+ /// overload).
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if parsing was successful and a matching key
+ /// existed, or an empty node view.
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<const node> operator[](std::wstring_view key) const {
+ return err_ ? node_view<const node>{} : table()[key];
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// @}
#if TOML_ENABLE_FORMATTERS
- /// \brief Prints the held error or table object out to a text stream.
- ///
- /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
- friend std::ostream& operator<<(std::ostream& os, const parse_result& result)
- {
- return result.err_ ? (os << result.error()) : (os << result.table());
- }
+ /// \brief Prints the held error or table object out to a text stream.
+ ///
+ /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ friend std::ostream& operator<<(std::ostream& os, const parse_result& result) {
+ return result.err_ ? (os << result.error()) : (os << result.table());
+ }
#endif
- };
+ };
- TOML_ABI_NAMESPACE_END;
+ TOML_ABI_NAMESPACE_END;
}
TOML_NAMESPACE_END;
#include "header_end.hpp"
-#endif // TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
+#endif // TOML_ENABLE_PARSER && !TOML_EXCEPTIONS
diff --git a/vendor/toml++/impl/parser.hpp b/vendor/toml++/impl/parser.hpp
index c794c5e..281efbc 100644
--- a/vendor/toml++/impl/parser.hpp
+++ b/vendor/toml++/impl/parser.hpp
@@ -1,390 +1,386 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_ENABLE_PARSER
-#include "table.hpp"
-#include "parse_result.hpp"
#include "header_start.hpp"
+#include "parse_result.hpp"
+#include "table.hpp"
-TOML_NAMESPACE_START
-{
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
+TOML_NAMESPACE_START {
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, ex, noex);
- /// \brief Parses a TOML document from a string view.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse("a = 3"sv);
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::string_view doc, std::string_view source_path = {});
+ /// \brief Parses a TOML document from a string view.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse("a = 3"sv);
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::string_view doc, std::string_view source_path = {});
- /// \brief Parses a TOML document from a string view.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse("a = 3"sv, "foo.toml");
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::string_view doc, std::string && source_path);
+ /// \brief Parses a TOML document from a string view.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse("a = 3"sv, "foo.toml");
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::string_view doc, std::string && source_path);
- /// \brief Parses a TOML document from a file.
- ///
- /// \detail \cpp
- /// toml::parse_result get_foo_toml()
- /// {
- /// return toml::parse_file("foo.toml");
- /// }
- /// \ecpp
- ///
- /// \param file_path The TOML document to parse. Must be valid UTF-8.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse_file(std::string_view file_path);
+ /// \brief Parses a TOML document from a file.
+ ///
+ /// \detail \cpp
+ /// toml::parse_result get_foo_toml()
+ /// {
+ /// return toml::parse_file("foo.toml");
+ /// }
+ /// \ecpp
+ ///
+ /// \param file_path The TOML document to parse. Must be valid UTF-8.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse_file(std::string_view file_path);
#if TOML_HAS_CHAR8
- /// \brief Parses a TOML document from a char8_t string view.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse(u8"a = 3"sv);
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::u8string_view doc, std::string_view source_path = {});
+ /// \brief Parses a TOML document from a char8_t string view.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse(u8"a = 3"sv);
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::u8string_view doc, std::string_view source_path = {});
- /// \brief Parses a TOML document from a char8_t string view.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::u8string_view doc, std::string && source_path);
+ /// \brief Parses a TOML document from a char8_t string view.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse(u8"a = 3"sv, "foo.toml");
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::u8string_view doc, std::string && source_path);
- /// \brief Parses a TOML document from a file.
- ///
- /// \detail \cpp
- /// toml::parse_result get_foo_toml()
- /// {
- /// return toml::parse_file(u8"foo.toml");
- /// }
- /// \ecpp
- ///
- /// \param file_path The TOML document to parse. Must be valid UTF-8.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse_file(std::u8string_view file_path);
+ /// \brief Parses a TOML document from a file.
+ ///
+ /// \detail \cpp
+ /// toml::parse_result get_foo_toml()
+ /// {
+ /// return toml::parse_file(u8"foo.toml");
+ /// }
+ /// \ecpp
+ ///
+ /// \param file_path The TOML document to parse. Must be valid UTF-8.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse_file(std::u8string_view file_path);
-#endif // TOML_HAS_CHAR8
+#endif // TOML_HAS_CHAR8
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a TOML document from a string view.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::string_view doc, std::wstring_view source_path);
+ /// \brief Parses a TOML document from a string view.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse("a = 3"sv, L"foo.toml");
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::string_view doc, std::wstring_view source_path);
- /// \brief Parses a TOML document from a stream.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \detail \cpp
- /// std::stringstream ss;
- /// ss << "a = 3"sv;
- ///
- /// auto tbl = toml::parse(ss);
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::istream & doc, std::wstring_view source_path);
+ /// \brief Parses a TOML document from a stream.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \detail \cpp
+ /// std::stringstream ss;
+ /// ss << "a = 3"sv;
+ ///
+ /// auto tbl = toml::parse(ss);
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::istream & doc, std::wstring_view source_path);
- /// \brief Parses a TOML document from a file.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \detail \cpp
- /// toml::parse_result get_foo_toml()
- /// {
- /// return toml::parse_file(L"foo.toml");
- /// }
- /// \ecpp
- ///
- /// \param file_path The TOML document to parse. Must be valid UTF-8.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse_file(std::wstring_view file_path);
+ /// \brief Parses a TOML document from a file.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \detail \cpp
+ /// toml::parse_result get_foo_toml()
+ /// {
+ /// return toml::parse_file(L"foo.toml");
+ /// }
+ /// \ecpp
+ ///
+ /// \param file_path The TOML document to parse. Must be valid UTF-8.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse_file(std::wstring_view file_path);
-#endif // TOML_ENABLE_WINDOWS_COMPAT
+#endif // TOML_ENABLE_WINDOWS_COMPAT
#if TOML_HAS_CHAR8 && TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a TOML document from a char8_t string view.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse(u8"a = 3"sv, L"foo.toml");
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::u8string_view doc, std::wstring_view source_path);
+ /// \brief Parses a TOML document from a char8_t string view.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse(u8"a = 3"sv, L"foo.toml");
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::u8string_view doc, std::wstring_view source_path);
-#endif // TOML_HAS_CHAR8 && TOML_ENABLE_WINDOWS_COMPAT
+#endif // TOML_HAS_CHAR8 && TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a TOML document from a stream.
- ///
- /// \detail \cpp
- /// std::stringstream ss;
- /// ss << "a = 3"sv;
- ///
- /// auto tbl = toml::parse(ss);
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::istream & doc, std::string_view source_path = {});
+ /// \brief Parses a TOML document from a stream.
+ ///
+ /// \detail \cpp
+ /// std::stringstream ss;
+ /// ss << "a = 3"sv;
+ ///
+ /// auto tbl = toml::parse(ss);
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::istream & doc, std::string_view source_path = {});
- /// \brief Parses a TOML document from a stream.
- ///
- /// \detail \cpp
- /// std::stringstream ss;
- /// ss << "a = 3"sv;
- ///
- /// auto tbl = toml::parse(ss, "foo.toml");
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param doc The TOML document to parse. Must be valid UTF-8.
- /// \param source_path The path used to initialize each node's `source().path`.
- /// If you don't have a path (or you have no intention of using paths in diagnostics)
- /// then this parameter can safely be left blank.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- parse_result TOML_CALLCONV parse(std::istream & doc, std::string && source_path);
+ /// \brief Parses a TOML document from a stream.
+ ///
+ /// \detail \cpp
+ /// std::stringstream ss;
+ /// ss << "a = 3"sv;
+ ///
+ /// auto tbl = toml::parse(ss, "foo.toml");
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param doc The TOML document to parse. Must be valid UTF-8.
+ /// \param source_path The path used to initialize each node's `source().path`.
+ /// If you don't have a path (or you have no intention of using paths in diagnostics)
+ /// then this parameter can safely be left blank.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ parse_result TOML_CALLCONV parse(std::istream & doc, std::string && source_path);
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
- inline namespace literals
- {
- TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, lit_ex, lit_noex);
+ inline namespace literals {
+ TOML_ABI_NAMESPACE_BOOL(TOML_EXCEPTIONS, lit_ex, lit_noex);
- /// \brief Parses TOML data from a string literal.
- ///
- /// \detail \cpp
- /// using namespace toml::literals;
- ///
- /// auto tbl = "a = 3"_toml;
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param str The string data. Must be valid UTF-8.
- /// \param len The string length.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- parse_result operator"" _toml(const char* str, size_t len)
- {
- return parse(std::string_view{ str, len });
- }
+ /// \brief Parses TOML data from a string literal.
+ ///
+ /// \detail \cpp
+ /// using namespace toml::literals;
+ ///
+ /// auto tbl = "a = 3"_toml;
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param str The string data. Must be valid UTF-8.
+ /// \param len The string length.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ parse_result operator"" _toml(const char* str, size_t len) {
+ return parse(std::string_view{str, len});
+ }
#if TOML_HAS_CHAR8
- /// \brief Parses TOML data from a UTF-8 string literal.
- ///
- /// \detail \cpp
- /// using namespace toml::literals;
- ///
- /// auto tbl = u8"a = 3"_toml;
- /// std::cout << tbl["a"] << "\n";
- /// \ecpp
- ///
- /// \out
- /// 3
- /// \eout
- ///
- /// \param str The string data. Must be valid UTF-8.
- /// \param len The string length.
- ///
- /// \returns \conditional_return{With exceptions}
- /// A toml::table.
- /// \conditional_return{Without exceptions}
- /// A toml::parse_result.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- parse_result operator"" _toml(const char8_t* str, size_t len)
- {
- return parse(std::u8string_view{ str, len });
- }
+ /// \brief Parses TOML data from a UTF-8 string literal.
+ ///
+ /// \detail \cpp
+ /// using namespace toml::literals;
+ ///
+ /// auto tbl = u8"a = 3"_toml;
+ /// std::cout << tbl["a"] << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 3
+ /// \eout
+ ///
+ /// \param str The string data. Must be valid UTF-8.
+ /// \param len The string length.
+ ///
+ /// \returns \conditional_return{With exceptions}
+ /// A toml::table.
+ /// \conditional_return{Without exceptions}
+ /// A toml::parse_result.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ parse_result operator"" _toml(const char8_t* str, size_t len) {
+ return parse(std::u8string_view{str, len});
+ }
-#endif // TOML_HAS_CHAR8
+#endif // TOML_HAS_CHAR8
- TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
- }
+ TOML_ABI_NAMESPACE_END; // TOML_EXCEPTIONS
+ } // namespace literals
}
TOML_NAMESPACE_END;
#include "header_end.hpp"
-#endif // TOML_ENABLE_PARSER
+#endif // TOML_ENABLE_PARSER
diff --git a/vendor/toml++/impl/path.hpp b/vendor/toml++/impl/path.hpp
index 5bd0ef3..db3faaa 100644
--- a/vendor/toml++/impl/path.hpp
+++ b/vendor/toml++/impl/path.hpp
@@ -1,850 +1,725 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "forward_declarations.hpp"
-#include "std_vector.hpp"
#include "header_start.hpp"
+#include "std_vector.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief Indicates type of path component, either a key, an index in an array, or invalid
- enum class TOML_CLOSED_ENUM path_component_type : uint8_t
- {
- key = 0x1,
- array_index = 0x2
- };
-
- /// \brief Represents a single component of a complete 'TOML-path': either a key or an array index
- class TOML_EXPORTED_CLASS path_component
- {
- /// \cond
- struct storage_t
- {
- static constexpr size_t size =
- (sizeof(size_t) < sizeof(std::string) ? sizeof(std::string) : sizeof(size_t));
- static constexpr size_t align =
- (alignof(size_t) < alignof(std::string) ? alignof(std::string) : alignof(size_t));
-
- alignas(align) unsigned char bytes[size];
- };
- alignas(storage_t::align) mutable storage_t value_storage_;
-
- path_component_type type_;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_STATIC_FUNCTION
- static bool TOML_CALLCONV equal(const path_component&, const path_component&) noexcept;
-
- template <typename Type>
- TOML_PURE_INLINE_GETTER
- static Type* get_as(storage_t& s) noexcept
- {
- return TOML_LAUNDER(reinterpret_cast<Type*>(s.bytes));
- }
-
- static void store_key(std::string_view key, storage_t& storage_)
- {
- ::new (static_cast<void*>(storage_.bytes)) std::string{ key };
- }
-
- static void store_index(size_t index, storage_t& storage_) noexcept
- {
- ::new (static_cast<void*>(storage_.bytes)) std::size_t{ index };
- }
-
- void destroy() noexcept
- {
- if (type_ == path_component_type::key)
- get_as<std::string>(value_storage_)->~basic_string();
- }
-
- TOML_NODISCARD
- size_t& index_ref() noexcept
- {
- TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
- return *get_as<size_t>(value_storage_);
- }
-
- TOML_NODISCARD
- std::string& key_ref() noexcept
- {
- TOML_ASSERT_ASSUME(type_ == path_component_type::key);
- return *get_as<std::string>(value_storage_);
- }
- /// \endcond
-
- public:
- /// \brief Default constructor (creates an empty key).
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component();
-
- /// \brief Constructor for a path component that is an array index
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component(size_t index) noexcept;
-
- /// \brief Constructor for a path component that is a key string
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component(std::string_view key);
+TOML_NAMESPACE_START {
+ /// \brief Indicates type of path component, either a key, an index in an array, or invalid
+ enum class TOML_CLOSED_ENUM path_component_type : uint8_t { key = 0x1, array_index = 0x2 };
+
+ /// \brief Represents a single component of a complete 'TOML-path': either a key or an array index
+ class TOML_EXPORTED_CLASS path_component {
+ /// \cond
+ struct storage_t {
+ static constexpr size_t size =
+ (sizeof(size_t) < sizeof(std::string) ? sizeof(std::string) : sizeof(size_t));
+ static constexpr size_t align =
+ (alignof(size_t) < alignof(std::string) ? alignof(std::string) : alignof(size_t));
+
+ alignas(align) unsigned char bytes[size];
+ };
+ alignas(storage_t::align) mutable storage_t value_storage_;
+
+ path_component_type type_;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_STATIC_FUNCTION
+ static bool TOML_CALLCONV equal(const path_component&, const path_component&) noexcept;
+
+ template <typename Type>
+ TOML_PURE_INLINE_GETTER static Type* get_as(storage_t& s) noexcept {
+ return TOML_LAUNDER(reinterpret_cast<Type*>(s.bytes));
+ }
+
+ static void store_key(std::string_view key, storage_t& storage_) {
+ ::new (static_cast<void*>(storage_.bytes)) std::string{key};
+ }
+
+ static void store_index(size_t index, storage_t& storage_) noexcept {
+ ::new (static_cast<void*>(storage_.bytes)) std::size_t{index};
+ }
+
+ void destroy() noexcept {
+ if (type_ == path_component_type::key) get_as<std::string>(value_storage_)->~basic_string();
+ }
+
+ TOML_NODISCARD
+ size_t& index_ref() noexcept {
+ TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
+ return *get_as<size_t>(value_storage_);
+ }
+
+ TOML_NODISCARD
+ std::string& key_ref() noexcept {
+ TOML_ASSERT_ASSUME(type_ == path_component_type::key);
+ return *get_as<std::string>(value_storage_);
+ }
+ /// \endcond
+
+ public:
+ /// \brief Default constructor (creates an empty key).
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component();
+
+ /// \brief Constructor for a path component that is an array index
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component(size_t index) noexcept;
+
+ /// \brief Constructor for a path component that is a key string
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component(std::string_view key);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Constructor for a path component that is a key string
- ///
- /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component(std::wstring_view key);
+ /// \brief Constructor for a path component that is a key string
+ ///
+ /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is
+ /// enabled.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component(std::wstring_view key);
#endif
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component(const path_component& pc);
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component(const path_component& pc);
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component(path_component&& pc) noexcept;
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component(path_component&& pc) noexcept;
- /// \brief Copy-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component& operator=(const path_component& rhs);
+ /// \brief Copy-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component& operator=(const path_component& rhs);
- /// \brief Move-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component& operator=(path_component&& rhs) noexcept;
+ /// \brief Move-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component& operator=(path_component&& rhs) noexcept;
- /// \brief Assigns an array index to this path component.
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component& operator=(size_t new_index) noexcept;
+ /// \brief Assigns an array index to this path component.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component& operator=(size_t new_index) noexcept;
- /// \brief Assigns a path key to this path component.
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component& operator=(std::string_view new_key);
+ /// \brief Assigns a path key to this path component.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component& operator=(std::string_view new_key);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Assigns a path key to this path component.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_EXPORTED_MEMBER_FUNCTION
- path_component& operator=(std::wstring_view new_key);
+ /// \brief Assigns a path key to this path component.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path_component& operator=(std::wstring_view new_key);
#endif
- /// \brief Destructor.
- ~path_component() noexcept
- {
- destroy();
- }
-
- /// \name Array index accessors
- /// \warning It is undefined behaviour to call these functions when the path component does not represent an array index.
- /// Check #type() to determine the component's value type.
- /// @{
-
- /// \brief Returns the array index (const lvalue overload).
- TOML_PURE_GETTER
- size_t index() const noexcept
- {
- TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
- return *get_as<const size_t>(value_storage_);
- }
-
- /// \brief Returns the array index (const lvalue).
- TOML_PURE_INLINE_GETTER
- explicit operator size_t() const noexcept
- {
- return index();
- }
-
- /// @}
-
- /// \name Key accessors
- /// \warning It is undefined behaviour to call these functions when the path component does not represent a key.
- /// Check #type() to determine the component's value type.
- /// @{
-
- /// \brief Returns the key string.
- TOML_PURE_GETTER
- const std::string& key() const noexcept
- {
- TOML_ASSERT_ASSUME(type_ == path_component_type::key);
- return *get_as<const std::string>(value_storage_);
- }
-
- /// \brief Returns the key string.
- TOML_PURE_INLINE_GETTER
- explicit operator const std::string&() const noexcept
- {
- return key();
- }
-
- /// @}
-
- /// \brief Retrieve the type of this path component, either path_component::key or path_component::array_index
- TOML_PURE_INLINE_GETTER
- path_component_type type() const noexcept
- {
- return type_;
- }
-
- /// \name Equality
- /// @{
-
- /// \brief Returns true if two path components represent the same key or array index.
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const path_component& lhs, const path_component& rhs) noexcept
- {
- return equal(lhs, rhs);
- }
-
- /// \brief Returns true if two path components do not represent the same key or array index.
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const path_component& lhs, const path_component& rhs) noexcept
- {
- return !equal(lhs, rhs);
- }
-
- /// @}
- };
-
- /// \brief A TOML path.
- ///
- /// \detail This type parses and represents a path to a TOML node. It validates
- /// the syntax of the path but does not ensure that the path refers to
- /// a valid node in any particular TOML document. If parsing fails,
- /// the object will evaluate as 'falsy', and will be empty.
- ///
- /// \cpp
- /// toml::path the_path("animals.cats[1]");
- ///
- /// // can use with tbl.at_path or operator[]
- /// std::cout << "second cat: " << tbl[the_path] << "\n";
- /// std::cout << "cats: " << tbl.at_path(the_path.parent_path()) << "\n";
- /// \ecpp
- ///
- /// \out
- /// second cat: lion
- /// cats: ['tiger', 'lion', 'puma']
- /// \eout
- class TOML_EXPORTED_CLASS path
- {
- private:
- /// \cond
-
- std::vector<path_component> components_;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_to(std::ostream&) const;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_STATIC_FUNCTION
- static bool TOML_CALLCONV equal(const path&, const path&) noexcept;
-
- /// \endcond
-
- public:
- /// \brief Default constructor.
- TOML_NODISCARD_CTOR
- path() noexcept = default;
-
- /// \brief Construct a path by parsing from a string.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- explicit path(std::string_view);
+ /// \brief Destructor.
+ ~path_component() noexcept { destroy(); }
+
+ /// \name Array index accessors
+ /// \warning It is undefined behaviour to call these functions when the path component does not
+ /// represent an array index. Check #type() to determine the component's value type.
+ /// @{
+
+ /// \brief Returns the array index (const lvalue overload).
+ TOML_PURE_GETTER
+ size_t index() const noexcept {
+ TOML_ASSERT_ASSUME(type_ == path_component_type::array_index);
+ return *get_as<const size_t>(value_storage_);
+ }
+
+ /// \brief Returns the array index (const lvalue).
+ TOML_PURE_INLINE_GETTER
+ explicit operator size_t() const noexcept { return index(); }
+
+ /// @}
+
+ /// \name Key accessors
+ /// \warning It is undefined behaviour to call these functions when the path component does not
+ /// represent a key. Check #type() to determine the component's value type.
+ /// @{
+
+ /// \brief Returns the key string.
+ TOML_PURE_GETTER
+ const std::string& key() const noexcept {
+ TOML_ASSERT_ASSUME(type_ == path_component_type::key);
+ return *get_as<const std::string>(value_storage_);
+ }
+
+ /// \brief Returns the key string.
+ TOML_PURE_INLINE_GETTER
+ explicit operator const std::string&() const noexcept { return key(); }
+
+ /// @}
+
+ /// \brief Retrieve the type of this path component, either path_component::key or
+ /// path_component::array_index
+ TOML_PURE_INLINE_GETTER
+ path_component_type type() const noexcept { return type_; }
+
+ /// \name Equality
+ /// @{
+
+ /// \brief Returns true if two path components represent the same key or array index.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const path_component& lhs, const path_component& rhs) noexcept {
+ return equal(lhs, rhs);
+ }
+
+ /// \brief Returns true if two path components do not represent the same key or array index.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const path_component& lhs, const path_component& rhs) noexcept {
+ return !equal(lhs, rhs);
+ }
+
+ /// @}
+ };
+
+ /// \brief A TOML path.
+ ///
+ /// \detail This type parses and represents a path to a TOML node. It validates
+ /// the syntax of the path but does not ensure that the path refers to
+ /// a valid node in any particular TOML document. If parsing fails,
+ /// the object will evaluate as 'falsy', and will be empty.
+ ///
+ /// \cpp
+ /// toml::path the_path("animals.cats[1]");
+ ///
+ /// // can use with tbl.at_path or operator[]
+ /// std::cout << "second cat: " << tbl[the_path] << "\n";
+ /// std::cout << "cats: " << tbl.at_path(the_path.parent_path()) << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// second cat: lion
+ /// cats: ['tiger', 'lion', 'puma']
+ /// \eout
+ class TOML_EXPORTED_CLASS path {
+ private:
+ /// \cond
+
+ std::vector<path_component> components_;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_to(std::ostream&) const;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_STATIC_FUNCTION
+ static bool TOML_CALLCONV equal(const path&, const path&) noexcept;
+
+ /// \endcond
+
+ public:
+ /// \brief Default constructor.
+ TOML_NODISCARD_CTOR
+ path() noexcept = default;
+
+ /// \brief Construct a path by parsing from a string.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ explicit path(std::string_view);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Construct a path by parsing from a string.
- ///
- /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- explicit path(std::wstring_view);
+ /// \brief Construct a path by parsing from a string.
+ ///
+ /// \availability This constructor is only available when #TOML_ENABLE_WINDOWS_COMPAT is
+ /// enabled.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ explicit path(std::wstring_view);
#endif
- /// \brief Default destructor.
- ~path() noexcept = default;
-
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- path(const path&) = default;
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- path(path&&) noexcept = default;
-
- /// \brief Returns the number of components in the path.
- TOML_PURE_INLINE_GETTER
- size_t size() const noexcept
- {
- return components_.size();
- }
-
- /// \brief Returns true if the path has one or more components.
- TOML_PURE_INLINE_GETTER
- explicit operator bool() const noexcept
- {
- return !components_.empty();
- }
-
- /// \brief Whether (true) or not (false) the path is empty
- TOML_PURE_INLINE_GETTER
- bool empty() const noexcept
- {
- return components_.empty();
- }
-
- /// \brief Fetch a path component by index.
- TOML_PURE_INLINE_GETTER
- path_component& operator[](size_t index) noexcept
- {
- TOML_ASSERT(index < size());
- return components_[index];
- }
-
- /// \brief Fetch a path component by index (const overload).
- TOML_PURE_INLINE_GETTER
- const path_component& operator[](size_t index) const noexcept
- {
- TOML_ASSERT(index < size());
- return components_[index];
- }
-
- /// \name Assignment
- /// @{
-
- /// \brief Copy-assignment operator.
- path& operator=(const path&) = default;
-
- /// \brief Move-assignment operator.
- path& operator=(path&&) noexcept = default;
-
- /// \brief Replaces the contents of the path by parsing from a string.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator=(std::string_view);
+ /// \brief Default destructor.
+ ~path() noexcept = default;
+
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ path(const path&) = default;
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ path(path&&) noexcept = default;
+
+ /// \brief Returns the number of components in the path.
+ TOML_PURE_INLINE_GETTER
+ size_t size() const noexcept { return components_.size(); }
+
+ /// \brief Returns true if the path has one or more components.
+ TOML_PURE_INLINE_GETTER
+ explicit operator bool() const noexcept { return !components_.empty(); }
+
+ /// \brief Whether (true) or not (false) the path is empty
+ TOML_PURE_INLINE_GETTER
+ bool empty() const noexcept { return components_.empty(); }
+
+ /// \brief Fetch a path component by index.
+ TOML_PURE_INLINE_GETTER
+ path_component& operator[](size_t index) noexcept {
+ TOML_ASSERT(index < size());
+ return components_[index];
+ }
+
+ /// \brief Fetch a path component by index (const overload).
+ TOML_PURE_INLINE_GETTER
+ const path_component& operator[](size_t index) const noexcept {
+ TOML_ASSERT(index < size());
+ return components_[index];
+ }
+
+ /// \name Assignment
+ /// @{
+
+ /// \brief Copy-assignment operator.
+ path& operator=(const path&) = default;
+
+ /// \brief Move-assignment operator.
+ path& operator=(path&&) noexcept = default;
+
+ /// \brief Replaces the contents of the path by parsing from a string.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator=(std::string_view);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Replaces the contents of the path by parsing from a string.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator=(std::wstring_view);
+ /// \brief Replaces the contents of the path by parsing from a string.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator=(std::wstring_view);
#endif
- /// \brief Replaces the contents of the path with that of another.
- TOML_ALWAYS_INLINE
- path& assign(const path& p)
- {
- return *this = p;
- }
-
- /// \brief Replaces the contents of the path with that of another.
- TOML_ALWAYS_INLINE
- path& assign(path&& p) noexcept
- {
- return *this = std::move(p);
- }
-
- /// \brief Replaces the contents of the path object by a new path
- TOML_ALWAYS_INLINE
- path& assign(std::string_view str)
- {
- return *this = str;
- }
+ /// \brief Replaces the contents of the path with that of another.
+ TOML_ALWAYS_INLINE
+ path& assign(const path& p) { return *this = p; }
+
+ /// \brief Replaces the contents of the path with that of another.
+ TOML_ALWAYS_INLINE
+ path& assign(path&& p) noexcept { return *this = std::move(p); }
+
+ /// \brief Replaces the contents of the path object by a new path
+ TOML_ALWAYS_INLINE
+ path& assign(std::string_view str) { return *this = str; }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Replaces the contents of the path object by a new path
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_ALWAYS_INLINE
- path& assign(std::wstring_view str)
- {
- return *this = str;
- }
+ /// \brief Replaces the contents of the path object by a new path
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_ALWAYS_INLINE
+ path& assign(std::wstring_view str) { return *this = str; }
#endif
- /// @}
+ /// @}
- /// \name Appending
- /// @{
+ /// \name Appending
+ /// @{
- /// \brief Appends another path onto the end of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator+=(const path&);
+ /// \brief Appends another path onto the end of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator+=(const path&);
- /// \brief Appends another path onto the end of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator+=(path&&);
+ /// \brief Appends another path onto the end of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator+=(path&&);
- /// \brief Parses a path and appends it onto the end of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator+=(std::string_view);
+ /// \brief Parses a path and appends it onto the end of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator+=(std::string_view);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a path and appends it onto the end of this one.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& operator+=(std::wstring_view);
+ /// \brief Parses a path and appends it onto the end of this one.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& operator+=(std::wstring_view);
#endif
- /// \brief Appends another path onto the end of this one.
- TOML_ALWAYS_INLINE
- path& append(const path& p)
- {
- return *this += p;
- }
-
- /// \brief Appends another path onto the end of this one.
- TOML_ALWAYS_INLINE
- path& append(path&& p)
- {
- return *this += std::move(p);
- }
-
- /// \brief Parses a path and appends it onto the end of this one.
- TOML_ALWAYS_INLINE
- path& append(std::string_view str)
- {
- return *this += str;
- }
+ /// \brief Appends another path onto the end of this one.
+ TOML_ALWAYS_INLINE
+ path& append(const path& p) { return *this += p; }
+
+ /// \brief Appends another path onto the end of this one.
+ TOML_ALWAYS_INLINE
+ path& append(path&& p) { return *this += std::move(p); }
+
+ /// \brief Parses a path and appends it onto the end of this one.
+ TOML_ALWAYS_INLINE
+ path& append(std::string_view str) { return *this += str; }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a path and appends it onto the end of this one.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_ALWAYS_INLINE
- path& append(std::wstring_view str)
- {
- return *this += str;
- }
+ /// \brief Parses a path and appends it onto the end of this one.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_ALWAYS_INLINE
+ path& append(std::wstring_view str) { return *this += str; }
#endif
- /// @}
+ /// @}
- /// \name Prepending
- /// @{
+ /// \name Prepending
+ /// @{
- /// \brief Prepends another path onto the beginning of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& prepend(const path&);
+ /// \brief Prepends another path onto the beginning of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& prepend(const path&);
- /// \brief Prepends another path onto the beginning of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& prepend(path&&);
+ /// \brief Prepends another path onto the beginning of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& prepend(path&&);
- /// \brief Parses a path and prepends it onto the beginning of this one.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& prepend(std::string_view);
+ /// \brief Parses a path and prepends it onto the beginning of this one.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& prepend(std::string_view);
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Parses a path and prepends it onto the beginning of this one.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_EXPORTED_MEMBER_FUNCTION
- path& prepend(std::wstring_view);
+ /// \brief Parses a path and prepends it onto the beginning of this one.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& prepend(std::wstring_view);
#endif
- /// @}
-
- /// \name Concatenation
- /// @{
-
- /// \brief Concatenates two paths.
- TOML_NODISCARD
- friend path operator+(const path& lhs, const path& rhs)
- {
- path result = lhs;
- result += rhs;
- return result;
- }
-
- /// \brief Concatenates two paths.
- TOML_NODISCARD
- friend path operator+(const path& lhs, std::string_view rhs)
- {
- path result = lhs;
- result += rhs;
- return result;
- }
-
- /// \brief Concatenates two paths.
- TOML_NODISCARD
- friend path operator+(std::string_view lhs, const path& rhs)
- {
- path result = rhs;
- result.prepend(lhs);
- return result;
- }
+ /// @}
+
+ /// \name Concatenation
+ /// @{
+
+ /// \brief Concatenates two paths.
+ TOML_NODISCARD
+ friend path operator+(const path& lhs, const path& rhs) {
+ path result = lhs;
+ result += rhs;
+ return result;
+ }
+
+ /// \brief Concatenates two paths.
+ TOML_NODISCARD
+ friend path operator+(const path& lhs, std::string_view rhs) {
+ path result = lhs;
+ result += rhs;
+ return result;
+ }
+
+ /// \brief Concatenates two paths.
+ TOML_NODISCARD
+ friend path operator+(std::string_view lhs, const path& rhs) {
+ path result = rhs;
+ result.prepend(lhs);
+ return result;
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Concatenates two paths.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- friend path operator+(const path& lhs, std::wstring_view rhs)
- {
- path result = lhs;
- result += rhs;
- return result;
- }
-
- /// \brief Concatenates two paths.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- friend path operator+(std::wstring_view lhs, const path& rhs)
- {
- path result = rhs;
- result.prepend(lhs);
- return result;
- }
+ /// \brief Concatenates two paths.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ friend path operator+(const path& lhs, std::wstring_view rhs) {
+ path result = lhs;
+ result += rhs;
+ return result;
+ }
+
+ /// \brief Concatenates two paths.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ friend path operator+(std::wstring_view lhs, const path& rhs) {
+ path result = rhs;
+ result.prepend(lhs);
+ return result;
+ }
#endif
- /// @}
+ /// @}
- /// \name String conversion
- /// @{
+ /// \name String conversion
+ /// @{
- /// \brief Prints the string representation of a #toml::path out to a stream.
- TOML_ALWAYS_INLINE
- friend std::ostream& operator<<(std::ostream& os, const path& rhs)
- {
- rhs.print_to(os);
- return os;
- }
+ /// \brief Prints the string representation of a #toml::path out to a stream.
+ TOML_ALWAYS_INLINE
+ friend std::ostream& operator<<(std::ostream& os, const path& rhs) {
+ rhs.print_to(os);
+ return os;
+ }
- /// \brief Returns a string representation of this path.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- std::string str() const;
+ /// \brief Returns a string representation of this path.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ std::string str() const;
- /// \brief Returns a string representation of this path.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- explicit operator std::string() const
- {
- return str();
- }
+ /// \brief Returns a string representation of this path.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ explicit operator std::string() const { return str(); }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns a string representation of this path.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- std::wstring wide_str() const;
-
- /// \brief Returns a string representation of this path.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- explicit operator std::wstring() const
- {
- return wide_str();
- }
+ /// \brief Returns a string representation of this path.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ std::wstring wide_str() const;
+
+ /// \brief Returns a string representation of this path.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ explicit operator std::wstring() const { return wide_str(); }
#endif
- /// @}
-
- /// \name Equality
- /// @{
-
- /// \brief Returns whether two paths are the same.
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const path& lhs, const path& rhs) noexcept
- {
- return equal(lhs, rhs);
- }
-
- /// \brief Returns whether two paths are not the same.
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const path& lhs, const path& rhs) noexcept
- {
- return !equal(lhs, rhs);
- }
-
- /// \brief Returns whether two paths are the same.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator==(const path& lhs, std::string_view rhs)
- {
- return lhs == path{ rhs };
- }
-
- /// \brief Returns whether two paths are the same.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator==(std::string_view lhs, const path& rhs)
- {
- return rhs == lhs;
- }
-
- /// \brief Returns whether two paths are not the same.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator!=(const path& lhs, std::string_view rhs)
- {
- return lhs != path{ rhs };
- }
-
- /// \brief Returns whether two paths are not the same.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator!=(std::string_view lhs, const path& rhs)
- {
- return rhs != lhs;
- }
+ /// @}
+
+ /// \name Equality
+ /// @{
+
+ /// \brief Returns whether two paths are the same.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const path& lhs, const path& rhs) noexcept { return equal(lhs, rhs); }
+
+ /// \brief Returns whether two paths are not the same.
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const path& lhs, const path& rhs) noexcept { return !equal(lhs, rhs); }
+
+ /// \brief Returns whether two paths are the same.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator==(const path& lhs, std::string_view rhs) { return lhs == path{rhs}; }
+
+ /// \brief Returns whether two paths are the same.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator==(std::string_view lhs, const path& rhs) { return rhs == lhs; }
+
+ /// \brief Returns whether two paths are not the same.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator!=(const path& lhs, std::string_view rhs) { return lhs != path{rhs}; }
+
+ /// \brief Returns whether two paths are not the same.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator!=(std::string_view lhs, const path& rhs) { return rhs != lhs; }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns whether two paths are the same.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator==(const path& lhs, std::wstring_view rhs)
- {
- return lhs == path{ rhs };
- }
-
- /// \brief Returns whether two paths are the same.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator==(std::wstring_view lhs, const path& rhs)
- {
- return rhs == lhs;
- }
-
- /// \brief Returns whether two paths are not the same.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator!=(const path& lhs, std::wstring_view rhs)
- {
- return lhs != path{ rhs };
- }
-
- /// \brief Returns whether two paths are not the same.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- friend bool operator!=(std::wstring_view lhs, const path& rhs)
- {
- return rhs != lhs;
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// @}
-
- /// \name Iteration
- /// @{
-
- /// An iterator for iterating over the components in the path.
- /// \see #toml::path_component
- using iterator = std::vector<path_component>::iterator;
-
- /// A const iterator for iterating over the components in the path.
- /// \see #toml::path_component
- using const_iterator = std::vector<path_component>::const_iterator;
-
- /// \brief Returns an iterator to the first component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- iterator begin() noexcept
- {
- return components_.begin();
- }
-
- /// \brief Returns an iterator to one-past-the-last component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- iterator end() noexcept
- {
- return components_.end();
- }
-
- /// \brief Returns a const iterator to the first component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- const_iterator begin() const noexcept
- {
- return components_.begin();
- }
-
- /// \brief Returns a const iterator to one-past-the-last component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- const_iterator end() const noexcept
- {
- return components_.end();
- }
-
- /// \brief Returns a const iterator to the first component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- const_iterator cbegin() const noexcept
- {
- return components_.begin();
- }
-
- /// \brief Returns a const iterator to one-past-the-last component in the path.
- /// \see #toml::path_component
- TOML_PURE_INLINE_GETTER
- const_iterator cend() const noexcept
- {
- return components_.end();
- }
-
- /// @}
-
- /// \name Subpaths and Truncation
- /// @{
-
- /// \brief Erases the contents of the path.
- TOML_EXPORTED_MEMBER_FUNCTION
- void clear() noexcept;
-
- /// \brief Removes the number of terminal path components specified by n
- TOML_EXPORTED_MEMBER_FUNCTION
- path& truncate(size_t n);
-
- /// \brief Returns a toml::path object which has had n terminal path components removed
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- path truncated(size_t n) const;
-
- /// \brief Returns a toml::path object representing the path of the parent node
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- path parent() const;
-
- /// \brief Returns a toml::path object representing terminal n-parts of a TOML path
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- path leaf(size_t n = 1) const;
-
- /// \brief Returns a toml::path object that is a specified subpath of the current path, representing the
- /// range of path components from [start, end).
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- path subpath(const_iterator start, const_iterator end) const;
-
- /// \brief Returns a toml::path object that is a specified subpath of the current path, representing the
- /// range of path components with indexes from [start, start + length].
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- path subpath(size_t start, size_t length) const;
-
- /// @}
- };
-
- inline namespace literals
- {
- /// \brief Parses a TOML path from a string literal.
- ///
- /// \detail \cpp
- /// using namespace toml::literals;
- ///
- /// auto path = "main.settings.devices[2]"_tpath;
- /// std::cout << path.parent_path() << "\n";
- /// \ecpp
- ///
- /// \out
- /// main.settings.devices
- /// \eout
- ///
- /// \param str The string data.
- /// \param len The string length.
- ///
- /// \returns A #toml::path generated from the string literal.
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- path operator"" _tpath(const char* str, size_t len)
- {
- return path(std::string_view{ str, len });
- }
- }
-
- /// \brief Returns a view of the node matching a fully-qualified "TOML path".
- ///
- /// \detail \cpp
- /// auto config = toml::parse(R"(
- ///
- /// [foo]
- /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- ///
- /// )"sv);
- ///
- /// toml::path path1("foo.bar[2]");
- /// toml::path path2("foo.bar[4].kek");
- /// std::cout << toml::at_path(config, path1) << "\n";
- /// std::cout << toml::at_path(config, path1.parent_path()) << "\n";
- /// std::cout << toml::at_path(config, path2) << "\n";
- /// std::cout << toml::at_path(config, path2.parent_path()) << "\n";
- /// \ecpp
- ///
- /// \out
- /// 2
- /// [ 0, 1, 2, [ 3 ], { kek = 4 } ]
- /// 4
- /// { kek = 4 }
- /// \eout
- ///
- ///
- /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
- /// \cpp
- /// toml::at_path(config, toml::path("foo.bar")) // same as config["foo"]["bar"]
- /// toml::at_path(config, toml::path("foo. bar")) // same as config["foo"][" bar"]
- /// toml::at_path(config, toml::path("foo..bar")) // same as config["foo"][""]["bar"]
- /// toml::at_path(config, toml::path(".foo.bar")) // same as config[""]["foo"]["bar"]
- /// \ecpp
- /// <br>
- /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted strings.
- /// This function makes no allowance for this, instead treating all period characters as sub-table delimiters.
- ///
- /// \param root The root node from which the path will be traversed.
- /// \param path The "TOML path" to traverse.
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<node> TOML_CALLCONV at_path(node & root, const toml::path& path) noexcept;
-
- /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
- ///
- /// \see #toml::at_path(node&, const toml::path& path)
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- node_view<const node> TOML_CALLCONV at_path(const node& root, const toml::path& path) noexcept;
+ /// \brief Returns whether two paths are the same.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator==(const path& lhs, std::wstring_view rhs) { return lhs == path{rhs}; }
+
+ /// \brief Returns whether two paths are the same.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator==(std::wstring_view lhs, const path& rhs) { return rhs == lhs; }
+
+ /// \brief Returns whether two paths are not the same.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator!=(const path& lhs, std::wstring_view rhs) { return lhs != path{rhs}; }
+
+ /// \brief Returns whether two paths are not the same.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ friend bool operator!=(std::wstring_view lhs, const path& rhs) { return rhs != lhs; }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// @}
+
+ /// \name Iteration
+ /// @{
+
+ /// An iterator for iterating over the components in the path.
+ /// \see #toml::path_component
+ using iterator = std::vector<path_component>::iterator;
+
+ /// A const iterator for iterating over the components in the path.
+ /// \see #toml::path_component
+ using const_iterator = std::vector<path_component>::const_iterator;
+
+ /// \brief Returns an iterator to the first component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ iterator begin() noexcept { return components_.begin(); }
+
+ /// \brief Returns an iterator to one-past-the-last component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ iterator end() noexcept { return components_.end(); }
+
+ /// \brief Returns a const iterator to the first component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ const_iterator begin() const noexcept { return components_.begin(); }
+
+ /// \brief Returns a const iterator to one-past-the-last component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ const_iterator end() const noexcept { return components_.end(); }
+
+ /// \brief Returns a const iterator to the first component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ const_iterator cbegin() const noexcept { return components_.begin(); }
+
+ /// \brief Returns a const iterator to one-past-the-last component in the path.
+ /// \see #toml::path_component
+ TOML_PURE_INLINE_GETTER
+ const_iterator cend() const noexcept { return components_.end(); }
+
+ /// @}
+
+ /// \name Subpaths and Truncation
+ /// @{
+
+ /// \brief Erases the contents of the path.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void clear() noexcept;
+
+ /// \brief Removes the number of terminal path components specified by n
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path& truncate(size_t n);
+
+ /// \brief Returns a toml::path object which has had n terminal path components removed
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path truncated(size_t n) const;
+
+ /// \brief Returns a toml::path object representing the path of the parent node
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path parent() const;
+
+ /// \brief Returns a toml::path object representing terminal n-parts of a TOML path
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path leaf(size_t n = 1) const;
+
+ /// \brief Returns a toml::path object that is a specified subpath of the current path,
+ /// representing the range of path components from [start, end).
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path subpath(const_iterator start, const_iterator end) const;
+
+ /// \brief Returns a toml::path object that is a specified subpath of the current path,
+ /// representing the range of path components with indexes from [start, start + length].
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ path subpath(size_t start, size_t length) const;
+
+ /// @}
+ };
+
+ inline namespace literals {
+ /// \brief Parses a TOML path from a string literal.
+ ///
+ /// \detail \cpp
+ /// using namespace toml::literals;
+ ///
+ /// auto path = "main.settings.devices[2]"_tpath;
+ /// std::cout << path.parent_path() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// main.settings.devices
+ /// \eout
+ ///
+ /// \param str The string data.
+ /// \param len The string length.
+ ///
+ /// \returns A #toml::path generated from the string literal.
+ TOML_NODISCARD
+ TOML_ALWAYS_INLINE
+ path operator"" _tpath(const char* str, size_t len) {
+ return path(std::string_view{str, len});
+ }
+ } // namespace literals
+
+ /// \brief Returns a view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \detail \cpp
+ /// auto config = toml::parse(R"(
+ ///
+ /// [foo]
+ /// bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ ///
+ /// )"sv);
+ ///
+ /// toml::path path1("foo.bar[2]");
+ /// toml::path path2("foo.bar[4].kek");
+ /// std::cout << toml::at_path(config, path1) << "\n";
+ /// std::cout << toml::at_path(config, path1.parent_path()) << "\n";
+ /// std::cout << toml::at_path(config, path2) << "\n";
+ /// std::cout << toml::at_path(config, path2.parent_path()) << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// 2
+ /// [ 0, 1, 2, [ 3 ], { kek = 4 } ]
+ /// 4
+ /// { kek = 4 }
+ /// \eout
+ ///
+ ///
+ /// \note Keys in paths are interpreted literally, so whitespace (or lack thereof) matters:
+ /// \cpp
+ /// toml::at_path(config, toml::path("foo.bar")) // same as config["foo"]["bar"]
+ /// toml::at_path(config, toml::path("foo. bar")) // same as config["foo"][" bar"]
+ /// toml::at_path(config, toml::path("foo..bar")) // same as config["foo"][""]["bar"]
+ /// toml::at_path(config, toml::path(".foo.bar")) // same as config[""]["foo"]["bar"]
+ /// \ecpp
+ /// <br>
+ /// Additionally, TOML allows '.' (period) characters to appear in keys if they are quoted
+ /// strings. This function makes no allowance for this, instead treating all period characters as
+ /// sub-table delimiters.
+ ///
+ /// \param root The root node from which the path will be traversed.
+ /// \param path The "TOML path" to traverse.
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<node> TOML_CALLCONV at_path(node & root, const toml::path& path) noexcept;
+
+ /// \brief Returns a const view of the node matching a fully-qualified "TOML path".
+ ///
+ /// \see #toml::at_path(node&, const toml::path& path)
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ node_view<const node> TOML_CALLCONV at_path(const node& root, const toml::path& path) noexcept;
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/preprocessor.hpp b/vendor/toml++/impl/preprocessor.hpp
index feeb802..85972d2 100644
--- a/vendor/toml++/impl/preprocessor.hpp
+++ b/vendor/toml++/impl/preprocessor.hpp
@@ -1,12 +1,12 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-//#=====================================================================================================================
-//# C++ VERSION
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # C++ VERSION
+// #=====================================================================================================================
#ifndef __cplusplus
#error toml++ is a C++ library.
@@ -54,12 +54,12 @@
#error toml++ requires C++17 or higher. For a C++11 TOML library see https://github.com/ToruNiina/toml11
#endif
-//#=====================================================================================================================
-//# COMPILER
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # COMPILER
+// #=====================================================================================================================
#ifndef TOML_MAKE_VERSION
-#define TOML_MAKE_VERSION(major, minor, patch) (((major)*10000) + ((minor)*100) + ((patch)))
+#define TOML_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + ((patch)))
#endif
#ifndef TOML_INTELLISENSE
@@ -71,8 +71,8 @@
#endif
#ifndef TOML_DOXYGEN
-#if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || defined(__POXY__) \
- || defined(__poxy__)
+#if defined(DOXYGEN) || defined(__DOXYGEN) || defined(__DOXYGEN__) || defined(__doxygen__) || \
+ defined(__POXY__) || defined(__poxy__)
#define TOML_DOXYGEN 1
#else
#define TOML_DOXYGEN 0
@@ -115,7 +115,7 @@
#elif TOML_CLANG_VERSION >= TOML_MAKE_VERSION(10, 0, 1)
#define TOML_CLANG 7
#else
-#define TOML_CLANG 6 // not strictly correct but doesn't matter below this
+#define TOML_CLANG 6 // not strictly correct but doesn't matter below this
#endif
#undef TOML_CLANG_VERSION
#endif
@@ -130,7 +130,7 @@
#define TOML_ICC_CL 0
#endif
#else
-#define TOML_ICC 0
+#define TOML_ICC 0
#define TOML_ICC_CL 0
#endif
#endif
@@ -175,9 +175,9 @@
#endif
#endif
-//#=====================================================================================================================
-//# ARCHITECTURE
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # ARCHITECTURE
+// #=====================================================================================================================
#ifndef TOML_ARCH_ITANIUM
#if defined(__ia64__) || defined(__ia64) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64)
@@ -189,8 +189,9 @@
#endif
#ifndef TOML_ARCH_AMD64
-#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64)
-#define TOML_ARCH_AMD64 1
+#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
+ defined(_M_AMD64)
+#define TOML_ARCH_AMD64 1
#define TOML_ARCH_BITNESS 64
#else
#define TOML_ARCH_AMD64 0
@@ -199,7 +200,7 @@
#ifndef TOML_ARCH_X86
#if defined(__i386__) || defined(_M_IX86)
-#define TOML_ARCH_X86 1
+#define TOML_ARCH_X86 1
#define TOML_ARCH_BITNESS 32
#else
#define TOML_ARCH_X86 0
@@ -207,21 +208,21 @@
#endif
#ifndef TOML_ARCH_ARM
-#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || defined(__ARM_64BIT_STATE) \
- || defined(_M_ARM64EC)
-#define TOML_ARCH_ARM32 0
-#define TOML_ARCH_ARM64 1
-#define TOML_ARCH_ARM 1
+#if defined(__aarch64__) || defined(__ARM_ARCH_ISA_A64) || defined(_M_ARM64) || \
+ defined(__ARM_64BIT_STATE) || defined(_M_ARM64EC)
+#define TOML_ARCH_ARM32 0
+#define TOML_ARCH_ARM64 1
+#define TOML_ARCH_ARM 1
#define TOML_ARCH_BITNESS 64
#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_32BIT_STATE)
-#define TOML_ARCH_ARM32 1
-#define TOML_ARCH_ARM64 0
-#define TOML_ARCH_ARM 1
+#define TOML_ARCH_ARM32 1
+#define TOML_ARCH_ARM64 0
+#define TOML_ARCH_ARM 1
#define TOML_ARCH_BITNESS 32
#else
#define TOML_ARCH_ARM32 0
#define TOML_ARCH_ARM64 0
-#define TOML_ARCH_ARM 0
+#define TOML_ARCH_ARM 0
#endif
#endif
@@ -237,11 +238,12 @@
#endif
#endif
-//#=====================================================================================================================
-//# OS
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # OS
+// #=====================================================================================================================
-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__)
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || \
+ defined(__CYGWIN__)
#define TOML_WINDOWS 1
#else
#define TOML_WINDOWS 0
@@ -259,9 +261,9 @@
#define TOML_LINUX 0
#endif
-//#=====================================================================================================================
-//# ATTRIBUTES / FEATURE DETECTION / UTILITY MACROS
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # ATTRIBUTES / FEATURE DETECTION / UTILITY MACROS
+// #=====================================================================================================================
// TOML_HAS_INCLUDE
#ifndef TOML_HAS_INCLUDE
@@ -346,11 +348,11 @@
// TOML_CONCAT
#define TOML_CONCAT_1(x, y) x##y
-#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y)
+#define TOML_CONCAT(x, y) TOML_CONCAT_1(x, y)
// TOML_MAKE_STRING
#define TOML_MAKE_STRING_1(s) #s
-#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s)
+#define TOML_MAKE_STRING(s) TOML_MAKE_STRING_1(s)
// TOML_PRAGMA_XXXX (compiler-specific pragmas)
#if TOML_CLANG
@@ -398,9 +400,9 @@
#ifdef _MSC_VER
#define TOML_ALWAYS_INLINE __forceinline
#elif TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__always_inline__)
-#define TOML_ALWAYS_INLINE \
- TOML_ATTR(__always_inline__) \
- inline
+#define TOML_ALWAYS_INLINE \
+ TOML_ATTR(__always_inline__) \
+ inline
#else
#define TOML_ALWAYS_INLINE inline
#endif
@@ -408,7 +410,7 @@
// TOML_NEVER_INLINE
#ifdef _MSC_VER
#define TOML_NEVER_INLINE TOML_DECLSPEC(noinline)
-#elif TOML_CUDA // https://gitlab.gnome.org/GNOME/glib/-/issues/2555
+#elif TOML_CUDA // https://gitlab.gnome.org/GNOME/glib/-/issues/2555
#define TOML_NEVER_INLINE TOML_ATTR(noinline)
#else
#if TOML_GCC || TOML_CLANG || TOML_HAS_ATTR(__noinline__)
@@ -421,7 +423,7 @@
// MSVC attributes
#define TOML_ABSTRACT_INTERFACE TOML_DECLSPEC(novtable)
-#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases)
+#define TOML_EMPTY_BASES TOML_DECLSPEC(empty_bases)
// TOML_TRIVIAL_ABI
#if TOML_CLANG || TOML_HAS_ATTR(__trivial_abi__)
@@ -449,48 +451,48 @@
// pure + const
#ifndef TOML_PURE
#ifdef NDEBUG
-#define TOML_PURE \
- TOML_DECLSPEC(noalias) \
- TOML_ATTR(pure)
+#define TOML_PURE \
+ TOML_DECLSPEC(noalias) \
+ TOML_ATTR(pure)
#else
#define TOML_PURE
#endif
#endif
#ifndef TOML_CONST
#ifdef NDEBUG
-#define TOML_CONST \
- TOML_DECLSPEC(noalias) \
- TOML_ATTR(const)
+#define TOML_CONST \
+ TOML_DECLSPEC(noalias) \
+ TOML_ATTR(const)
#else
#define TOML_CONST
#endif
#endif
#ifndef TOML_INLINE_GETTER
-#define TOML_INLINE_GETTER \
- TOML_NODISCARD \
- TOML_ALWAYS_INLINE
+#define TOML_INLINE_GETTER \
+ TOML_NODISCARD \
+ TOML_ALWAYS_INLINE
#endif
#ifndef TOML_PURE_GETTER
-#define TOML_PURE_GETTER \
- TOML_NODISCARD \
- TOML_PURE
+#define TOML_PURE_GETTER \
+ TOML_NODISCARD \
+ TOML_PURE
#endif
#ifndef TOML_PURE_INLINE_GETTER
-#define TOML_PURE_INLINE_GETTER \
- TOML_NODISCARD \
- TOML_ALWAYS_INLINE \
- TOML_PURE
+#define TOML_PURE_INLINE_GETTER \
+ TOML_NODISCARD \
+ TOML_ALWAYS_INLINE \
+ TOML_PURE
#endif
#ifndef TOML_CONST_GETTER
-#define TOML_CONST_GETTER \
- TOML_NODISCARD \
- TOML_CONST
+#define TOML_CONST_GETTER \
+ TOML_NODISCARD \
+ TOML_CONST
#endif
#ifndef TOML_CONST_INLINE_GETTER
-#define TOML_CONST_INLINE_GETTER \
- TOML_NODISCARD \
- TOML_ALWAYS_INLINE \
- TOML_CONST
+#define TOML_CONST_INLINE_GETTER \
+ TOML_NODISCARD \
+ TOML_ALWAYS_INLINE \
+ TOML_CONST
#endif
// TOML_ASSUME
@@ -550,7 +552,7 @@
// TOML_OPEN_ENUM + TOML_CLOSED_ENUM
#if TOML_CLANG || TOML_HAS_ATTR(enum_extensibility)
-#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open)))
+#define TOML_OPEN_ENUM __attribute__((enum_extensibility(open)))
#define TOML_CLOSED_ENUM __attribute__((enum_extensibility(closed)))
#else
#define TOML_OPEN_ENUM
@@ -558,73 +560,63 @@
#endif
// TOML_OPEN_FLAGS_ENUM + TOML_CLOSED_FLAGS_ENUM
-#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM
+#define TOML_OPEN_FLAGS_ENUM TOML_OPEN_ENUM TOML_FLAGS_ENUM
#define TOML_CLOSED_FLAGS_ENUM TOML_CLOSED_ENUM TOML_FLAGS_ENUM
// TOML_MAKE_FLAGS
-#define TOML_MAKE_FLAGS_2(T, op, linkage) \
- TOML_CONST_INLINE_GETTER \
- linkage constexpr T operator op(T lhs, T rhs) noexcept \
- { \
- using under = std::underlying_type_t<T>; \
- return static_cast<T>(static_cast<under>(lhs) op static_cast<under>(rhs)); \
- } \
- \
- linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept \
- { \
- return lhs = (lhs op rhs); \
- } \
- \
- static_assert(true)
-#define TOML_MAKE_FLAGS_1(T, linkage) \
- static_assert(std::is_enum_v<T>); \
- \
- TOML_MAKE_FLAGS_2(T, &, linkage); \
- TOML_MAKE_FLAGS_2(T, |, linkage); \
- TOML_MAKE_FLAGS_2(T, ^, linkage); \
- \
- TOML_CONST_INLINE_GETTER \
- linkage constexpr T operator~(T val) noexcept \
- { \
- using under = std::underlying_type_t<T>; \
- return static_cast<T>(~static_cast<under>(val)); \
- } \
- \
- TOML_CONST_INLINE_GETTER \
- linkage constexpr bool operator!(T val) noexcept \
- { \
- using under = std::underlying_type_t<T>; \
- return !static_cast<under>(val); \
- } \
- \
- static_assert(true)
+#define TOML_MAKE_FLAGS_2(T, op, linkage) \
+ TOML_CONST_INLINE_GETTER \
+ linkage constexpr T operator op(T lhs, T rhs) noexcept { \
+ using under = std::underlying_type_t<T>; \
+ return static_cast<T>(static_cast<under>(lhs) op static_cast<under>(rhs)); \
+ } \
+ \
+ linkage constexpr T& operator TOML_CONCAT(op, =)(T & lhs, T rhs) noexcept { \
+ return lhs = (lhs op rhs); \
+ } \
+ \
+ static_assert(true)
+#define TOML_MAKE_FLAGS_1(T, linkage) \
+ static_assert(std::is_enum_v<T>); \
+ \
+ TOML_MAKE_FLAGS_2(T, &, linkage); \
+ TOML_MAKE_FLAGS_2(T, |, linkage); \
+ TOML_MAKE_FLAGS_2(T, ^, linkage); \
+ \
+ TOML_CONST_INLINE_GETTER \
+ linkage constexpr T operator~(T val) noexcept { \
+ using under = std::underlying_type_t<T>; \
+ return static_cast<T>(~static_cast<under>(val)); \
+ } \
+ \
+ TOML_CONST_INLINE_GETTER \
+ linkage constexpr bool operator!(T val) noexcept { \
+ using under = std::underlying_type_t<T>; \
+ return !static_cast<under>(val); \
+ } \
+ \
+ static_assert(true)
#define TOML_MAKE_FLAGS(T) TOML_MAKE_FLAGS_1(T, )
#define TOML_UNUSED(...) static_cast<void>(__VA_ARGS__)
-#define TOML_DELETE_DEFAULTS(T) \
- T(const T&) = delete; \
- T(T&&) = delete; \
- T& operator=(const T&) = delete; \
- T& operator=(T&&) = delete
-
-#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \
- __VA_ARGS__ TOML_NODISCARD \
- friend bool operator==(RHS rhs, LHS lhs) noexcept \
- { \
- return lhs == rhs; \
- } \
- __VA_ARGS__ TOML_NODISCARD \
- friend bool operator!=(LHS lhs, RHS rhs) noexcept \
- { \
- return !(lhs == rhs); \
- } \
- __VA_ARGS__ TOML_NODISCARD \
- friend bool operator!=(RHS rhs, LHS lhs) noexcept \
- { \
- return !(lhs == rhs); \
- } \
- static_assert(true)
+#define TOML_DELETE_DEFAULTS(T) \
+ T(const T&) = delete; \
+ T(T&&) = delete; \
+ T& operator=(const T&) = delete; \
+ T& operator=(T&&) = delete
+
+#define TOML_ASYMMETRICAL_EQUALITY_OPS(LHS, RHS, ...) \
+ __VA_ARGS__ TOML_NODISCARD friend bool operator==(RHS rhs, LHS lhs) noexcept { \
+ return lhs == rhs; \
+ } \
+ __VA_ARGS__ TOML_NODISCARD friend bool operator!=(LHS lhs, RHS rhs) noexcept { \
+ return !(lhs == rhs); \
+ } \
+ __VA_ARGS__ TOML_NODISCARD friend bool operator!=(RHS rhs, LHS lhs) noexcept { \
+ return !(lhs == rhs); \
+ } \
+ static_assert(true)
#define TOML_EVAL_BOOL_1(T, F) T
#define TOML_EVAL_BOOL_0(T, F) F
@@ -639,210 +631,194 @@
#if TOML_CLANG
-#define TOML_PUSH_WARNINGS \
- TOML_PRAGMA_CLANG(diagnostic push) \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wunknown-warning-option") \
- static_assert(true)
-
-#define TOML_DISABLE_SWITCH_WARNINGS \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \
- static_assert(true)
-
-#define TOML_DISABLE_ARITHMETIC_WARNINGS \
- TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wimplicit-int-float-conversion") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \
- static_assert(true)
-
-#define TOML_DISABLE_SPAM_WARNINGS \
- TOML_PRAGMA_CLANG_GE_8(diagnostic ignored "-Wdefaulted-function-deleted") \
- TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \
- TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \
- TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \
- static_assert(true)
-
-#define TOML_POP_WARNINGS \
- TOML_PRAGMA_CLANG(diagnostic pop) \
- static_assert(true)
-
-#define TOML_DISABLE_WARNINGS \
- TOML_PRAGMA_CLANG(diagnostic push) \
- TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \
- static_assert(true, "")
-
-#define TOML_ENABLE_WARNINGS \
- TOML_PRAGMA_CLANG(diagnostic pop) \
- static_assert(true)
+#define TOML_PUSH_WARNINGS \
+ TOML_PRAGMA_CLANG(diagnostic push) \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wunknown-warning-option") \
+ static_assert(true)
+
+#define TOML_DISABLE_SWITCH_WARNINGS \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wswitch") \
+ static_assert(true)
+
+#define TOML_DISABLE_ARITHMETIC_WARNINGS \
+ TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wimplicit-int-float-conversion") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wfloat-equal") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wshift-sign-overflow") \
+ static_assert(true)
+
+#define TOML_DISABLE_SPAM_WARNINGS \
+ TOML_PRAGMA_CLANG_GE_8(diagnostic ignored "-Wdefaulted-function-deleted") \
+ TOML_PRAGMA_CLANG_GE_9(diagnostic ignored "-Wctad-maybe-unsupported") \
+ TOML_PRAGMA_CLANG_GE_10(diagnostic ignored "-Wzero-as-null-pointer-constant") \
+ TOML_PRAGMA_CLANG_GE_11(diagnostic ignored "-Wsuggest-destructor-override") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-vtables") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wweak-template-vtables") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wdouble-promotion") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wchar-subscripts") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wmissing-field-initializers") \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Wpadded") \
+ static_assert(true)
+
+#define TOML_POP_WARNINGS \
+ TOML_PRAGMA_CLANG(diagnostic pop) \
+ static_assert(true)
+
+#define TOML_DISABLE_WARNINGS \
+ TOML_PRAGMA_CLANG(diagnostic push) \
+ TOML_PRAGMA_CLANG(diagnostic ignored "-Weverything") \
+ static_assert(true, "")
+
+#define TOML_ENABLE_WARNINGS \
+ TOML_PRAGMA_CLANG(diagnostic pop) \
+ static_assert(true)
#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 1
#elif TOML_MSVC
-#define TOML_PUSH_WARNINGS \
- __pragma(warning(push)) \
- static_assert(true)
+#define TOML_PUSH_WARNINGS __pragma(warning(push)) static_assert(true)
-#if TOML_HAS_INCLUDE(<CodeAnalysis/Warnings.h>)
+#if TOML_HAS_INCLUDE(<CodeAnalysis / Warnings.h>)
#pragma warning(push, 0)
#include <CodeAnalysis/Warnings.h>
#pragma warning(pop)
-#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \
- __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) \
- static_assert(true)
+#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS \
+ __pragma(warning(disable : ALL_CODE_ANALYSIS_WARNINGS)) static_assert(true)
#else
#define TOML_DISABLE_CODE_ANALYSIS_WARNINGS static_assert(true)
#endif
-#define TOML_DISABLE_SWITCH_WARNINGS \
- __pragma(warning(disable : 4061)) \
- __pragma(warning(disable : 4062)) \
- __pragma(warning(disable : 4063)) \
- __pragma(warning(disable : 5262)) /* switch-case implicit fallthrough (false-positive) */ \
- __pragma(warning(disable : 26819)) /* cg: unannotated fallthrough */ \
- static_assert(true)
-
-#define TOML_DISABLE_SPAM_WARNINGS \
- __pragma(warning(disable : 4127)) /* conditional expr is constant */ \
- __pragma(warning(disable : 4324)) /* structure was padded due to alignment specifier */ \
- __pragma(warning(disable : 4348)) \
- __pragma(warning(disable : 4464)) /* relative include path contains '..' */ \
- __pragma(warning(disable : 4505)) /* unreferenced local function removed */ \
- __pragma(warning(disable : 4514)) /* unreferenced inline function has been removed */ \
- __pragma(warning(disable : 4582)) /* constructor is not implicitly called */ \
- __pragma(warning(disable : 4619)) /* there is no warning number 'XXXX' */ \
- __pragma(warning(disable : 4623)) /* default constructor was implicitly defined as deleted */ \
- __pragma(warning(disable : 4625)) /* copy constructor was implicitly defined as deleted */ \
- __pragma(warning(disable : 4626)) /* assignment operator was implicitly defined as deleted */ \
- __pragma(warning(disable : 4710)) /* function not inlined */ \
- __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \
- __pragma(warning(disable : 4820)) /* N bytes padding added */ \
- __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \
- __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \
- __pragma(warning(disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \
- __pragma(warning(disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \
- __pragma(warning(disable : 5045)) /* Compiler will insert Spectre mitigation */ \
- __pragma(warning(disable : 5264)) /* const variable is not used (false-positive) */ \
- __pragma(warning(disable : 26451)) \
- __pragma(warning(disable : 26490)) \
- __pragma(warning(disable : 26495)) \
- __pragma(warning(disable : 26812)) \
- __pragma(warning(disable : 26819)) \
- static_assert(true)
-
-#define TOML_DISABLE_ARITHMETIC_WARNINGS \
- __pragma(warning(disable : 4365)) /* argument signed/unsigned mismatch */ \
- __pragma(warning(disable : 4738)) /* storing 32-bit float result in memory */ \
- __pragma(warning(disable : 5219)) /* implicit conversion from integral to float */ \
- static_assert(true)
-
-#define TOML_POP_WARNINGS \
- __pragma(warning(pop)) \
- static_assert(true)
-
-#define TOML_DISABLE_WARNINGS \
- __pragma(warning(push, 0)) \
- __pragma(warning(disable : 4348)) \
- __pragma(warning(disable : 4668)) \
- __pragma(warning(disable : 5105)) \
- __pragma(warning(disable : 5264)) \
- TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \
- TOML_DISABLE_SWITCH_WARNINGS; \
- TOML_DISABLE_SPAM_WARNINGS; \
- TOML_DISABLE_ARITHMETIC_WARNINGS; \
- static_assert(true)
+#define TOML_DISABLE_SWITCH_WARNINGS \
+ __pragma(warning(disable : 4061)) __pragma(warning(disable : 4062)) \
+ __pragma(warning(disable : 4063)) __pragma( \
+ warning(disable : 5262)) /* switch-case implicit fallthrough (false-positive) */ \
+ __pragma(warning(disable : 26819)) /* cg: unannotated fallthrough */ \
+ static_assert(true)
+
+#define TOML_DISABLE_SPAM_WARNINGS \
+ __pragma(warning(disable : 4127)) /* conditional expr is constant */ \
+ __pragma(warning(disable : 4324)) /* structure was padded due to alignment specifier */ \
+ __pragma(warning(disable : 4348)) \
+ __pragma(warning(disable : 4464)) /* relative include path contains '..' */ \
+ __pragma(warning(disable : 4505)) /* unreferenced local function removed */ \
+ __pragma(warning(disable : 4514)) /* unreferenced inline function has been removed */ \
+ __pragma(warning(disable : 4582)) /* constructor is not implicitly called */ \
+ __pragma(warning(disable : 4619)) /* there is no warning number 'XXXX' */ \
+ __pragma( \
+ warning(disable : 4623)) /* default constructor was implicitly defined as deleted */ \
+ __pragma(warning(disable : 4625)) /* copy constructor was implicitly defined as deleted */ \
+ __pragma( \
+ warning(disable : 4626)) /* assignment operator was implicitly defined as deleted */ \
+ __pragma(warning(disable : 4710)) /* function not inlined */ \
+ __pragma(warning(disable : 4711)) /* function selected for automatic expansion */ \
+ __pragma(warning(disable : 4820)) /* N bytes padding added */ \
+ __pragma(warning(disable : 4946)) /* reinterpret_cast used between related classes */ \
+ __pragma(warning(disable : 5026)) /* move constructor was implicitly defined as deleted */ \
+ __pragma(warning( \
+ disable : 5027)) /* move assignment operator was implicitly defined as deleted */ \
+ __pragma(warning( \
+ disable : 5039)) /* potentially throwing function passed to 'extern "C"' function */ \
+ __pragma(warning(disable : 5045)) /* Compiler will insert Spectre mitigation */ \
+ __pragma(warning(disable : 5264)) /* const variable is not used (false-positive) */ \
+ __pragma(warning(disable : 26451)) __pragma(warning(disable : 26490)) \
+ __pragma(warning(disable : 26495)) __pragma(warning(disable : 26812)) \
+ __pragma(warning(disable : 26819)) static_assert(true)
+
+#define TOML_DISABLE_ARITHMETIC_WARNINGS \
+ __pragma(warning(disable : 4365)) /* argument signed/unsigned mismatch */ \
+ __pragma(warning(disable : 4738)) /* storing 32-bit float result in memory */ \
+ __pragma(warning(disable : 5219)) /* implicit conversion from integral to float */ \
+ static_assert(true)
+
+#define TOML_POP_WARNINGS __pragma(warning(pop)) static_assert(true)
+
+#define TOML_DISABLE_WARNINGS \
+ __pragma(warning(push, 0)) __pragma(warning(disable : 4348)) __pragma(warning(disable : 4668)) \
+ __pragma(warning(disable : 5105)) __pragma(warning(disable : 5264)) \
+ TOML_DISABLE_CODE_ANALYSIS_WARNINGS; \
+ TOML_DISABLE_SWITCH_WARNINGS; \
+ TOML_DISABLE_SPAM_WARNINGS; \
+ TOML_DISABLE_ARITHMETIC_WARNINGS; \
+ static_assert(true)
#define TOML_ENABLE_WARNINGS TOML_POP_WARNINGS
#elif TOML_ICC
-#define TOML_PUSH_WARNINGS \
- __pragma(warning(push)) \
- static_assert(true)
+#define TOML_PUSH_WARNINGS __pragma(warning(push)) static_assert(true)
-#define TOML_DISABLE_SPAM_WARNINGS \
- __pragma(warning(disable : 82)) /* storage class is not first */ \
- __pragma(warning(disable : 111)) /* statement unreachable (false-positive) */ \
- __pragma(warning(disable : 869)) /* unreferenced parameter */ \
- __pragma(warning(disable : 1011)) /* missing return (false-positive) */ \
- __pragma(warning(disable : 2261)) /* assume expr side-effects discarded */ \
- static_assert(true)
+#define TOML_DISABLE_SPAM_WARNINGS \
+ __pragma(warning(disable : 82)) /* storage class is not first */ \
+ __pragma(warning(disable : 111)) /* statement unreachable (false-positive) */ \
+ __pragma(warning(disable : 869)) /* unreferenced parameter */ \
+ __pragma(warning(disable : 1011)) /* missing return (false-positive) */ \
+ __pragma(warning(disable : 2261)) /* assume expr side-effects discarded */ \
+ static_assert(true)
-#define TOML_POP_WARNINGS \
- __pragma(warning(pop)) \
- static_assert(true)
+#define TOML_POP_WARNINGS __pragma(warning(pop)) static_assert(true)
-#define TOML_DISABLE_WARNINGS \
- __pragma(warning(push, 0)) \
- TOML_DISABLE_SPAM_WARNINGS
+#define TOML_DISABLE_WARNINGS __pragma(warning(push, 0)) TOML_DISABLE_SPAM_WARNINGS
-#define TOML_ENABLE_WARNINGS \
- __pragma(warning(pop)) \
- static_assert(true)
+#define TOML_ENABLE_WARNINGS __pragma(warning(pop)) static_assert(true)
#elif TOML_GCC
-#define TOML_PUSH_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic push) \
- static_assert(true)
-
-#define TOML_DISABLE_SWITCH_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \
- static_assert(true)
-
-#define TOML_DISABLE_ARITHMETIC_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
- static_assert(true)
-
-#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \
- static_assert(true)
-
-#define TOML_DISABLE_SPAM_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wnull-dereference") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wduplicated-branches") \
- static_assert(true)
-
-#define TOML_POP_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic pop) \
- static_assert(true)
-
-#define TOML_DISABLE_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic push) \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \
- TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \
- TOML_DISABLE_SWITCH_WARNINGS; \
- TOML_DISABLE_ARITHMETIC_WARNINGS; \
- TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \
- TOML_DISABLE_SPAM_WARNINGS; \
- static_assert(true)
-
-#define TOML_ENABLE_WARNINGS \
- TOML_PRAGMA_GCC(diagnostic pop) \
- static_assert(true)
+#define TOML_PUSH_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic push) \
+ static_assert(true)
+
+#define TOML_DISABLE_SWITCH_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-enum") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wswitch-default") \
+ static_assert(true)
+
+#define TOML_DISABLE_ARITHMETIC_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wfloat-equal") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wsign-conversion") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
+ static_assert(true)
+
+#define TOML_DISABLE_SUGGEST_ATTR_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=const") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wsuggest-attribute=pure") \
+ static_assert(true)
+
+#define TOML_DISABLE_SPAM_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wpadded") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wcast-align") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wcomment") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wtype-limits") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wuseless-cast") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wchar-subscripts") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wsubobject-linkage") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wmissing-field-initializers") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wnoexcept") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wnull-dereference") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wduplicated-branches") \
+ static_assert(true)
+
+#define TOML_POP_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic pop) \
+ static_assert(true)
+
+#define TOML_DISABLE_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic push) \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wall") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wextra") \
+ TOML_PRAGMA_GCC(diagnostic ignored "-Wpedantic") \
+ TOML_DISABLE_SWITCH_WARNINGS; \
+ TOML_DISABLE_ARITHMETIC_WARNINGS; \
+ TOML_DISABLE_SUGGEST_ATTR_WARNINGS; \
+ TOML_DISABLE_SPAM_WARNINGS; \
+ static_assert(true)
+
+#define TOML_ENABLE_WARNINGS \
+ TOML_PRAGMA_GCC(diagnostic pop) \
+ static_assert(true)
#endif
@@ -877,9 +853,9 @@
#define TOML_SIMPLE_STATIC_ASSERT_MESSAGES 0
#endif
-//#====================================================================================================================
-//# USER CONFIGURATION
-//#====================================================================================================================
+// #====================================================================================================================
+// # USER CONFIGURATION
+// #====================================================================================================================
/// \addtogroup configuration Library Configuration
/// \brief Preprocessor macros for configuring library functionality.
/// \detail Define these before including toml++ to alter the way it functions.
@@ -890,14 +866,14 @@
#ifdef TOML_CONFIG_HEADER
#include TOML_CONFIG_HEADER
#endif
-//# {{
+// # {{
#if TOML_DOXYGEN
#define TOML_CONFIG_HEADER
#endif
/// \def TOML_CONFIG_HEADER
/// \brief An additional header to include before any other toml++ header files.
/// \detail Not defined by default.
-//# }}
+// # }}
// is the library being built as a shared lib/dll using meson and friends?
#ifndef TOML_SHARED_LIB
@@ -905,10 +881,11 @@
#endif
// header-only mode
-#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0
+#if !defined(TOML_HEADER_ONLY) && defined(TOML_ALL_INLINE) // was TOML_ALL_INLINE pre-2.0
#define TOML_HEADER_ONLY TOML_ALL_INLINE
#endif
-#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || TOML_INTELLISENSE
+#if !defined(TOML_HEADER_ONLY) || (defined(TOML_HEADER_ONLY) && TOML_HEADER_ONLY) || \
+ TOML_INTELLISENSE
#undef TOML_HEADER_ONLY
#define TOML_HEADER_ONLY 1
#endif
@@ -943,11 +920,11 @@
/// \detail Not defined by default. Meaningless when #TOML_HEADER_ONLY is enabled.
// dll/shared lib function exports (legacy - TOML_API was the old name for this setting)
-#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) \
- && !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API)
+#if !defined(TOML_EXPORTED_MEMBER_FUNCTION) && !defined(TOML_EXPORTED_STATIC_FUNCTION) && \
+ !defined(TOML_EXPORTED_FREE_FUNCTION) && !defined(TOML_EXPORTED_CLASS) && defined(TOML_API)
#define TOML_EXPORTED_MEMBER_FUNCTION TOML_API
#define TOML_EXPORTED_STATIC_FUNCTION TOML_API
-#define TOML_EXPORTED_FREE_FUNCTION TOML_API
+#define TOML_EXPORTED_FREE_FUNCTION TOML_API
#endif
// dll/shared lib exports
@@ -959,20 +936,20 @@
#undef TOML_EXPORTED_FREE_FUNCTION
#if TOML_WINDOWS
#if TOML_IMPLEMENTATION
-#define TOML_EXPORTED_CLASS __declspec(dllexport)
+#define TOML_EXPORTED_CLASS __declspec(dllexport)
#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllexport)
#else
-#define TOML_EXPORTED_CLASS __declspec(dllimport)
+#define TOML_EXPORTED_CLASS __declspec(dllimport)
#define TOML_EXPORTED_FREE_FUNCTION __declspec(dllimport)
#endif
#ifndef TOML_CALLCONV
#define TOML_CALLCONV __cdecl
#endif
#elif defined(__GNUC__) && __GNUC__ >= 4
-#define TOML_EXPORTED_CLASS __attribute__((visibility("default")))
+#define TOML_EXPORTED_CLASS __attribute__((visibility("default")))
#define TOML_EXPORTED_MEMBER_FUNCTION __attribute__((visibility("default")))
#define TOML_EXPORTED_STATIC_FUNCTION __attribute__((visibility("default")))
-#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default")))
+#define TOML_EXPORTED_FREE_FUNCTION __attribute__((visibility("default")))
#endif
#endif
#ifndef TOML_EXPORTED_CLASS
@@ -1012,11 +989,13 @@
/// into the public API of a DLL on Windows.
// experimental language features
-#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES
- // pre-3.0
+#if !defined(TOML_ENABLE_UNRELEASED_FEATURES) && \
+ defined(TOML_UNRELEASED_FEATURES) // was TOML_UNRELEASED_FEATURES
+ // pre-3.0
#define TOML_ENABLE_UNRELEASED_FEATURES TOML_UNRELEASED_FEATURES
#endif
-#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || TOML_INTELLISENSE
+#if (defined(TOML_ENABLE_UNRELEASED_FEATURES) && TOML_ENABLE_UNRELEASED_FEATURES) || \
+ TOML_INTELLISENSE
#undef TOML_ENABLE_UNRELEASED_FEATURES
#define TOML_ENABLE_UNRELEASED_FEATURES 1
#endif
@@ -1027,13 +1006,15 @@
/// \brief Enables support for unreleased TOML language features not yet part of a
/// [numbered version](https://github.com/toml-lang/toml/releases).
/// \detail Defaults to `0`.
-/// \see [TOML Language Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support)
+/// \see [TOML Language
+/// Support](https://github.com/marzer/tomlplusplus/blob/master/README.md#toml-language-support)
// parser
-#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0
+#if !defined(TOML_ENABLE_PARSER) && defined(TOML_PARSER) // was TOML_PARSER pre-3.0
#define TOML_ENABLE_PARSER TOML_PARSER
#endif
-#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || TOML_INTELLISENSE
+#if !defined(TOML_ENABLE_PARSER) || (defined(TOML_ENABLE_PARSER) && TOML_ENABLE_PARSER) || \
+ TOML_INTELLISENSE
#undef TOML_ENABLE_PARSER
#define TOML_ENABLE_PARSER 1
#endif
@@ -1044,7 +1025,8 @@
/// to `0` can improve compilation speed and reduce binary size.
// formatters
-#if !defined(TOML_ENABLE_FORMATTERS) || (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE
+#if !defined(TOML_ENABLE_FORMATTERS) || \
+ (defined(TOML_ENABLE_FORMATTERS) && TOML_ENABLE_FORMATTERS) || TOML_INTELLISENSE
#undef TOML_ENABLE_FORMATTERS
#define TOML_ENABLE_FORMATTERS 1
#endif
@@ -1059,17 +1041,19 @@
/// - toml::yaml_formatter
// SIMD
-#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || TOML_INTELLISENSE
+#if !defined(TOML_ENABLE_SIMD) || (defined(TOML_ENABLE_SIMD) && TOML_ENABLE_SIMD) || \
+ TOML_INTELLISENSE
#undef TOML_ENABLE_SIMD
#define TOML_ENABLE_SIMD 1
#endif
// windows compat
-#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0
+#if !defined(TOML_ENABLE_WINDOWS_COMPAT) && \
+ defined(TOML_WINDOWS_COMPAT) // was TOML_WINDOWS_COMPAT pre-3.0
#define TOML_ENABLE_WINDOWS_COMPAT TOML_WINDOWS_COMPAT
#endif
-#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) \
- || TOML_INTELLISENSE
+#if !defined(TOML_ENABLE_WINDOWS_COMPAT) || \
+ (defined(TOML_ENABLE_WINDOWS_COMPAT) && TOML_ENABLE_WINDOWS_COMPAT) || TOML_INTELLISENSE
#undef TOML_ENABLE_WINDOWS_COMPAT
#define TOML_ENABLE_WINDOWS_COMPAT 1
#endif
@@ -1083,16 +1067,15 @@
#define TOML_INCLUDE_WINDOWS_H 0
#endif
/// \def TOML_ENABLE_WINDOWS_COMPAT
-/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library
-/// when building for Windows.
-/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building for anything other
-/// than Windows.
-/// \remark This <strong>does not</strong> change the underlying string type used to represent TOML keys and string
-/// values; that will still be std::string. This setting simply enables some narrow &lt;=&gt; wide string
-/// conversions when necessary at various interface boundaries.
-/// <br><br>
-/// If you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide strings,
-/// you can safely set this to `0`.
+/// \brief Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the
+/// library when building for Windows.
+/// \detail Defaults to `1` when building for Windows, `0` otherwise. Has no effect when building
+/// for anything other than Windows.
+/// \remark This <strong>does not</strong> change the underlying string type used to represent TOML
+/// keys and string values; that will still be std::string. This setting simply enables some narrow
+/// &lt;=&gt; wide string conversions when necessary at various interface boundaries. <br><br> If
+/// you're building for Windows and you have no need for Windows' "Pretends-to-be-unicode" wide
+/// strings, you can safely set this to `0`.
// custom optional
#ifdef TOML_OPTIONAL_TYPE
@@ -1100,17 +1083,17 @@
#else
#define TOML_HAS_CUSTOM_OPTIONAL_TYPE 0
#endif
-//# {{
+// # {{
#if TOML_DOXYGEN
#define TOML_OPTIONAL_TYPE
#endif
/// \def TOML_OPTIONAL_TYPE
/// \brief Overrides the `optional<T>` type used by the library.
/// \detail Not defined by default (use std::optional).
-/// \warning The library uses optionals internally in a few places; if you choose to replace the optional type
-/// it must be with something that is still API-compatible with std::optional
-/// (e.g. [tl::optional](https://github.com/TartanLlama/optional)).
-//# }}
+/// \warning The library uses optionals internally in a few places; if you choose to replace the
+/// optional type it must be with something that is still API-compatible with std::optional (e.g.
+/// [tl::optional](https://github.com/TartanLlama/optional)).
+// # }}
// exceptions (library use)
#if TOML_COMPILER_HAS_EXCEPTIONS
@@ -1137,14 +1120,15 @@
/// \brief Calling convention to apply to exported free/static functions.
/// \detail Not defined by default (let the compiler decide).
-//# {{
+// # {{
#if TOML_DOXYGEN
#define TOML_SMALL_FLOAT_TYPE
#endif
/// \def TOML_SMALL_FLOAT_TYPE
-/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it.
+/// \brief If your codebase has an additional 'small' float type (e.g. half-precision), this tells
+/// toml++ about it.
/// \detail Not defined by default.
-//# }}
+// # }}
#ifndef TOML_UNDEF_MACROS
#define TOML_UNDEF_MACROS 1
@@ -1153,7 +1137,8 @@
#ifndef TOML_MAX_NESTED_VALUES
#define TOML_MAX_NESTED_VALUES 256
// this refers to the depth of nested values, e.g. inline tables and arrays.
-// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool for the job...
+// 256 is crazy high! if you're hitting this limit with real input, TOML is probably the wrong tool
+// for the job...
#endif
#ifdef TOML_CHAR_8_STRINGS
@@ -1193,28 +1178,29 @@ TOML_ENABLE_WARNINGS;
/// \brief Sets the assert function used by the library.
/// \detail Defaults to the standard C `assert()`.
-//# {{
+// # {{
#if TOML_DOXYGEN
#define TOML_SMALL_INT_TYPE
#endif
/// \def TOML_SMALL_INT_TYPE
-/// \brief If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++ about it.
+/// \brief If your codebase has an additional 'small' integer type (e.g. 24-bits), this tells toml++
+/// about it.
/// \detail Not defined by default.
-//# }}
+// # }}
#ifndef TOML_ENABLE_FLOAT16
#define TOML_ENABLE_FLOAT16 0
#endif
-//# {{
+// # {{
/// \def TOML_ENABLE_FLOAT16
/// \brief Enable support for the built-in `_Float16` type.
/// \detail Defaults to `0`.
-//# }}
+// # }}
/// @}
-//#====================================================================================================================
-//# CHARCONV SUPPORT
-//#====================================================================================================================
+// #====================================================================================================================
+// # CHARCONV SUPPORT
+// #====================================================================================================================
#if !defined(TOML_FLOAT_CHARCONV) && (TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL))
// not supported by any version of GCC or Clang as of 26/11/2020
@@ -1235,13 +1221,13 @@ TOML_ENABLE_WARNINGS;
#if (TOML_INT_CHARCONV || TOML_FLOAT_CHARCONV) && !TOML_HAS_INCLUDE(<charconv>)
#undef TOML_INT_CHARCONV
#undef TOML_FLOAT_CHARCONV
-#define TOML_INT_CHARCONV 0
+#define TOML_INT_CHARCONV 0
#define TOML_FLOAT_CHARCONV 0
#endif
-//#=====================================================================================================================
-//# SFINAE
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # SFINAE
+// #=====================================================================================================================
/// \cond
#if defined(__cpp_concepts) && __cpp_concepts >= 201907
@@ -1250,41 +1236,41 @@ TOML_ENABLE_WARNINGS;
#define TOML_REQUIRES(...)
#endif
#define TOML_ENABLE_IF(...) , typename std::enable_if<(__VA_ARGS__), int>::type = 0
-#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \
- template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \
- TOML_REQUIRES(condition)
+#define TOML_CONSTRAINED_TEMPLATE(condition, ...) \
+ template <__VA_ARGS__ TOML_ENABLE_IF(condition)> \
+ TOML_REQUIRES(condition)
#define TOML_HIDDEN_CONSTRAINT(condition, ...) TOML_CONSTRAINED_TEMPLATE(condition, __VA_ARGS__)
/// \endcond
-//# {{
+// # {{
#ifndef TOML_CONSTRAINED_TEMPLATE
#define TOML_CONSTRAINED_TEMPLATE(condition, ...) template <__VA_ARGS__>
#endif
#ifndef TOML_HIDDEN_CONSTRAINT
#define TOML_HIDDEN_CONSTRAINT(condition, ...)
#endif
-//# }}
+// # }}
-//#=====================================================================================================================
-//# FLOAT128
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # FLOAT128
+// #=====================================================================================================================
-#if defined(__SIZEOF_FLOAT128__) && defined(__FLT128_MANT_DIG__) && defined(__LDBL_MANT_DIG__) \
- && __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__
+#if defined(__SIZEOF_FLOAT128__) && defined(__FLT128_MANT_DIG__) && defined(__LDBL_MANT_DIG__) && \
+ __FLT128_MANT_DIG__ > __LDBL_MANT_DIG__
#define TOML_FLOAT128 __float128
#endif
-//#=====================================================================================================================
-//# INT128
-//#=====================================================================================================================
+// #=====================================================================================================================
+// # INT128
+// #=====================================================================================================================
#ifdef __SIZEOF_INT128__
-#define TOML_INT128 __int128_t
+#define TOML_INT128 __int128_t
#define TOML_UINT128 __uint128_t
#endif
-//#====================================================================================================================
-//# VERSIONS AND NAMESPACES
-//#====================================================================================================================
+// #====================================================================================================================
+// # VERSIONS AND NAMESPACES
+// #====================================================================================================================
// clang-format off
#include "version.hpp"
@@ -1349,13 +1335,13 @@ TOML_ENABLE_WARNINGS;
#endif
// clang-format on
-//#====================================================================================================================
-//# ASSERT
-//#====================================================================================================================
+// #====================================================================================================================
+// # ASSERT
+// #====================================================================================================================
-//#====================================================================================================================
-//# STATIC ASSERT MESSAGE FORMATTING
-//#====================================================================================================================
+// #====================================================================================================================
+// # STATIC ASSERT MESSAGE FORMATTING
+// #====================================================================================================================
// clang-format off
/// \cond
diff --git a/vendor/toml++/impl/print_to_stream.hpp b/vendor/toml++/impl/print_to_stream.hpp
index b6a4895..60eac4e 100644
--- a/vendor/toml++/impl/print_to_stream.hpp
+++ b/vendor/toml++/impl/print_to_stream.hpp
@@ -1,128 +1,138 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_string.hpp"
#include "forward_declarations.hpp"
#include "header_start.hpp"
+#include "std_string.hpp"
-TOML_IMPL_NAMESPACE_START
-{
- // Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?"
- // A: - I'm using <charconv> to format numerics. Faster and locale-independent.
- // - I can (potentially) avoid forcing users to drag in <sstream> and <iomanip>.
- // - Strings in C++. Honestly.
+TOML_IMPL_NAMESPACE_START {
+ // Q: "why does print_to_stream() exist? why not just use ostream::write(), ostream::put() etc?"
+ // A: - I'm using <charconv> to format numerics. Faster and locale-independent.
+ // - I can (potentially) avoid forcing users to drag in <sstream> and <iomanip>.
+ // - Strings in C++. Honestly.
- TOML_EXPORTED_FREE_FUNCTION
- TOML_ATTR(nonnull)
- void TOML_CALLCONV print_to_stream(std::ostream&, const char*, size_t);
+ TOML_EXPORTED_FREE_FUNCTION
+ TOML_ATTR(nonnull)
+ void TOML_CALLCONV print_to_stream(std::ostream&, const char*, size_t);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, std::string_view);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, std::string_view);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const std::string&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const std::string&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, char);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, char);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, signed char, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, signed char, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, signed short, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, signed short, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, signed int, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, signed int, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, signed long, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, signed long, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, signed long long, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, signed long long, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, unsigned char, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, unsigned char, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, unsigned short, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, unsigned short, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, unsigned int, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, unsigned int, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long long, value_flags = {}, size_t min_digits = 0);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, unsigned long long, value_flags = {},
+ size_t min_digits = 0);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, float, value_flags = {}, bool relaxed_precision = false);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, float, value_flags = {},
+ bool relaxed_precision = false);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, double, value_flags = {}, bool relaxed_precision = false);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, double, value_flags = {},
+ bool relaxed_precision = false);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, bool);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, bool);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time_offset&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const toml::time_offset&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date_time&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const toml::date_time&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const source_position&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const source_position&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const source_region&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const source_region&);
#if TOML_ENABLE_FORMATTERS
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const array&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const array&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const table&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const table&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<std::string>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<std::string>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<int64_t>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<int64_t>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<double>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<double>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<bool>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<bool>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<date>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<date>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<time>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<time>&);
- TOML_EXPORTED_FREE_FUNCTION
- void TOML_CALLCONV print_to_stream(std::ostream&, const value<date_time>&);
+ TOML_EXPORTED_FREE_FUNCTION
+ void TOML_CALLCONV print_to_stream(std::ostream&, const value<date_time>&);
#endif
- template <typename T, typename U>
- inline void print_to_stream_bookended(std::ostream & stream, const T& val, const U& bookend)
- {
- print_to_stream(stream, bookend);
- print_to_stream(stream, val);
- print_to_stream(stream, bookend);
- }
+ template <typename T, typename U>
+ inline void print_to_stream_bookended(std::ostream & stream, const T& val, const U& bookend) {
+ print_to_stream(stream, bookend);
+ print_to_stream(stream, val);
+ print_to_stream(stream, bookend);
+ }
}
TOML_IMPL_NAMESPACE_END;
diff --git a/vendor/toml++/impl/simd.hpp b/vendor/toml++/impl/simd.hpp
index ef66d66..0f9616c 100644
--- a/vendor/toml++/impl/simd.hpp
+++ b/vendor/toml++/impl/simd.hpp
@@ -1,14 +1,14 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_ENABLE_SIMD
-#if defined(__SSE2__) \
- || (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)))
+#if defined(__SSE2__) || (defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_X64) || \
+ (defined(_M_IX86_FP) && _M_IX86_FP >= 2)))
#define TOML_HAS_SSE2 1
#endif
@@ -16,7 +16,7 @@
#define TOML_HAS_SSE4_1 1
#endif
-#endif // TOML_ENABLE_SIMD
+#endif // TOML_ENABLE_SIMD
#ifndef TOML_HAS_SSE2
#define TOML_HAS_SSE2 0
diff --git a/vendor/toml++/impl/source_region.hpp b/vendor/toml++/impl/source_region.hpp
index 82a6d4b..e46b013 100644
--- a/vendor/toml++/impl/source_region.hpp
+++ b/vendor/toml++/impl/source_region.hpp
@@ -1,222 +1,213 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "std_optional.hpp"
-#include "std_string.hpp"
#include "forward_declarations.hpp"
-#include "print_to_stream.hpp"
#include "header_start.hpp"
+#include "print_to_stream.hpp"
+#include "std_optional.hpp"
+#include "std_string.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief The integer type used to tally line numbers and columns.
- using source_index = uint32_t;
-
- /// \brief A pointer to a shared string resource containing a source path.
- using source_path_ptr = std::shared_ptr<const std::string>;
-
- /// \brief A source document line-and-column pair.
- ///
- /// \detail \cpp
- /// auto table = toml::parse_file("config.toml"sv);
- /// std::cout << "The node 'description' was defined at "sv
- /// << table.get("description")->source().begin()
- /// << "\n";
- /// \ecpp
- ///
- /// \out
- /// The value 'description' was defined at line 7, column 15
- /// \eout
- ///
- /// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
- /// non-ASCII whitespace and newline characters, but it doesn't give much thought
- /// to combining marks, grapheme clusters vs. characters, et cetera.
- /// If a TOML document contains lots of codepoints outside of the ASCII range
- /// you may find that your source_positions don't match those given by a text editor
- /// (typically the line numbers will be accurate but column numbers will be too high).
- /// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
- /// between parser complexity and correctness.
- struct TOML_TRIVIAL_ABI source_position
- {
- /// \brief The line number.
- /// \remarks Valid line numbers start at 1.
- source_index line;
-
- /// \brief The column number.
- /// \remarks Valid column numbers start at 1.
- source_index column;
-
- /// \brief Returns true if both line and column numbers are non-zero.
- TOML_PURE_GETTER
- explicit constexpr operator bool() const noexcept
- {
- return line > source_index{} //
- && column > source_index{};
- }
-
- /// \brief Equality operator.
- TOML_PURE_GETTER
- friend constexpr bool operator==(const source_position& lhs, const source_position& rhs) noexcept
- {
- return lhs.line == rhs.line //
- && lhs.column == rhs.column;
- }
-
- /// \brief Inequality operator.
- TOML_PURE_INLINE_GETTER
- friend constexpr bool operator!=(const source_position& lhs, const source_position& rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- private:
- /// \cond
-
- TOML_PURE_GETTER
- static constexpr uint64_t pack(const source_position& pos) noexcept
- {
- return static_cast<uint64_t>(pos.line) << 32 | static_cast<uint64_t>(pos.column);
- }
-
- /// \endcond
-
- public:
- /// \brief Less-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<(const source_position& lhs, const source_position& rhs) noexcept
- {
- return pack(lhs) < pack(rhs);
- }
-
- /// \brief Less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator<=(const source_position& lhs, const source_position& rhs) noexcept
- {
- return pack(lhs) <= pack(rhs);
- }
-
- /// \brief Greater-than operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>(const source_position& lhs, const source_position& rhs) noexcept
- {
- return pack(lhs) > pack(rhs);
- }
-
- /// \brief Greater-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend constexpr bool operator>=(const source_position& lhs, const source_position& rhs) noexcept
- {
- return pack(lhs) >= pack(rhs);
- }
-
- /// \brief Prints a source_position to a stream.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse("bar = 42"sv);
- ///
- /// std::cout << "The value for 'bar' was found on "sv
- /// << tbl.get("bar")->source().begin()
- /// << "\n";
- /// \ecpp
- ///
- /// \out
- /// The value for 'bar' was found on line 1, column 7
- /// \eout
- ///
- /// \param lhs The stream.
- /// \param rhs The source_position.
- ///
- /// \returns The input stream.
- friend std::ostream& operator<<(std::ostream& lhs, const source_position& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
-
- /// \brief A source document region.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse_file("config.toml"sv);
- /// if (auto server = tbl.get("server"))
- /// {
- /// std::cout << "begin: "sv << server->source().begin << "\n";
- /// std::cout << "end: "sv << server->source().end << "\n";
- /// std::cout << "path: "sv << *server->source().path << "\n";
- /// }
- /// \ecpp
- ///
- /// \out
- /// begin: line 3, column 1
- /// end: line 3, column 22
- /// path: config.toml
- /// \eout
- ///
- /// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
- /// non-ASCII whitespace and newline characters, but it doesn't give much thought
- /// to combining marks, grapheme clusters vs. characters, et cetera.
- /// If a TOML document contains lots of codepoints outside of the ASCII range
- /// you may find that your source_positions don't match those given by a text editor
- /// (typically the line numbers will be accurate but column numbers will be too high).
- /// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate trade-off
- /// between parser complexity and correctness.
- struct source_region
- {
- /// \brief The beginning of the region (inclusive).
- source_position begin;
-
- /// \brief The end of the region (exclusive).
- source_position end;
-
- /// \brief The path to the corresponding source document.
- ///
- /// \remarks This will be `nullptr` if no path was provided to toml::parse().
- source_path_ptr path;
+TOML_NAMESPACE_START {
+ /// \brief The integer type used to tally line numbers and columns.
+ using source_index = uint32_t;
+
+ /// \brief A pointer to a shared string resource containing a source path.
+ using source_path_ptr = std::shared_ptr<const std::string>;
+
+ /// \brief A source document line-and-column pair.
+ ///
+ /// \detail \cpp
+ /// auto table = toml::parse_file("config.toml"sv);
+ /// std::cout << "The node 'description' was defined at "sv
+ /// << table.get("description")->source().begin()
+ /// << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// The value 'description' was defined at line 7, column 15
+ /// \eout
+ ///
+ /// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
+ /// non-ASCII whitespace and newline characters, but it doesn't give much thought
+ /// to combining marks, grapheme clusters vs. characters, et cetera.
+ /// If a TOML document contains lots of codepoints outside of the ASCII range
+ /// you may find that your source_positions don't match those given by a text editor
+ /// (typically the line numbers will be accurate but column numbers will be too high).
+ /// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate
+ /// trade-off between parser complexity and correctness.
+ struct TOML_TRIVIAL_ABI source_position {
+ /// \brief The line number.
+ /// \remarks Valid line numbers start at 1.
+ source_index line;
+
+ /// \brief The column number.
+ /// \remarks Valid column numbers start at 1.
+ source_index column;
+
+ /// \brief Returns true if both line and column numbers are non-zero.
+ TOML_PURE_GETTER
+ explicit constexpr operator bool() const noexcept {
+ return line > source_index{} //
+ && column > source_index{};
+ }
+
+ /// \brief Equality operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator==(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return lhs.line == rhs.line //
+ && lhs.column == rhs.column;
+ }
+
+ /// \brief Inequality operator.
+ TOML_PURE_INLINE_GETTER
+ friend constexpr bool operator!=(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return !(lhs == rhs);
+ }
+
+ private:
+ /// \cond
+
+ TOML_PURE_GETTER
+ static constexpr uint64_t pack(const source_position& pos) noexcept {
+ return static_cast<uint64_t>(pos.line) << 32 | static_cast<uint64_t>(pos.column);
+ }
+
+ /// \endcond
+
+ public:
+ /// \brief Less-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return pack(lhs) < pack(rhs);
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator<=(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return pack(lhs) <= pack(rhs);
+ }
+
+ /// \brief Greater-than operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return pack(lhs) > pack(rhs);
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend constexpr bool operator>=(const source_position& lhs,
+ const source_position& rhs) noexcept {
+ return pack(lhs) >= pack(rhs);
+ }
+
+ /// \brief Prints a source_position to a stream.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse("bar = 42"sv);
+ ///
+ /// std::cout << "The value for 'bar' was found on "sv
+ /// << tbl.get("bar")->source().begin()
+ /// << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// The value for 'bar' was found on line 1, column 7
+ /// \eout
+ ///
+ /// \param lhs The stream.
+ /// \param rhs The source_position.
+ ///
+ /// \returns The input stream.
+ friend std::ostream& operator<<(std::ostream& lhs, const source_position& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
+
+ /// \brief A source document region.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse_file("config.toml"sv);
+ /// if (auto server = tbl.get("server"))
+ /// {
+ /// std::cout << "begin: "sv << server->source().begin << "\n";
+ /// std::cout << "end: "sv << server->source().end << "\n";
+ /// std::cout << "path: "sv << *server->source().path << "\n";
+ /// }
+ /// \ecpp
+ ///
+ /// \out
+ /// begin: line 3, column 1
+ /// end: line 3, column 22
+ /// path: config.toml
+ /// \eout
+ ///
+ /// \remarks toml++'s parser is unicode-aware insofar as it knows how to handle
+ /// non-ASCII whitespace and newline characters, but it doesn't give much thought
+ /// to combining marks, grapheme clusters vs. characters, et cetera.
+ /// If a TOML document contains lots of codepoints outside of the ASCII range
+ /// you may find that your source_positions don't match those given by a text editor
+ /// (typically the line numbers will be accurate but column numbers will be too high).
+ /// <strong>This is not an error.</strong> I've chosen this behaviour as a deliberate
+ /// trade-off between parser complexity and correctness.
+ struct source_region {
+ /// \brief The beginning of the region (inclusive).
+ source_position begin;
+
+ /// \brief The end of the region (exclusive).
+ source_position end;
+
+ /// \brief The path to the corresponding source document.
+ ///
+ /// \remarks This will be `nullptr` if no path was provided to toml::parse().
+ source_path_ptr path;
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief The path to the corresponding source document as a wide-string.
- ///
- /// \availability This function is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \remarks This will return an empty optional if no path was provided to toml::parse().
- TOML_NODISCARD
- optional<std::wstring> wide_path() const
- {
- if (!path || path->empty())
- return {};
- return { impl::widen(*path) };
- }
+ /// \brief The path to the corresponding source document as a wide-string.
+ ///
+ /// \availability This function is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \remarks This will return an empty optional if no path was provided to toml::parse().
+ TOML_NODISCARD
+ optional<std::wstring> wide_path() const {
+ if (!path || path->empty()) return {};
+ return {impl::widen(*path)};
+ }
#endif
- /// \brief Prints a source_region to a stream.
- ///
- /// \detail \cpp
- /// auto tbl = toml::parse("bar = 42", "config.toml");
- ///
- /// std::cout << "The value for 'bar' was found on "sv
- /// << tbl.get("bar")->source()
- /// << "\n";
- /// \ecpp
- ///
- /// \out
- /// The value for 'bar' was found on line 1, column 7 of 'config.toml'
- /// \eout
- ///
- /// \param lhs The stream.
- /// \param rhs The source_position.
- ///
- /// \returns The input stream.
- friend std::ostream& operator<<(std::ostream& lhs, const source_region& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
- };
+ /// \brief Prints a source_region to a stream.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::parse("bar = 42", "config.toml");
+ ///
+ /// std::cout << "The value for 'bar' was found on "sv
+ /// << tbl.get("bar")->source()
+ /// << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// The value for 'bar' was found on line 1, column 7 of 'config.toml'
+ /// \eout
+ ///
+ /// \param lhs The stream.
+ /// \param rhs The source_position.
+ ///
+ /// \returns The input stream.
+ friend std::ostream& operator<<(std::ostream& lhs, const source_region& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
+ };
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/std_except.hpp b/vendor/toml++/impl/std_except.hpp
index 9ea1479..fe63d6c 100644
--- a/vendor/toml++/impl/std_except.hpp
+++ b/vendor/toml++/impl/std_except.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
diff --git a/vendor/toml++/impl/std_initializer_list.hpp b/vendor/toml++/impl/std_initializer_list.hpp
index e1ba61d..00f7ba0 100644
--- a/vendor/toml++/impl/std_initializer_list.hpp
+++ b/vendor/toml++/impl/std_initializer_list.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
diff --git a/vendor/toml++/impl/std_map.hpp b/vendor/toml++/impl/std_map.hpp
index 8f97330..64305aa 100644
--- a/vendor/toml++/impl/std_map.hpp
+++ b/vendor/toml++/impl/std_map.hpp
@@ -1,11 +1,11 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
TOML_DISABLE_WARNINGS;
-#include <map>
#include <iterator>
+#include <map>
TOML_ENABLE_WARNINGS;
diff --git a/vendor/toml++/impl/std_new.hpp b/vendor/toml++/impl/std_new.hpp
index c896a71..dd54bad 100644
--- a/vendor/toml++/impl/std_new.hpp
+++ b/vendor/toml++/impl/std_new.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
@@ -9,7 +9,8 @@ TOML_DISABLE_WARNINGS;
#include <new>
TOML_ENABLE_WARNINGS;
-#if (!defined(__apple_build_version__) && TOML_CLANG >= 8) || TOML_GCC >= 7 || TOML_ICC >= 1910 || TOML_MSVC >= 1914
+#if (!defined(__apple_build_version__) && TOML_CLANG >= 8) || TOML_GCC >= 7 || TOML_ICC >= 1910 || \
+ TOML_MSVC >= 1914
#define TOML_LAUNDER(x) __builtin_launder(x)
#elif defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
#define TOML_LAUNDER(x) std::launder(x)
diff --git a/vendor/toml++/impl/std_optional.hpp b/vendor/toml++/impl/std_optional.hpp
index 6760388..6e988b5 100644
--- a/vendor/toml++/impl/std_optional.hpp
+++ b/vendor/toml++/impl/std_optional.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
@@ -11,21 +11,20 @@ TOML_DISABLE_WARNINGS;
#endif
TOML_ENABLE_WARNINGS;
-TOML_NAMESPACE_START
-{
+TOML_NAMESPACE_START {
#if TOML_HAS_CUSTOM_OPTIONAL_TYPE
- template <typename T>
- using optional = TOML_OPTIONAL_TYPE<T>;
+ template <typename T>
+ using optional = TOML_OPTIONAL_TYPE<T>;
#else
- /// \brief The 'optional' type used throughout the library.
- ///
- /// \remarks By default this will be an alias for std::optional, but you can change the optional type
- /// used by the library by defining #TOML_OPTIONAL_TYPE.
- template <typename T>
- using optional = std::optional<T>;
+ /// \brief The 'optional' type used throughout the library.
+ ///
+ /// \remarks By default this will be an alias for std::optional, but you can change the optional
+ /// type used by the library by defining #TOML_OPTIONAL_TYPE.
+ template <typename T>
+ using optional = std::optional<T>;
#endif
}
diff --git a/vendor/toml++/impl/std_string.hpp b/vendor/toml++/impl/std_string.hpp
index b75afaf..5230661 100644
--- a/vendor/toml++/impl/std_string.hpp
+++ b/vendor/toml++/impl/std_string.hpp
@@ -1,18 +1,17 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
TOML_DISABLE_WARNINGS;
-#include <string_view>
#include <string>
+#include <string_view>
TOML_ENABLE_WARNINGS;
-#if TOML_DOXYGEN \
- || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && defined(__cpp_lib_char8_t) \
- && __cpp_lib_char8_t >= 201907)
+#if TOML_DOXYGEN || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811 && \
+ defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201907)
#define TOML_HAS_CHAR8 1
#else
#define TOML_HAS_CHAR8 0
@@ -20,34 +19,33 @@ TOML_ENABLE_WARNINGS;
/// \cond
-namespace toml // non-abi namespace; this is not an error
+namespace toml // non-abi namespace; this is not an error
{
- using namespace std::string_literals;
- using namespace std::string_view_literals;
-}
+using namespace std::string_literals;
+using namespace std::string_view_literals;
+} // namespace toml
#if TOML_ENABLE_WINDOWS_COMPAT
-TOML_IMPL_NAMESPACE_START
-{
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- std::string narrow(std::wstring_view);
+TOML_IMPL_NAMESPACE_START {
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ std::string narrow(std::wstring_view);
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- std::wstring widen(std::string_view);
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ std::wstring widen(std::string_view);
#if TOML_HAS_CHAR8
- TOML_NODISCARD
- TOML_EXPORTED_FREE_FUNCTION
- std::wstring widen(std::u8string_view);
+ TOML_NODISCARD
+ TOML_EXPORTED_FREE_FUNCTION
+ std::wstring widen(std::u8string_view);
#endif
}
TOML_IMPL_NAMESPACE_END;
-#endif // TOML_ENABLE_WINDOWS_COMPAT
+#endif // TOML_ENABLE_WINDOWS_COMPAT
/// \endcond
diff --git a/vendor/toml++/impl/std_utility.hpp b/vendor/toml++/impl/std_utility.hpp
index aacb1d5..02c836f 100644
--- a/vendor/toml++/impl/std_utility.hpp
+++ b/vendor/toml++/impl/std_utility.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
diff --git a/vendor/toml++/impl/std_variant.hpp b/vendor/toml++/impl/std_variant.hpp
index 14bf1b4..14534eb 100644
--- a/vendor/toml++/impl/std_variant.hpp
+++ b/vendor/toml++/impl/std_variant.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
diff --git a/vendor/toml++/impl/std_vector.hpp b/vendor/toml++/impl/std_vector.hpp
index e0cbac4..c1a1218 100644
--- a/vendor/toml++/impl/std_vector.hpp
+++ b/vendor/toml++/impl/std_vector.hpp
@@ -1,11 +1,11 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
TOML_DISABLE_WARNINGS;
-#include <vector>
#include <iterator>
+#include <vector>
TOML_ENABLE_WARNINGS;
diff --git a/vendor/toml++/impl/table.hpp b/vendor/toml++/impl/table.hpp
index edb7316..a49b16b 100644
--- a/vendor/toml++/impl/table.hpp
+++ b/vendor/toml++/impl/table.hpp
@@ -1,1995 +1,1726 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "forward_declarations.hpp"
-#include "std_map.hpp"
-#include "std_initializer_list.hpp"
#include "array.hpp"
+#include "forward_declarations.hpp"
+#include "header_start.hpp"
+#include "key.hpp"
#include "make_node.hpp"
#include "node_view.hpp"
-#include "key.hpp"
-#include "header_start.hpp"
+#include "std_initializer_list.hpp"
+#include "std_map.hpp"
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <bool IsConst>
- struct table_proxy_pair
- {
- using value_type = std::conditional_t<IsConst, const node, node>;
-
- const toml::key& first;
- value_type& second;
- };
-
- template <bool IsConst>
- class table_iterator
- {
- private:
- template <bool>
- friend class table_iterator;
-
- using proxy_type = table_proxy_pair<IsConst>;
- using mutable_map_iterator = std::map<toml::key, node_ptr, std::less<>>::iterator;
- using const_map_iterator = std::map<toml::key, node_ptr, std::less<>>::const_iterator;
- using map_iterator = std::conditional_t<IsConst, const_map_iterator, mutable_map_iterator>;
-
- mutable map_iterator iter_;
- alignas(proxy_type) mutable unsigned char proxy_[sizeof(proxy_type)];
- mutable bool proxy_instantiated_ = false;
-
- TOML_NODISCARD
- proxy_type* get_proxy() const noexcept
- {
- if (!proxy_instantiated_)
- {
- auto p = ::new (static_cast<void*>(proxy_)) proxy_type{ iter_->first, *iter_->second.get() };
- proxy_instantiated_ = true;
- return p;
- }
- else
- return TOML_LAUNDER(reinterpret_cast<proxy_type*>(proxy_));
- }
-
- public:
- TOML_NODISCARD_CTOR
- table_iterator() noexcept = default;
-
- TOML_NODISCARD_CTOR
- explicit table_iterator(mutable_map_iterator iter) noexcept //
- : iter_{ iter }
- {}
-
- TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
- TOML_NODISCARD_CTOR
- explicit table_iterator(const_map_iterator iter) noexcept //
- : iter_{ iter }
- {}
-
- TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
- TOML_NODISCARD_CTOR
- table_iterator(const table_iterator<false>& other) noexcept //
- : iter_{ other.iter_ }
- {}
-
- TOML_NODISCARD_CTOR
- table_iterator(const table_iterator& other) noexcept //
- : iter_{ other.iter_ }
- {}
-
- table_iterator& operator=(const table_iterator& rhs) noexcept
- {
- iter_ = rhs.iter_;
- proxy_instantiated_ = false;
- return *this;
- }
-
- using value_type = table_proxy_pair<IsConst>;
- using reference = value_type&;
- using pointer = value_type*;
- using difference_type = typename std::iterator_traits<map_iterator>::difference_type;
- using iterator_category = typename std::iterator_traits<map_iterator>::iterator_category;
-
- table_iterator& operator++() noexcept // ++pre
- {
- ++iter_;
- proxy_instantiated_ = false;
- return *this;
- }
-
- table_iterator operator++(int) noexcept // post++
- {
- table_iterator out{ iter_ };
- ++iter_;
- proxy_instantiated_ = false;
- return out;
- }
-
- table_iterator& operator--() noexcept // --pre
- {
- --iter_;
- proxy_instantiated_ = false;
- return *this;
- }
-
- table_iterator operator--(int) noexcept // post--
- {
- table_iterator out{ iter_ };
- --iter_;
- proxy_instantiated_ = false;
- return out;
- }
-
- TOML_PURE_INLINE_GETTER
- reference operator*() const noexcept
- {
- return *get_proxy();
- }
-
- TOML_PURE_INLINE_GETTER
- pointer operator->() const noexcept
- {
- return get_proxy();
- }
-
- TOML_PURE_INLINE_GETTER
- explicit operator const map_iterator&() const noexcept
- {
- return iter_;
- }
-
- TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
- TOML_PURE_INLINE_GETTER
- explicit operator const const_map_iterator() const noexcept
- {
- return iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator==(const table_iterator& lhs, const table_iterator& rhs) noexcept
- {
- return lhs.iter_ == rhs.iter_;
- }
-
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const table_iterator& lhs, const table_iterator& rhs) noexcept
- {
- return lhs.iter_ != rhs.iter_;
- }
- };
-
- struct table_init_pair
- {
- mutable toml::key key;
- mutable node_ptr value;
-
- template <typename K, typename V>
- TOML_NODISCARD_CTOR
- table_init_pair(K&& k, V&& v, value_flags flags = preserve_source_value_flags) //
- : key{ static_cast<K&&>(k) },
- value{ make_node(static_cast<V&&>(v), flags) }
- {}
- };
+TOML_IMPL_NAMESPACE_START {
+ template <bool IsConst>
+ struct table_proxy_pair {
+ using value_type = std::conditional_t<IsConst, const node, node>;
+
+ const toml::key& first;
+ value_type& second;
+ };
+
+ template <bool IsConst>
+ class table_iterator {
+ private:
+ template <bool>
+ friend class table_iterator;
+
+ using proxy_type = table_proxy_pair<IsConst>;
+ using mutable_map_iterator = std::map<toml::key, node_ptr, std::less<>>::iterator;
+ using const_map_iterator = std::map<toml::key, node_ptr, std::less<>>::const_iterator;
+ using map_iterator = std::conditional_t<IsConst, const_map_iterator, mutable_map_iterator>;
+
+ mutable map_iterator iter_;
+ alignas(proxy_type) mutable unsigned char proxy_[sizeof(proxy_type)];
+ mutable bool proxy_instantiated_ = false;
+
+ TOML_NODISCARD
+ proxy_type* get_proxy() const noexcept {
+ if (!proxy_instantiated_) {
+ auto p = ::new (static_cast<void*>(proxy_)) proxy_type{iter_->first, *iter_->second.get()};
+ proxy_instantiated_ = true;
+ return p;
+ } else
+ return TOML_LAUNDER(reinterpret_cast<proxy_type*>(proxy_));
+ }
+
+ public:
+ TOML_NODISCARD_CTOR
+ table_iterator() noexcept = default;
+
+ TOML_NODISCARD_CTOR
+ explicit table_iterator(mutable_map_iterator iter) noexcept //
+ : iter_{iter} {}
+
+ TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
+ TOML_NODISCARD_CTOR
+ explicit table_iterator(const_map_iterator iter) noexcept //
+ : iter_{iter} {}
+
+ TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
+ TOML_NODISCARD_CTOR
+ table_iterator(const table_iterator<false>& other) noexcept //
+ : iter_{other.iter_} {}
+
+ TOML_NODISCARD_CTOR
+ table_iterator(const table_iterator& other) noexcept //
+ : iter_{other.iter_} {}
+
+ table_iterator& operator=(const table_iterator& rhs) noexcept {
+ iter_ = rhs.iter_;
+ proxy_instantiated_ = false;
+ return *this;
+ }
+
+ using value_type = table_proxy_pair<IsConst>;
+ using reference = value_type&;
+ using pointer = value_type*;
+ using difference_type = typename std::iterator_traits<map_iterator>::difference_type;
+ using iterator_category = typename std::iterator_traits<map_iterator>::iterator_category;
+
+ table_iterator& operator++() noexcept // ++pre
+ {
+ ++iter_;
+ proxy_instantiated_ = false;
+ return *this;
+ }
+
+ table_iterator operator++(int) noexcept // post++
+ {
+ table_iterator out{iter_};
+ ++iter_;
+ proxy_instantiated_ = false;
+ return out;
+ }
+
+ table_iterator& operator--() noexcept // --pre
+ {
+ --iter_;
+ proxy_instantiated_ = false;
+ return *this;
+ }
+
+ table_iterator operator--(int) noexcept // post--
+ {
+ table_iterator out{iter_};
+ --iter_;
+ proxy_instantiated_ = false;
+ return out;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ reference operator*() const noexcept { return *get_proxy(); }
+
+ TOML_PURE_INLINE_GETTER
+ pointer operator->() const noexcept { return get_proxy(); }
+
+ TOML_PURE_INLINE_GETTER
+ explicit operator const map_iterator&() const noexcept { return iter_; }
+
+ TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
+ TOML_PURE_INLINE_GETTER
+ explicit operator const const_map_iterator() const noexcept { return iter_; }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator==(const table_iterator& lhs, const table_iterator& rhs) noexcept {
+ return lhs.iter_ == rhs.iter_;
+ }
+
+ TOML_PURE_INLINE_GETTER
+ friend bool operator!=(const table_iterator& lhs, const table_iterator& rhs) noexcept {
+ return lhs.iter_ != rhs.iter_;
+ }
+ };
+
+ struct table_init_pair {
+ mutable toml::key key;
+ mutable node_ptr value;
+
+ template <typename K, typename V>
+ TOML_NODISCARD_CTOR table_init_pair(K&& k, V&& v,
+ value_flags flags = preserve_source_value_flags) //
+ : key{static_cast<K&&>(k)}, value{make_node(static_cast<V&&>(v), flags)} {}
+ };
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
- using table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<false>);
-
- /// \brief A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
- using const_table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<true>);
-
- /// \brief A TOML table.
- ///
- /// \detail The interface of this type is modeled after std::map, with some
- /// additional considerations made for the heterogeneous nature of a
- /// TOML table.
- ///
- /// \cpp
- /// toml::table tbl = toml::parse(R"(
- ///
- /// [animals]
- /// cats = [ "tiger", "lion", "puma" ]
- /// birds = [ "macaw", "pigeon", "canary" ]
- /// fish = [ "salmon", "trout", "carp" ]
- ///
- /// )"sv);
- ///
- /// // operator[] retrieves node-views
- /// std::cout << "cats: " << tbl["animals"]["cats"] << "\n";
- /// std::cout << "fish[1]: " << tbl["animals"]["fish"][1] << "\n";
- ///
- /// // at_path() does fully-qualified "toml path" lookups
- /// std::cout << "cats: " << tbl.at_path("animals.cats") << "\n";
- /// std::cout << "fish[1]: " << tbl.at_path("animals.fish[1]") << "\n";
- /// \ecpp
- ///
- /// \out
- /// cats: ['tiger', 'lion', 'puma']
- /// fish[1] : 'trout'
- /// cats : ['tiger', 'lion', 'puma']
- /// fish[1] : 'trout'
- /// \eout
- class TOML_EXPORTED_CLASS table : public node
- {
- private:
- /// \cond
-
- using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
- using map_pair = std::pair<const toml::key, impl::node_ptr>;
- using map_iterator = typename map_type::iterator;
- using const_map_iterator = typename map_type::const_iterator;
- map_type map_;
-
- bool inline_ = false;
-
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- table(const impl::table_init_pair*, const impl::table_init_pair*);
-
- /// \endcond
-
- public:
- /// \brief Default constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- table() noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- ~table() noexcept;
-
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- table(const table&);
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- table(table&& other) noexcept;
-
- /// \brief Constructs a table with one or more initial key-value pairs.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "foo", 1 },
- /// { "bar", 2.0 },
- /// { "kek", "three" }
- /// };
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { foo = 1, bar = 2.0, kek = "three" }
- /// \eout
- ///
- /// \param kvps A list of key-value pairs used to initialize the table.
- TOML_NODISCARD_CTOR
- TOML_EXPORTED_MEMBER_FUNCTION
- explicit table(std::initializer_list<impl::table_init_pair> kvps) //
- : table(kvps.begin(), kvps.end())
- {}
-
- /// \brief Copy-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- table& operator=(const table&);
-
- /// \brief Move-assignment operator.
- TOML_EXPORTED_MEMBER_FUNCTION
- table& operator=(table&& rhs) noexcept;
-
- /// \name Type checks
- /// @{
-
- /// \brief Returns #toml::node_type::table.
- TOML_CONST_INLINE_GETTER
- node_type type() const noexcept final
- {
- return node_type::table;
- }
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype) const noexcept final;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
-
- /// \cond
- template <typename ElemType = void>
- TOML_PURE_GETTER
- bool is_homogeneous() const noexcept
- {
- using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
- static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
- "The template type argument of table::is_homogeneous() must be void or one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- return is_homogeneous(impl::node_type_of<type>);
- }
- /// \endcond
-
- /// \brief Returns `true`.
- TOML_CONST_INLINE_GETTER
- bool is_table() const noexcept final
- {
- return true;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_array() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_PURE_GETTER
- bool is_array_of_tables() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_value() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_string() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_integer() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_floating_point() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_number() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_boolean() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_date() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_time() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_date_time() const noexcept final
- {
- return false;
- }
-
- /// @}
-
- /// \name Type casts
- /// @{
-
- /// \brief Returns a pointer to the table.
- TOML_CONST_INLINE_GETTER
- table* as_table() noexcept final
- {
- return this;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- array* as_array() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<std::string>* as_string() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<int64_t>* as_integer() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<double>* as_floating_point() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<bool>* as_boolean() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<date>* as_date() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<time>* as_time() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- toml::value<date_time>* as_date_time() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns a const-qualified pointer to the table.
- TOML_CONST_INLINE_GETTER
- const table* as_table() const noexcept final
- {
- return this;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const array* as_array() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<std::string>* as_string() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<int64_t>* as_integer() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<double>* as_floating_point() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<bool>* as_boolean() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<date>* as_date() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<time>* as_time() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const toml::value<date_time>* as_date_time() const noexcept final
- {
- return nullptr;
- }
-
- /// @}
-
- /// \name Metadata
- /// @{
-
- /// \brief Returns true if this table is an inline table.
- ///
- /// \remarks Runtime-constructed tables (i.e. those not created during
- /// parsing) are not inline by default.
- TOML_PURE_INLINE_GETTER
- bool is_inline() const noexcept
- {
- return inline_;
- }
-
- /// \brief Sets whether this table is a TOML inline table.
- ///
- /// \detail \godbolt{an9xdj}
- ///
- /// \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 },
- /// { "d", toml::table{ { "e", 4 } } }
- /// };
- /// std::cout << "is inline? "sv << tbl.is_inline() << "\n";
- /// std::cout << tbl << "\n\n";
- ///
- /// tbl.is_inline(!tbl.is_inline());
- /// std::cout << "is inline? "sv << tbl.is_inline() << "\n";
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// is inline? false
- /// a = 1
- /// b = 2
- /// c = 3
- ///
- /// [d]
- /// e = 4
- ///
- ///
- /// is inline? true
- /// { a = 1, b = 2, c = 3, d = { e = 4 } }
- /// \eout
- ///
- /// \remarks A table being 'inline' is only relevent during printing;
- /// it has no effect on the general functionality of the table
- /// object.
- ///
- /// \param val The new value for 'inline'.
- void is_inline(bool val) noexcept
- {
- inline_ = val;
- }
-
- /// @}
-
- /// \name Value retrieval
- /// @{
-
- /// \brief Gets the node at a specific key.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 42, },
- /// { "b", "is the meaning of life, apparently." }
- /// };
- /// std::cout << R"(node ["a"] exists: )"sv << !!arr.get("a") << "\n";
- /// std::cout << R"(node ["b"] exists: )"sv << !!arr.get("b") << "\n";
- /// std::cout << R"(node ["c"] exists: )"sv << !!arr.get("c") << "\n";
- /// if (auto val = arr.get("a"))
- /// std::cout << R"(node ["a"] was an )"sv << val->type() << "\n";
- /// \ecpp
- ///
- /// \out
- /// node ["a"] exists: true
- /// node ["b"] exists: true
- /// node ["c"] exists: false
- /// node ["a"] was an integer
- /// \eout
- ///
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key, or nullptr.
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- node* get(std::string_view key) noexcept;
-
- /// \brief Gets the node at a specific key (const overload).
- ///
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key, or nullptr.
- TOML_PURE_INLINE_GETTER
- const node* get(std::string_view key) const noexcept
- {
- return const_cast<table&>(*this).get(key);
- }
+TOML_NAMESPACE_START {
+ /// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
+ using table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<false>);
+
+ /// \brief A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
+ using const_table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<true>);
+
+ /// \brief A TOML table.
+ ///
+ /// \detail The interface of this type is modeled after std::map, with some
+ /// additional considerations made for the heterogeneous nature of a
+ /// TOML table.
+ ///
+ /// \cpp
+ /// toml::table tbl = toml::parse(R"(
+ ///
+ /// [animals]
+ /// cats = [ "tiger", "lion", "puma" ]
+ /// birds = [ "macaw", "pigeon", "canary" ]
+ /// fish = [ "salmon", "trout", "carp" ]
+ ///
+ /// )"sv);
+ ///
+ /// // operator[] retrieves node-views
+ /// std::cout << "cats: " << tbl["animals"]["cats"] << "\n";
+ /// std::cout << "fish[1]: " << tbl["animals"]["fish"][1] << "\n";
+ ///
+ /// // at_path() does fully-qualified "toml path" lookups
+ /// std::cout << "cats: " << tbl.at_path("animals.cats") << "\n";
+ /// std::cout << "fish[1]: " << tbl.at_path("animals.fish[1]") << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// cats: ['tiger', 'lion', 'puma']
+ /// fish[1] : 'trout'
+ /// cats : ['tiger', 'lion', 'puma']
+ /// fish[1] : 'trout'
+ /// \eout
+ class TOML_EXPORTED_CLASS table : public node {
+ private:
+ /// \cond
+
+ using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
+ using map_pair = std::pair<const toml::key, impl::node_ptr>;
+ using map_iterator = typename map_type::iterator;
+ using const_map_iterator = typename map_type::const_iterator;
+ map_type map_;
+
+ bool inline_ = false;
+
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table(const impl::table_init_pair*, const impl::table_init_pair*);
+
+ /// \endcond
+
+ public:
+ /// \brief Default constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table() noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ ~table() noexcept;
+
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table(const table&);
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table(table&& other) noexcept;
+
+ /// \brief Constructs a table with one or more initial key-value pairs.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "foo", 1 },
+ /// { "bar", 2.0 },
+ /// { "kek", "three" }
+ /// };
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { foo = 1, bar = 2.0, kek = "three" }
+ /// \eout
+ ///
+ /// \param kvps A list of key-value pairs used to initialize the table.
+ TOML_NODISCARD_CTOR
+ TOML_EXPORTED_MEMBER_FUNCTION
+ explicit table(std::initializer_list<impl::table_init_pair> kvps) //
+ : table(kvps.begin(), kvps.end()) {}
+
+ /// \brief Copy-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table& operator=(const table&);
+
+ /// \brief Move-assignment operator.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table& operator=(table&& rhs) noexcept;
+
+ /// \name Type checks
+ /// @{
+
+ /// \brief Returns #toml::node_type::table.
+ TOML_CONST_INLINE_GETTER
+ node_type type() const noexcept final { return node_type::table; }
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype) const noexcept final;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
+
+ /// \cond
+ template <typename ElemType = void>
+ TOML_PURE_GETTER bool is_homogeneous() const noexcept {
+ using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
+ static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
+ "The template type argument of table::is_homogeneous() must be void or one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ return is_homogeneous(impl::node_type_of<type>);
+ }
+ /// \endcond
+
+ /// \brief Returns `true`.
+ TOML_CONST_INLINE_GETTER
+ bool is_table() const noexcept final { return true; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_array() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_PURE_GETTER
+ bool is_array_of_tables() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_value() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_string() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_integer() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_floating_point() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_number() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_boolean() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_date() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_time() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_date_time() const noexcept final { return false; }
+
+ /// @}
+
+ /// \name Type casts
+ /// @{
+
+ /// \brief Returns a pointer to the table.
+ TOML_CONST_INLINE_GETTER
+ table* as_table() noexcept final { return this; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ array* as_array() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<std::string>* as_string() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<int64_t>* as_integer() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<double>* as_floating_point() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<bool>* as_boolean() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<date>* as_date() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<time>* as_time() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ toml::value<date_time>* as_date_time() noexcept final { return nullptr; }
+
+ /// \brief Returns a const-qualified pointer to the table.
+ TOML_CONST_INLINE_GETTER
+ const table* as_table() const noexcept final { return this; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const array* as_array() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<std::string>* as_string() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<int64_t>* as_integer() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<double>* as_floating_point() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<bool>* as_boolean() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<date>* as_date() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<time>* as_time() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const toml::value<date_time>* as_date_time() const noexcept final { return nullptr; }
+
+ /// @}
+
+ /// \name Metadata
+ /// @{
+
+ /// \brief Returns true if this table is an inline table.
+ ///
+ /// \remarks Runtime-constructed tables (i.e. those not created during
+ /// parsing) are not inline by default.
+ TOML_PURE_INLINE_GETTER
+ bool is_inline() const noexcept { return inline_; }
+
+ /// \brief Sets whether this table is a TOML inline table.
+ ///
+ /// \detail \godbolt{an9xdj}
+ ///
+ /// \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 },
+ /// { "d", toml::table{ { "e", 4 } } }
+ /// };
+ /// std::cout << "is inline? "sv << tbl.is_inline() << "\n";
+ /// std::cout << tbl << "\n\n";
+ ///
+ /// tbl.is_inline(!tbl.is_inline());
+ /// std::cout << "is inline? "sv << tbl.is_inline() << "\n";
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// is inline? false
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ ///
+ /// [d]
+ /// e = 4
+ ///
+ ///
+ /// is inline? true
+ /// { a = 1, b = 2, c = 3, d = { e = 4 } }
+ /// \eout
+ ///
+ /// \remarks A table being 'inline' is only relevent during printing;
+ /// it has no effect on the general functionality of the table
+ /// object.
+ ///
+ /// \param val The new value for 'inline'.
+ void is_inline(bool val) noexcept { inline_ = val; }
+
+ /// @}
+
+ /// \name Value retrieval
+ /// @{
+
+ /// \brief Gets the node at a specific key.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 42, },
+ /// { "b", "is the meaning of life, apparently." }
+ /// };
+ /// std::cout << R"(node ["a"] exists: )"sv << !!arr.get("a") << "\n";
+ /// std::cout << R"(node ["b"] exists: )"sv << !!arr.get("b") << "\n";
+ /// std::cout << R"(node ["c"] exists: )"sv << !!arr.get("c") << "\n";
+ /// if (auto val = arr.get("a"))
+ /// std::cout << R"(node ["a"] was an )"sv << val->type() << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// node ["a"] exists: true
+ /// node ["b"] exists: true
+ /// node ["c"] exists: false
+ /// node ["a"] was an integer
+ /// \eout
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key, or nullptr.
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node* get(std::string_view key) noexcept;
+
+ /// \brief Gets the node at a specific key (const overload).
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key, or nullptr.
+ TOML_PURE_INLINE_GETTER
+ const node* get(std::string_view key) const noexcept {
+ return const_cast<table&>(*this).get(key);
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets the node at a specific key.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key, or nullptr.
- TOML_NODISCARD
- node* get(std::wstring_view key)
- {
- if (empty())
- return nullptr;
-
- return get(impl::narrow(key));
- }
-
- /// \brief Gets the node at a specific key (const overload).
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key, or nullptr.
- TOML_NODISCARD
- const node* get(std::wstring_view key) const
- {
- return const_cast<table&>(*this).get(key);
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Gets the node at a specific key if it is a particular type.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 42, },
- /// { "b", "is the meaning of life, apparently." }
- /// };
- /// if (auto val = arr.get_as<int64_t>("a"))
- /// std::cout << R"(node ["a"] was an integer with value )"sv << **val << "\n";
- /// \ecpp
- ///
- /// \out
- /// node ["a"] was an integer with value 42
- /// \eout
- ///
- /// \tparam T One of the TOML node or value types.
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
- template <typename T>
- TOML_PURE_GETTER
- impl::wrap_node<T>* get_as(std::string_view key) noexcept
- {
- const auto n = this->get(key);
- return n ? n->template as<T>() : nullptr;
- }
-
- /// \brief Gets the node at a specific key if it is a particular type (const overload).
- ///
- /// \tparam T One of the TOML node or value types.
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
- template <typename T>
- TOML_PURE_GETTER
- const impl::wrap_node<T>* get_as(std::string_view key) const noexcept
- {
- return const_cast<table&>(*this).template get_as<T>(key);
- }
+ /// \brief Gets the node at a specific key.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key, or nullptr.
+ TOML_NODISCARD
+ node* get(std::wstring_view key) {
+ if (empty()) return nullptr;
+
+ return get(impl::narrow(key));
+ }
+
+ /// \brief Gets the node at a specific key (const overload).
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key, or nullptr.
+ TOML_NODISCARD
+ const node* get(std::wstring_view key) const { return const_cast<table&>(*this).get(key); }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Gets the node at a specific key if it is a particular type.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 42, },
+ /// { "b", "is the meaning of life, apparently." }
+ /// };
+ /// if (auto val = arr.get_as<int64_t>("a"))
+ /// std::cout << R"(node ["a"] was an integer with value )"sv << **val << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// node ["a"] was an integer with value 42
+ /// \eout
+ ///
+ /// \tparam T One of the TOML node or value types.
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key if it was of the given type, or
+ /// nullptr.
+ template <typename T>
+ TOML_PURE_GETTER impl::wrap_node<T>* get_as(std::string_view key) noexcept {
+ const auto n = this->get(key);
+ return n ? n->template as<T>() : nullptr;
+ }
+
+ /// \brief Gets the node at a specific key if it is a particular type (const overload).
+ ///
+ /// \tparam T One of the TOML node or value types.
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key if it was of the given type, or
+ /// nullptr.
+ template <typename T>
+ TOML_PURE_GETTER const impl::wrap_node<T>* get_as(std::string_view key) const noexcept {
+ return const_cast<table&>(*this).template get_as<T>(key);
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets the node at a specific key if it is a particular type.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \tparam T One of the TOML node or value types.
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
- template <typename T>
- TOML_NODISCARD
- impl::wrap_node<T>* get_as(std::wstring_view key)
- {
- if (empty())
- return nullptr;
-
- return get_as<T>(impl::narrow(key));
- }
-
- /// \brief Gets the node at a specific key if it is a particular type (const overload).
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \tparam T One of the TOML node or value types.
- /// \param key The node's key.
- ///
- /// \returns A pointer to the node at the specified key if it was of the given type, or nullptr.
- template <typename T>
- TOML_NODISCARD
- const impl::wrap_node<T>* get_as(std::wstring_view key) const
- {
- return const_cast<table&>(*this).template get_as<T>(key);
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
- TOML_NODISCARD
- TOML_EXPORTED_MEMBER_FUNCTION
- node& at(std::string_view key);
-
- /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
- TOML_NODISCARD
- const node& at(std::string_view key) const
- {
- return const_cast<table&>(*this).at(key);
- }
+ /// \brief Gets the node at a specific key if it is a particular type.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \tparam T One of the TOML node or value types.
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key if it was of the given type, or
+ /// nullptr.
+ template <typename T>
+ TOML_NODISCARD impl::wrap_node<T>* get_as(std::wstring_view key) {
+ if (empty()) return nullptr;
+
+ return get_as<T>(impl::narrow(key));
+ }
+
+ /// \brief Gets the node at a specific key if it is a particular type (const overload).
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \tparam T One of the TOML node or value types.
+ /// \param key The node's key.
+ ///
+ /// \returns A pointer to the node at the specified key if it was of the given type, or
+ /// nullptr.
+ template <typename T>
+ TOML_NODISCARD const impl::wrap_node<T>* get_as(std::wstring_view key) const {
+ return const_cast<table&>(*this).template get_as<T>(key);
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if
+ /// none existed.
+ TOML_NODISCARD
+ TOML_EXPORTED_MEMBER_FUNCTION
+ node& at(std::string_view key);
+
+ /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if
+ /// none existed.
+ TOML_NODISCARD
+ const node& at(std::string_view key) const { return const_cast<table&>(*this).at(key); }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- node& at(std::wstring_view key)
- {
- return at(impl::narrow(key));
- }
-
- /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if none existed.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- const node& at(std::wstring_view key) const
- {
- return const_cast<table&>(*this).at(key);
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// @}
-
- /// \name Iteration
- /// @{
-
- /// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
- using iterator = toml::table_iterator;
-
- /// \brief A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
- using const_iterator = toml::const_table_iterator;
-
- /// \brief Returns an iterator to the first key-value pair.
- TOML_PURE_INLINE_GETTER
- iterator begin() noexcept
- {
- return iterator{ map_.begin() };
- }
-
- /// \brief Returns an iterator to the first key-value pair.
- TOML_PURE_INLINE_GETTER
- const_iterator begin() const noexcept
- {
- return const_iterator{ map_.cbegin() };
- }
-
- /// \brief Returns an iterator to the first key-value pair.
- TOML_PURE_INLINE_GETTER
- const_iterator cbegin() const noexcept
- {
- return const_iterator{ map_.cbegin() };
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair.
- TOML_PURE_INLINE_GETTER
- iterator end() noexcept
- {
- return iterator{ map_.end() };
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair.
- TOML_PURE_INLINE_GETTER
- const_iterator end() const noexcept
- {
- return const_iterator{ map_.cend() };
- }
-
- /// \brief Returns an iterator to one-past-the-last key-value pair.
- TOML_PURE_INLINE_GETTER
- const_iterator cend() const noexcept
- {
- return const_iterator{ map_.cend() };
- }
-
- private:
- /// \cond
-
- template <typename T, typename Table>
- using for_each_value_ref = impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
-
- template <typename Func, typename Table, typename T>
- using can_for_each = std::disjunction<std::is_invocable<Func, const key&, for_each_value_ref<T, Table>>, //
- std::is_invocable<Func, for_each_value_ref<T, Table>>>;
-
- template <typename Func, typename Table, typename T>
- using can_for_each_nothrow = std::conditional_t<
- // first form
- std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>>,
- std::is_nothrow_invocable<Func, const key&, for_each_value_ref<T, Table>>,
- std::conditional_t<
- // second form
- std::is_invocable_v<Func, for_each_value_ref<T, Table>>,
- std::is_nothrow_invocable<Func, for_each_value_ref<T, Table>>,
- std::false_type>>;
-
- template <typename Func, typename Table>
- using can_for_each_any = std::disjunction<can_for_each<Func, Table, table>,
- can_for_each<Func, Table, array>,
- can_for_each<Func, Table, std::string>,
- can_for_each<Func, Table, int64_t>,
- can_for_each<Func, Table, double>,
- can_for_each<Func, Table, bool>,
- can_for_each<Func, Table, date>,
- can_for_each<Func, Table, time>,
- can_for_each<Func, Table, date_time>>;
-
- template <typename Func, typename Table, typename T>
- using for_each_is_nothrow_one = std::disjunction<std::negation<can_for_each<Func, Table, T>>, //
- can_for_each_nothrow<Func, Table, T>>;
-
- template <typename Func, typename Table>
- using for_each_is_nothrow = std::conjunction<for_each_is_nothrow_one<Func, Table, table>,
- for_each_is_nothrow_one<Func, Table, array>,
- for_each_is_nothrow_one<Func, Table, std::string>,
- for_each_is_nothrow_one<Func, Table, int64_t>,
- for_each_is_nothrow_one<Func, Table, double>,
- for_each_is_nothrow_one<Func, Table, bool>,
- for_each_is_nothrow_one<Func, Table, date>,
- for_each_is_nothrow_one<Func, Table, time>,
- for_each_is_nothrow_one<Func, Table, date_time>>;
-
- template <typename Func, typename Table>
- static void do_for_each(Func&& visitor, Table&& tbl) //
- noexcept(for_each_is_nothrow<Func&&, Table&&>::value)
- {
- static_assert(can_for_each_any<Func&&, Table&&>::value,
- "TOML table for_each visitors must be invocable for at least one of the toml::node "
- "specializations:" TOML_SA_NODE_TYPE_LIST);
-
- using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
-
- for (kvp_type& kvp : tbl.map_)
- {
- using node_ref = impl::copy_cvref<toml::node, Table&&>;
- static_assert(std::is_reference_v<node_ref>);
+ /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if
+ /// none existed.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ node& at(std::wstring_view key) { return at(impl::narrow(key)); }
+
+ /// \brief Gets a reference to the element at a specific key, throwing `std::out_of_range` if
+ /// none existed.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ const node& at(std::wstring_view key) const { return const_cast<table&>(*this).at(key); }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// @}
+
+ /// \name Iteration
+ /// @{
+
+ /// \brief A BidirectionalIterator for iterating over key-value pairs in a toml::table.
+ using iterator = toml::table_iterator;
+
+ /// \brief A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
+ using const_iterator = toml::const_table_iterator;
+
+ /// \brief Returns an iterator to the first key-value pair.
+ TOML_PURE_INLINE_GETTER
+ iterator begin() noexcept { return iterator{map_.begin()}; }
+
+ /// \brief Returns an iterator to the first key-value pair.
+ TOML_PURE_INLINE_GETTER
+ const_iterator begin() const noexcept { return const_iterator{map_.cbegin()}; }
+
+ /// \brief Returns an iterator to the first key-value pair.
+ TOML_PURE_INLINE_GETTER
+ const_iterator cbegin() const noexcept { return const_iterator{map_.cbegin()}; }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair.
+ TOML_PURE_INLINE_GETTER
+ iterator end() noexcept { return iterator{map_.end()}; }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair.
+ TOML_PURE_INLINE_GETTER
+ const_iterator end() const noexcept { return const_iterator{map_.cend()}; }
+
+ /// \brief Returns an iterator to one-past-the-last key-value pair.
+ TOML_PURE_INLINE_GETTER
+ const_iterator cend() const noexcept { return const_iterator{map_.cend()}; }
+
+ private:
+ /// \cond
+
+ template <typename T, typename Table>
+ using for_each_value_ref =
+ impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
+
+ template <typename Func, typename Table, typename T>
+ using can_for_each =
+ std::disjunction<std::is_invocable<Func, const key&, for_each_value_ref<T, Table>>, //
+ std::is_invocable<Func, for_each_value_ref<T, Table>>>;
+
+ template <typename Func, typename Table, typename T>
+ using can_for_each_nothrow = std::conditional_t<
+ // first form
+ std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>>,
+ std::is_nothrow_invocable<Func, const key&, for_each_value_ref<T, Table>>,
+ std::conditional_t<
+ // second form
+ std::is_invocable_v<Func, for_each_value_ref<T, Table>>,
+ std::is_nothrow_invocable<Func, for_each_value_ref<T, Table>>, std::false_type>>;
+
+ template <typename Func, typename Table>
+ using can_for_each_any =
+ std::disjunction<can_for_each<Func, Table, table>, can_for_each<Func, Table, array>,
+ can_for_each<Func, Table, std::string>, can_for_each<Func, Table, int64_t>,
+ can_for_each<Func, Table, double>, can_for_each<Func, Table, bool>,
+ can_for_each<Func, Table, date>, can_for_each<Func, Table, time>,
+ can_for_each<Func, Table, date_time>>;
+
+ template <typename Func, typename Table, typename T>
+ using for_each_is_nothrow_one =
+ std::disjunction<std::negation<can_for_each<Func, Table, T>>, //
+ can_for_each_nothrow<Func, Table, T>>;
+
+ template <typename Func, typename Table>
+ using for_each_is_nothrow = std::conjunction<
+ for_each_is_nothrow_one<Func, Table, table>, for_each_is_nothrow_one<Func, Table, array>,
+ for_each_is_nothrow_one<Func, Table, std::string>,
+ for_each_is_nothrow_one<Func, Table, int64_t>, for_each_is_nothrow_one<Func, Table, double>,
+ for_each_is_nothrow_one<Func, Table, bool>, for_each_is_nothrow_one<Func, Table, date>,
+ for_each_is_nothrow_one<Func, Table, time>,
+ for_each_is_nothrow_one<Func, Table, date_time>>;
+
+ template <typename Func, typename Table>
+ static void do_for_each(Func&& visitor, Table&& tbl) //
+ noexcept(for_each_is_nothrow<Func&&, Table&&>::value) {
+ static_assert(
+ can_for_each_any<Func&&, Table&&>::value,
+ "TOML table for_each visitors must be invocable for at least one of the toml::node "
+ "specializations:" TOML_SA_NODE_TYPE_LIST);
+
+ using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
+
+ for (kvp_type& kvp : tbl.map_) {
+ using node_ref = impl::copy_cvref<toml::node, Table&&>;
+ static_assert(std::is_reference_v<node_ref>);
#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
- static_assert(impl::always_false<Func, Table, kvp_type, node_ref>, //
- TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
+ static_assert(impl::always_false<Func, Table, kvp_type, node_ref>, //
+ TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
#endif
- static_cast<node_ref>(*kvp.second)
- .visit(
- [&]([[maybe_unused]] auto&& v) //
- noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value)
- {
- using value_ref = for_each_value_ref<decltype(v), Table&&>;
- static_assert(std::is_reference_v<value_ref>);
-
- // func(key, val)
- if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
- {
- static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
- static_cast<value_ref>(v));
- }
-
- // func(val)
- else if constexpr (std::is_invocable_v<Func&&, value_ref>)
- {
- static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
- }
- });
+ static_cast<node_ref>(*kvp.second)
+ .visit([&]([[maybe_unused]] auto&& v) //
+ noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value) {
+ using value_ref = for_each_value_ref<decltype(v), Table&&>;
+ static_assert(std::is_reference_v<value_ref>);
+
+ // func(key, val)
+ if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>) {
+ static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
+ static_cast<value_ref>(v));
+ }
+
+ // func(val)
+ else if constexpr (std::is_invocable_v<Func&&, value_ref>) {
+ static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
+ }
+ });
#else
- const auto keep_going =
- static_cast<node_ref>(*kvp.second)
- .visit(
- [&]([[maybe_unused]] auto&& v) //
- noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value)
- {
- using value_ref = for_each_value_ref<decltype(v), Table&&>;
- static_assert(std::is_reference_v<value_ref>);
-
- // func(key, val)
- if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>)
- {
- using return_type = decltype(static_cast<Func&&>(
- visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
-
- if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
- {
- return static_cast<bool>(static_cast<Func&&>(
- visitor)(static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
- }
- else
- {
- static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
- static_cast<value_ref>(v));
- return true;
- }
- }
-
- // func(val)
- else if constexpr (std::is_invocable_v<Func&&, value_ref>)
- {
- using return_type =
- decltype(static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
-
- if constexpr (impl::is_constructible_or_convertible<bool, return_type>)
- {
- return static_cast<bool>(
- static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
- }
- else
- {
- static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
- return true;
- }
- }
-
- // visitor not compatible with this particular type
- else
- return true;
- });
-
- if (!keep_going)
- return;
+ const auto keep_going =
+ static_cast<node_ref>(*kvp.second)
+ .visit([&]([[maybe_unused]] auto&& v) //
+ noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value) {
+ using value_ref = for_each_value_ref<decltype(v), Table&&>;
+ static_assert(std::is_reference_v<value_ref>);
+
+ // func(key, val)
+ if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>) {
+ using return_type = decltype(static_cast<Func&&>(visitor)(
+ static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
+
+ if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
+ return static_cast<bool>(static_cast<Func&&>(visitor)(
+ static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
+ } else {
+ static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
+ static_cast<value_ref>(v));
+ return true;
+ }
+ }
+
+ // func(val)
+ else if constexpr (std::is_invocable_v<Func&&, value_ref>) {
+ using return_type =
+ decltype(static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
+
+ if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
+ return static_cast<bool>(
+ static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
+ } else {
+ static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
+ return true;
+ }
+ }
+
+ // visitor not compatible with this particular type
+ else
+ return true;
+ });
+
+ if (!keep_going) return;
#endif
- }
- }
-
- /// \endcond
-
- public:
- /// \brief Invokes a visitor on each key-value pair in the table.
- ///
- /// \tparam Func A callable type invocable with one of the following signatures:
- /// <ul>
- /// <li> `func(key, val)`
- /// <li> `func(val)`
- /// </ul>
- /// Where:
- /// <ul>
- /// <li> `key` will recieve a const reference to a toml::key
- /// <li> `val` will recieve the value as it's concrete type with cvref-qualifications matching the table
- /// </ul>
- /// Visitors returning `bool` (or something convertible to `bool`) will cause iteration to
- /// stop if they return `false`.
- ///
- /// \param visitor The visitor object.
- ///
- /// \returns A reference to the table.
- ///
- /// \details \cpp
- /// toml::table tbl{
- /// { "0", 0 },
- /// { "1", 1 },
- /// { "2", 2 },
- /// { "3", 3.0 },
- /// { "4", "four" },
- /// { "5", "five" },
- /// { "6", 6 }
- /// };
- ///
- /// // select only the integers using a strongly-typed visitor
- /// tbl.for_each([](toml::value<int64_t>& val)
- /// {
- /// std::cout << val << ", ";
- /// });
- /// std::cout << "\n";
- ///
- /// // select all the numeric values using a generic visitor + is_number<> metafunction
- /// tbl.for_each([](auto&& val)
- /// {
- /// if constexpr (toml::is_number<decltype(val)>)
- /// std::cout << val << ", ";
- /// });
- /// std::cout << "\n";
- ///
- /// // select all the numeric values until we encounter something non-numeric
- /// tbl.for_each([](auto&& val)
- /// {
- /// if constexpr (toml::is_number<decltype(val)>)
- /// {
- /// std::cout << val << ", ";
- /// return true; // "keep going"
- /// }
- /// else
- /// return false; // "stop!"
- ///
- /// });
- /// std::cout << "\n\n";
- ///
- /// // visitors may also recieve the key
- /// tbl.for_each([](const toml::key& key, auto&& val)
- /// {
- /// std::cout << key << ": " << val << "\n";
- /// });
- ///
- /// \ecpp
- /// \out
- /// 0, 1, 2, 6,
- /// 0, 1, 2, 3.0, 6,
- /// 0, 1, 2, 3.0,
- ///
- /// 0: 0
- /// 1: 1
- /// 2: 2
- /// 3: 3.0
- /// 4: 'four'
- /// 5: 'five'
- /// 6: 6
- /// \eout
- ///
- /// \see node::visit()
- template <typename Func>
- table& for_each(Func&& visitor) & //
- noexcept(for_each_is_nothrow<Func&&, table&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), *this);
- return *this;
- }
-
- /// \brief Invokes a visitor on each key-value pair in the table (rvalue overload).
- template <typename Func>
- table&& for_each(Func&& visitor) && //
- noexcept(for_each_is_nothrow<Func&&, table&&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), static_cast<table&&>(*this));
- return static_cast<table&&>(*this);
- }
-
- /// \brief Invokes a visitor on each key-value pair in the table (const lvalue overload).
- template <typename Func>
- const table& for_each(Func&& visitor) const& //
- noexcept(for_each_is_nothrow<Func&&, const table&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), *this);
- return *this;
- }
-
- /// \brief Invokes a visitor on each key-value pair in the table (const rvalue overload).
- template <typename Func>
- const table&& for_each(Func&& visitor) const&& //
- noexcept(for_each_is_nothrow<Func&&, const table&&>::value)
- {
- do_for_each(static_cast<Func&&>(visitor), static_cast<const table&&>(*this));
- return static_cast<const table&&>(*this);
- }
-
- /// @}
-
- /// \name Size and Capacity
- /// @{
-
- /// \brief Returns true if the table is empty.
- TOML_PURE_INLINE_GETTER
- bool empty() const noexcept
- {
- return map_.empty();
- }
-
- /// \brief Returns the number of key-value pairs in the table.
- TOML_PURE_INLINE_GETTER
- size_t size() const noexcept
- {
- return map_.size();
- }
-
- /// @}
-
- /// \name Searching
- /// @{
-
- private:
- /// \cond
-
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- map_iterator get_lower_bound(std::string_view) noexcept;
-
- /// \endcond
-
- public:
- /// \brief Returns an iterator to the first key-value pair with key that is _not less_ than the given key.
- ///
- /// \returns An iterator to the first matching key-value pair, or #end().
- TOML_PURE_GETTER
- iterator lower_bound(std::string_view key) noexcept
- {
- return iterator{ get_lower_bound(key) };
- }
-
- /// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than the given key.
- ///
- /// \returns An iterator to the first matching key-value pair, or #end().
- TOML_PURE_GETTER
- const_iterator lower_bound(std::string_view key) const noexcept
- {
- return const_iterator{ const_cast<table&>(*this).get_lower_bound(key) };
- }
+ }
+ }
+
+ /// \endcond
+
+ public:
+ /// \brief Invokes a visitor on each key-value pair in the table.
+ ///
+ /// \tparam Func A callable type invocable with one of the following signatures:
+ /// <ul>
+ /// <li> `func(key, val)`
+ /// <li> `func(val)`
+ /// </ul>
+ /// Where:
+ /// <ul>
+ /// <li> `key` will recieve a const reference to a toml::key
+ /// <li> `val` will recieve the value as it's concrete type with cvref-qualifications
+ ///matching the table
+ /// </ul>
+ /// Visitors returning `bool` (or something convertible to `bool`) will cause iteration
+ ///to stop if they return `false`.
+ ///
+ /// \param visitor The visitor object.
+ ///
+ /// \returns A reference to the table.
+ ///
+ /// \details \cpp
+ /// toml::table tbl{
+ /// { "0", 0 },
+ /// { "1", 1 },
+ /// { "2", 2 },
+ /// { "3", 3.0 },
+ /// { "4", "four" },
+ /// { "5", "five" },
+ /// { "6", 6 }
+ /// };
+ ///
+ /// // select only the integers using a strongly-typed visitor
+ /// tbl.for_each([](toml::value<int64_t>& val)
+ /// {
+ /// std::cout << val << ", ";
+ /// });
+ /// std::cout << "\n";
+ ///
+ /// // select all the numeric values using a generic visitor + is_number<> metafunction
+ /// tbl.for_each([](auto&& val)
+ /// {
+ /// if constexpr (toml::is_number<decltype(val)>)
+ /// std::cout << val << ", ";
+ /// });
+ /// std::cout << "\n";
+ ///
+ /// // select all the numeric values until we encounter something non-numeric
+ /// tbl.for_each([](auto&& val)
+ /// {
+ /// if constexpr (toml::is_number<decltype(val)>)
+ /// {
+ /// std::cout << val << ", ";
+ /// return true; // "keep going"
+ /// }
+ /// else
+ /// return false; // "stop!"
+ ///
+ /// });
+ /// std::cout << "\n\n";
+ ///
+ /// // visitors may also recieve the key
+ /// tbl.for_each([](const toml::key& key, auto&& val)
+ /// {
+ /// std::cout << key << ": " << val << "\n";
+ /// });
+ ///
+ /// \ecpp
+ /// \out
+ /// 0, 1, 2, 6,
+ /// 0, 1, 2, 3.0, 6,
+ /// 0, 1, 2, 3.0,
+ ///
+ /// 0: 0
+ /// 1: 1
+ /// 2: 2
+ /// 3: 3.0
+ /// 4: 'four'
+ /// 5: 'five'
+ /// 6: 6
+ /// \eout
+ ///
+ /// \see node::visit()
+ template <typename Func>
+ table& for_each(Func&& visitor) & //
+ noexcept(for_each_is_nothrow<Func&&, table&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), *this);
+ return *this;
+ }
+
+ /// \brief Invokes a visitor on each key-value pair in the table (rvalue overload).
+ template <typename Func>
+ table&& for_each(Func&& visitor) && //
+ noexcept(for_each_is_nothrow<Func&&, table&&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), static_cast<table&&>(*this));
+ return static_cast<table&&>(*this);
+ }
+
+ /// \brief Invokes a visitor on each key-value pair in the table (const lvalue overload).
+ template <typename Func>
+ const table& for_each(Func&& visitor) const& //
+ noexcept(for_each_is_nothrow<Func&&, const table&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), *this);
+ return *this;
+ }
+
+ /// \brief Invokes a visitor on each key-value pair in the table (const rvalue overload).
+ template <typename Func>
+ const table&& for_each(Func&& visitor) const&& //
+ noexcept(for_each_is_nothrow<Func&&, const table&&>::value) {
+ do_for_each(static_cast<Func&&>(visitor), static_cast<const table&&>(*this));
+ return static_cast<const table&&>(*this);
+ }
+
+ /// @}
+
+ /// \name Size and Capacity
+ /// @{
+
+ /// \brief Returns true if the table is empty.
+ TOML_PURE_INLINE_GETTER
+ bool empty() const noexcept { return map_.empty(); }
+
+ /// \brief Returns the number of key-value pairs in the table.
+ TOML_PURE_INLINE_GETTER
+ size_t size() const noexcept { return map_.size(); }
+
+ /// @}
+
+ /// \name Searching
+ /// @{
+
+ private:
+ /// \cond
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ map_iterator get_lower_bound(std::string_view) noexcept;
+
+ /// \endcond
+
+ public:
+ /// \brief Returns an iterator to the first key-value pair with key that is _not less_ than the
+ /// given key.
+ ///
+ /// \returns An iterator to the first matching key-value pair, or #end().
+ TOML_PURE_GETTER
+ iterator lower_bound(std::string_view key) noexcept { return iterator{get_lower_bound(key)}; }
+
+ /// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than
+ /// the given key.
+ ///
+ /// \returns An iterator to the first matching key-value pair, or #end().
+ TOML_PURE_GETTER
+ const_iterator lower_bound(std::string_view key) const noexcept {
+ return const_iterator{const_cast<table&>(*this).get_lower_bound(key)};
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Returns an iterator to the first key-value pair with key that is _not less_ than the given key.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \returns An iterator to the first matching key-value pair, or #end().
- TOML_NODISCARD
- iterator lower_bound(std::wstring_view key)
- {
- if (empty())
- return end();
-
- return lower_bound(impl::narrow(key));
- }
-
- /// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than the given key.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \returns An iterator to the first matching key-value pair, or #end().
- TOML_NODISCARD
- const_iterator lower_bound(std::wstring_view key) const
- {
- if (empty())
- return end();
-
- return lower_bound(impl::narrow(key));
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Gets an iterator to the node at a specific key.
- ///
- /// \param key The node's key.
- ///
- /// \returns An iterator to the node at the specified key, or end().
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- iterator find(std::string_view key) noexcept;
-
- /// \brief Gets an iterator to the node at a specific key (const overload)
- ///
- /// \param key The node's key.
- ///
- /// \returns A const iterator to the node at the specified key, or cend().
- TOML_PURE_GETTER
- TOML_EXPORTED_MEMBER_FUNCTION
- const_iterator find(std::string_view key) const noexcept;
-
- /// \brief Returns true if the table contains a node at the given key.
- TOML_PURE_GETTER
- bool contains(std::string_view key) const noexcept
- {
- return get(key) != nullptr;
- }
+ /// \brief Returns an iterator to the first key-value pair with key that is _not less_ than the
+ /// given key.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \returns An iterator to the first matching key-value pair, or #end().
+ TOML_NODISCARD
+ iterator lower_bound(std::wstring_view key) {
+ if (empty()) return end();
+
+ return lower_bound(impl::narrow(key));
+ }
+
+ /// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than
+ /// the given key.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \returns An iterator to the first matching key-value pair, or #end().
+ TOML_NODISCARD
+ const_iterator lower_bound(std::wstring_view key) const {
+ if (empty()) return end();
+
+ return lower_bound(impl::narrow(key));
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Gets an iterator to the node at a specific key.
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns An iterator to the node at the specified key, or end().
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ iterator find(std::string_view key) noexcept;
+
+ /// \brief Gets an iterator to the node at a specific key (const overload)
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A const iterator to the node at the specified key, or cend().
+ TOML_PURE_GETTER
+ TOML_EXPORTED_MEMBER_FUNCTION
+ const_iterator find(std::string_view key) const noexcept;
+
+ /// \brief Returns true if the table contains a node at the given key.
+ TOML_PURE_GETTER
+ bool contains(std::string_view key) const noexcept { return get(key) != nullptr; }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets an iterator to the node at a specific key.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The node's key.
- ///
- /// \returns An iterator to the node at the specified key, or end().
- TOML_NODISCARD
- iterator find(std::wstring_view key)
- {
- if (empty())
- return end();
-
- return find(impl::narrow(key));
- }
-
- /// \brief Gets an iterator to the node at a specific key (const overload).
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The node's key.
- ///
- /// \returns A const iterator to the node at the specified key, or cend().
- TOML_NODISCARD
- const_iterator find(std::wstring_view key) const
- {
- return find(impl::narrow(key));
- }
-
- /// \brief Returns true if the table contains a node at the given key.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- TOML_NODISCARD
- bool contains(std::wstring_view key) const
- {
- return contains(impl::narrow(key));
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// @}
-
- /// \name Erasure
- /// @{
-
- private:
- /// \cond
-
- TOML_EXPORTED_MEMBER_FUNCTION
- map_iterator erase(const_map_iterator) noexcept;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- map_iterator erase(const_map_iterator, const_map_iterator) noexcept;
-
- /// \endcond
-
- public:
- /// \brief Removes the specified key-value pair from the table.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// tbl.erase(tbl.begin() + 1);
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = 2, c = 3 }
- /// { a = 1, c = 3 }
- /// \eout
- ///
- /// \param pos Iterator to the key-value pair being erased.
- ///
- /// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
- iterator erase(iterator pos) noexcept
- {
- return iterator{ erase(const_map_iterator{ pos }) };
- }
-
- /// \brief Removes the specified key-value pair from the table (const iterator overload).
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// tbl.erase(tbl.cbegin() + 1);
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = 2, c = 3 }
- /// { a = 1, c = 3 }
- /// \eout
- ///
- /// \param pos Iterator to the key-value pair being erased.
- ///
- /// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
- iterator erase(const_iterator pos) noexcept
- {
- return iterator{ erase(const_map_iterator{ pos }) };
- }
-
- /// \brief Removes the key-value pairs in the range [first, last) from the table.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", "bad" },
- /// { "c", "karma" },
- /// { "d", 2 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// tbl.erase(tbl.cbegin() + 1, tbl.cbegin() + 3);
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = "bad", c = "karma", d = 2 }
- /// { a = 1, d = 2 }
- /// \eout
- ///
- /// \param begin Iterator to the first key-value pair being erased.
- /// \param end Iterator to the one-past-the-last key-value pair being erased.
- ///
- /// \returns Iterator to the first key-value pair immediately following the last removed key-value pair.
- iterator erase(const_iterator begin, const_iterator end) noexcept
- {
- return iterator{ erase(const_map_iterator{ begin }, const_map_iterator{ end }) };
- }
-
- /// \brief Removes the value with the given key from the table.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// std::cout << tbl.erase("b") << "\n";
- /// std::cout << tbl.erase("not an existing key") << "\n";
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = 2, c = 3 }
- /// true
- /// false
- /// { a = 1, c = 3 }
- /// \eout
- ///
- /// \param key Key to erase.
- ///
- /// \returns Number of elements removed (0 or 1).
- TOML_EXPORTED_MEMBER_FUNCTION
- size_t erase(std::string_view key) noexcept;
+ /// \brief Gets an iterator to the node at a specific key.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns An iterator to the node at the specified key, or end().
+ TOML_NODISCARD
+ iterator find(std::wstring_view key) {
+ if (empty()) return end();
+
+ return find(impl::narrow(key));
+ }
+
+ /// \brief Gets an iterator to the node at a specific key (const overload).
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The node's key.
+ ///
+ /// \returns A const iterator to the node at the specified key, or cend().
+ TOML_NODISCARD
+ const_iterator find(std::wstring_view key) const { return find(impl::narrow(key)); }
+
+ /// \brief Returns true if the table contains a node at the given key.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ TOML_NODISCARD
+ bool contains(std::wstring_view key) const { return contains(impl::narrow(key)); }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// @}
+
+ /// \name Erasure
+ /// @{
+
+ private:
+ /// \cond
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ map_iterator erase(const_map_iterator) noexcept;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ map_iterator erase(const_map_iterator, const_map_iterator) noexcept;
+
+ /// \endcond
+
+ public:
+ /// \brief Removes the specified key-value pair from the table.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// tbl.erase(tbl.begin() + 1);
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = 2, c = 3 }
+ /// { a = 1, c = 3 }
+ /// \eout
+ ///
+ /// \param pos Iterator to the key-value pair being erased.
+ ///
+ /// \returns Iterator to the first key-value pair immediately following the removed key-value
+ /// pair.
+ iterator erase(iterator pos) noexcept { return iterator{erase(const_map_iterator{pos})}; }
+
+ /// \brief Removes the specified key-value pair from the table (const iterator overload).
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// tbl.erase(tbl.cbegin() + 1);
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = 2, c = 3 }
+ /// { a = 1, c = 3 }
+ /// \eout
+ ///
+ /// \param pos Iterator to the key-value pair being erased.
+ ///
+ /// \returns Iterator to the first key-value pair immediately following the removed key-value
+ /// pair.
+ iterator erase(const_iterator pos) noexcept { return iterator{erase(const_map_iterator{pos})}; }
+
+ /// \brief Removes the key-value pairs in the range [first, last) from the table.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", "bad" },
+ /// { "c", "karma" },
+ /// { "d", 2 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// tbl.erase(tbl.cbegin() + 1, tbl.cbegin() + 3);
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = "bad", c = "karma", d = 2 }
+ /// { a = 1, d = 2 }
+ /// \eout
+ ///
+ /// \param begin Iterator to the first key-value pair being erased.
+ /// \param end Iterator to the one-past-the-last key-value pair being erased.
+ ///
+ /// \returns Iterator to the first key-value pair immediately following the last removed
+ /// key-value pair.
+ iterator erase(const_iterator begin, const_iterator end) noexcept {
+ return iterator{erase(const_map_iterator{begin}, const_map_iterator{end})};
+ }
+
+ /// \brief Removes the value with the given key from the table.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// std::cout << tbl.erase("b") << "\n";
+ /// std::cout << tbl.erase("not an existing key") << "\n";
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = 2, c = 3 }
+ /// true
+ /// false
+ /// { a = 1, c = 3 }
+ /// \eout
+ ///
+ /// \param key Key to erase.
+ ///
+ /// \returns Number of elements removed (0 or 1).
+ TOML_EXPORTED_MEMBER_FUNCTION
+ size_t erase(std::string_view key) noexcept;
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Removes the value with the given key from the table.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key Key to erase.
- ///
- /// \returns Number of elements removed (0 or 1).
- size_t erase(std::wstring_view key)
- {
- if (empty())
- return false;
-
- return erase(impl::narrow(key));
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// \brief Removes empty child arrays and tables.
- ///
- /// \detail \cpp
- ///
- /// auto tbl = toml::table{ { "a", 1 }, { "b", toml::array{ } }, { "c", toml::array{ toml::table{}, toml::array{} } } };
- /// std::cout << arr << "\n";
- ///
- /// arr.prune();
- /// std::cout << arr << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = [], c = [ {}, [] ] }
- /// { a = 1 }
- /// \eout
- ///
- /// \param recursive Should child arrays and tables themselves be pruned?
- ///
- /// \returns A reference to the table.
- TOML_EXPORTED_MEMBER_FUNCTION
- table& prune(bool recursive = true) & noexcept;
-
- /// \brief Removes empty child arrays and tables (rvalue overload).
- ///
- /// \param recursive Should child arrays and tables themselves be pruned?
- ///
- /// \returns An rvalue reference to the table.
- table&& prune(bool recursive = true) && noexcept
- {
- return static_cast<toml::table&&>(this->prune(recursive));
- }
-
- /// \brief Removes all key-value pairs from the table.
- TOML_EXPORTED_MEMBER_FUNCTION
- void clear() noexcept;
-
- /// @}
-
- /// \name Insertion and Emplacement
- /// @{
-
- private:
- /// \cond
-
- TOML_EXPORTED_MEMBER_FUNCTION
- map_iterator insert_with_hint(const_iterator, key&&, impl::node_ptr&&);
-
- /// \endcond
-
- public:
- /// \brief Emplaces a new value at a specific key if one did not already exist.
- ///
- /// \tparam ValueType toml::table, toml::array, or any native TOML value type.
- /// \tparam KeyType A toml::key or any compatible string type.
- /// \tparam ValueArgs Value constructor argument types.
- /// \param hint Iterator to the position before which the new element will be emplaced.
- /// \param key The key at which to emplace the new value.
- /// \param args Arguments to forward to the value's constructor.
- ///
- /// \returns An iterator to the emplacement position (or the position of the value that prevented emplacement)
- ///
- /// \note This function has exactly the same semantics as [std::map::emplace_hint()](https://en.cppreference.com/w/cpp/container/map/emplace_hint).
- TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
- typename ValueType = void,
- typename KeyType,
- typename... ValueArgs)
- iterator emplace_hint(const_iterator hint, KeyType&& key, ValueArgs&&... args)
- {
- static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
- "Emplacement using wide-character keys is only supported on Windows with "
- "TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- using raw_value_type = impl::remove_cvref<ValueType>;
- using value_type = std::
- conditional_t<std::is_void_v<raw_value_type>, impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
-
- if constexpr (impl::is_wide_string<KeyType>)
- {
+ /// \brief Removes the value with the given key from the table.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key Key to erase.
+ ///
+ /// \returns Number of elements removed (0 or 1).
+ size_t erase(std::wstring_view key) {
+ if (empty()) return false;
+
+ return erase(impl::narrow(key));
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// \brief Removes empty child arrays and tables.
+ ///
+ /// \detail \cpp
+ ///
+ /// auto tbl = toml::table{ { "a", 1 }, { "b", toml::array{ } }, { "c", toml::array{
+ /// toml::table{}, toml::array{} } } }; std::cout << arr << "\n";
+ ///
+ /// arr.prune();
+ /// std::cout << arr << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = [], c = [ {}, [] ] }
+ /// { a = 1 }
+ /// \eout
+ ///
+ /// \param recursive Should child arrays and tables themselves be pruned?
+ ///
+ /// \returns A reference to the table.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ table& prune(bool recursive = true) & noexcept;
+
+ /// \brief Removes empty child arrays and tables (rvalue overload).
+ ///
+ /// \param recursive Should child arrays and tables themselves be pruned?
+ ///
+ /// \returns An rvalue reference to the table.
+ table&& prune(bool recursive = true) && noexcept {
+ return static_cast<toml::table&&>(this->prune(recursive));
+ }
+
+ /// \brief Removes all key-value pairs from the table.
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void clear() noexcept;
+
+ /// @}
+
+ /// \name Insertion and Emplacement
+ /// @{
+
+ private:
+ /// \cond
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ map_iterator insert_with_hint(const_iterator, key&&, impl::node_ptr&&);
+
+ /// \endcond
+
+ public:
+ /// \brief Emplaces a new value at a specific key if one did not already exist.
+ ///
+ /// \tparam ValueType toml::table, toml::array, or any native TOML value type.
+ /// \tparam KeyType A toml::key or any compatible string type.
+ /// \tparam ValueArgs Value constructor argument types.
+ /// \param hint Iterator to the position before which the new element will be emplaced.
+ /// \param key The key at which to emplace the new value.
+ /// \param args Arguments to forward to the value's constructor.
+ ///
+ /// \returns An iterator to the emplacement position (or the position of the value that
+ /// prevented emplacement)
+ ///
+ /// \note This function has exactly the same semantics as
+ /// [std::map::emplace_hint()](https://en.cppreference.com/w/cpp/container/map/emplace_hint).
+ TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
+ typename ValueType = void, typename KeyType, typename... ValueArgs)
+ iterator emplace_hint(const_iterator hint, KeyType&& key, ValueArgs&&... args) {
+ static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Emplacement using wide-character keys is only supported on Windows with "
+ "TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ using raw_value_type = impl::remove_cvref<ValueType>;
+ using value_type = std::conditional_t<std::is_void_v<raw_value_type>,
+ impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
+
+ if constexpr (impl::is_wide_string<KeyType>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return emplace_hint<value_type>(hint,
- impl::narrow(static_cast<KeyType&&>(key)),
- static_cast<ValueArgs&&>(args)...);
+ return emplace_hint<value_type>(hint, impl::narrow(static_cast<KeyType&&>(key)),
+ static_cast<ValueArgs&&>(args)...);
#else
- static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- static constexpr auto moving_node_ptr = std::is_same_v<value_type, impl::node_ptr> //
- && sizeof...(ValueArgs) == 1u //
- && impl::first_is_same<impl::node_ptr&&, ValueArgs&&...>;
- using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
-
- static_assert(moving_node_ptr //
- || impl::is_native<unwrapped_type> //
- || impl::is_one_of<unwrapped_type, table, array>, //
- "ValueType argument of table::emplace_hint() must be one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- map_iterator ipos = insert_with_hint(hint, toml::key{ static_cast<KeyType&&>(key) }, nullptr);
-
- // if second is nullptr then we successully claimed the key and inserted the empty sentinel,
- // so now we have to construct the actual value
- if (!ipos->second)
- {
- if constexpr (moving_node_ptr)
- ipos->second = std::move(static_cast<ValueArgs&&>(args)...);
- else
- {
+ } else {
+ static constexpr auto moving_node_ptr =
+ std::is_same_v<value_type, impl::node_ptr> //
+ && sizeof...(ValueArgs) == 1u //
+ && impl::first_is_same<impl::node_ptr&&, ValueArgs&&...>;
+ using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
+
+ static_assert(moving_node_ptr //
+ || impl::is_native<unwrapped_type> //
+ || impl::is_one_of<unwrapped_type, table, array>, //
+ "ValueType argument of table::emplace_hint() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ map_iterator ipos = insert_with_hint(hint, toml::key{static_cast<KeyType&&>(key)}, nullptr);
+
+ // if second is nullptr then we successully claimed the key and inserted the empty sentinel,
+ // so now we have to construct the actual value
+ if (!ipos->second) {
+ if constexpr (moving_node_ptr)
+ ipos->second = std::move(static_cast<ValueArgs&&>(args)...);
+ else {
#if TOML_COMPILER_HAS_EXCEPTIONS
- try
- {
+ try {
#endif
- ipos->second.reset(
- new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... });
+ ipos->second.reset(
+ new impl::wrap_node<unwrapped_type>{static_cast<ValueArgs&&>(args)...});
#if TOML_COMPILER_HAS_EXCEPTIONS
- }
- catch (...)
- {
- erase(const_map_iterator{ ipos }); // strong exception guarantee
- throw;
- }
+ } catch (...) {
+ erase(const_map_iterator{ipos}); // strong exception guarantee
+ throw;
+ }
#endif
- }
- }
- return iterator{ ipos };
- }
- }
-
- /// \brief Inserts a new value at a specific key if one did not already exist.
- ///
- /// \detail \godbolt{bMnW5r}
- ///
- /// \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// for (auto k : { "a", "d" })
- /// {
- /// auto result = tbl.insert(k, 42);
- /// std::cout << "inserted with key '"sv << k << "': "sv << result.second << "\n";
- /// }
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// a = 1
- /// b = 2
- /// c = 3
- ///
- /// inserted with key 'a': false
- /// inserted with key 'd': true
- /// a = 1
- /// b = 2
- /// c = 3
- /// d = 42
- /// \eout
- ///
- /// \tparam KeyType A toml::key or any compatible string type.
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// <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>
- /// \conditional_return{Input is a null toml::node_view}
- /// `{ end(), false }`
- ///
- /// \attention The return value will always be `{ end(), false }` if the input value was an
- /// null toml::node_view, because no insertion can take place. This is the only circumstance
- /// in which this can occur.
- TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
- typename KeyType,
- typename ValueType)
- std::pair<iterator, bool> insert(KeyType&& key,
- ValueType&& val,
- value_flags flags = preserve_source_value_flags)
- {
- static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
- "Insertion using wide-character keys is only supported on Windows with "
- "TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (is_node_view<ValueType>)
- {
- if (!val)
- return { end(), false };
- }
-
- if constexpr (impl::is_wide_string<KeyType>)
- {
+ }
+ }
+ return iterator{ipos};
+ }
+ }
+
+ /// \brief Inserts a new value at a specific key if one did not already exist.
+ ///
+ /// \detail \godbolt{bMnW5r}
+ ///
+ /// \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// for (auto k : { "a", "d" })
+ /// {
+ /// auto result = tbl.insert(k, 42);
+ /// std::cout << "inserted with key '"sv << k << "': "sv << result.second << "\n";
+ /// }
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ ///
+ /// inserted with key 'a': false
+ /// inserted with key 'd': true
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ /// d = 42
+ /// \eout
+ ///
+ /// \tparam KeyType A toml::key or any compatible string type.
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// <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>
+ /// \conditional_return{Input is a null toml::node_view}
+ /// `{ end(), false }`
+ ///
+ /// \attention The return value will always be `{ end(), false }` if the input value was an
+ /// null toml::node_view, because no insertion can take place. This is the only
+ /// circumstance in which this can occur.
+ TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
+ typename KeyType, typename ValueType)
+ std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val,
+ value_flags flags = preserve_source_value_flags) {
+ static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Insertion using wide-character keys is only supported on Windows with "
+ "TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (is_node_view<ValueType>) {
+ if (!val) return {end(), false};
+ }
+
+ if constexpr (impl::is_wide_string<KeyType>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return insert(impl::narrow(static_cast<KeyType&&>(key)), static_cast<ValueType&&>(val), flags);
+ return insert(impl::narrow(static_cast<KeyType&&>(key)), static_cast<ValueType&&>(val),
+ flags);
#else
- static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- const auto key_view = std::string_view{ key };
- map_iterator ipos = get_lower_bound(key_view);
- if (ipos == map_.end() || ipos->first != key_view)
- {
- ipos = insert_with_hint(const_iterator{ ipos },
- toml::key{ static_cast<KeyType&&>(key) },
- impl::make_node(static_cast<ValueType&&>(val), flags));
- return { iterator{ ipos }, true };
- }
- return { iterator{ ipos }, false };
- }
- }
-
- /// \brief Inserts a series of key-value pairs into the table.
- ///
- /// \detail \godbolt{bzYcce}
- ///
- /// \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// auto kvps = std::array<std::pair<std::string, int>, 2>{{
- /// { "d", 42 },
- /// { "a", 43 } // won't be inserted, 'a' already exists
- /// }};
- /// tbl.insert(kvps.begin(), kvps.end());
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// a = 1
- /// b = 2
- /// c = 3
- ///
- /// a = 1
- /// b = 2
- /// c = 3
- /// d = 42
- /// \eout
- ///
- /// \tparam Iter An InputIterator to a collection of key-value pairs.
- /// \param begin An iterator to the first value in the input collection.
- /// \param end An iterator to one-past-the-last value in the input collection.
- /// \param flags Value flags to apply to new values.
- ///
- /// \remarks This function is morally equivalent to calling `insert(key, value)` for each
- /// key-value pair covered by the iterator range, so any values with keys already found in the
- /// table will not be replaced.
- TOML_CONSTRAINED_TEMPLATE((!is_key_or_convertible<Iter> && !impl::is_wide_string<Iter>), typename Iter)
- void insert(Iter begin, Iter end, value_flags flags = preserve_source_value_flags)
- {
- if (begin == end)
- return;
- for (auto it = begin; it != end; it++)
- {
- if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
- insert(std::move((*it).first), std::move((*it).second), flags);
- else
- insert((*it).first, (*it).second, flags);
- }
- }
-
- /// \brief Inserts or assigns a value at a specific key.
- ///
- /// \detail \godbolt{ddK563}
- ///
- /// \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// for (auto k : { "a", "d" })
- /// {
- /// auto result = tbl.insert_or_assign(k, 42);
- /// std::cout << "value at key '"sv << k
- /// << "' was "sv << (result.second ? "inserted"sv : "assigned"sv) << "\n";
- /// }
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// a = 1
- /// b = 2
- /// c = 3
- ///
- /// value at key 'a' was assigned
- /// value at key 'd' was inserted
- /// a = 42
- /// b = 2
- /// c = 3
- /// d = 42
- /// \eout
- ///
- /// \tparam KeyType A toml::key or any compatible string type.
- /// \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.
- /// \param flags Value flags to apply to new values.
- ///
- /// \returns \conditional_return{Valid input}
- /// <ul>
- /// <li>An iterator to the value's position
- /// <li>`true` if the value was inserted, `false` if it was assigned.
- /// </ul>
- /// \conditional_return{Input is a null toml::node_view}
- /// `{ end(), false }`
- ///
- /// \attention The return value will always be `{ end(), false }` if the input value was
- /// a null toml::node_view, because no insertion or assignment can take place.
- /// This is the only circumstance in which this can occur.
- TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
- typename KeyType,
- typename ValueType)
- std::pair<iterator, bool> insert_or_assign(KeyType&& key,
- ValueType&& val,
- value_flags flags = preserve_source_value_flags)
- {
- static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
- "Insertion using wide-character keys is only supported on Windows with "
- "TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (is_node_view<ValueType>)
- {
- if (!val)
- return { end(), false };
- }
-
- if constexpr (impl::is_wide_string<KeyType>)
- {
+ } else {
+ const auto key_view = std::string_view{key};
+ map_iterator ipos = get_lower_bound(key_view);
+ if (ipos == map_.end() || ipos->first != key_view) {
+ ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
+ impl::make_node(static_cast<ValueType&&>(val), flags));
+ return {iterator{ipos}, true};
+ }
+ return {iterator{ipos}, false};
+ }
+ }
+
+ /// \brief Inserts a series of key-value pairs into the table.
+ ///
+ /// \detail \godbolt{bzYcce}
+ ///
+ /// \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// auto kvps = std::array<std::pair<std::string, int>, 2>{{
+ /// { "d", 42 },
+ /// { "a", 43 } // won't be inserted, 'a' already exists
+ /// }};
+ /// tbl.insert(kvps.begin(), kvps.end());
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ ///
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ /// d = 42
+ /// \eout
+ ///
+ /// \tparam Iter An InputIterator to a collection of key-value pairs.
+ /// \param begin An iterator to the first value in the input collection.
+ /// \param end An iterator to one-past-the-last value in the input collection.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \remarks This function is morally equivalent to calling `insert(key, value)` for each
+ /// key-value pair covered by the iterator range, so any values with keys already found in
+ /// the table will not be replaced.
+ TOML_CONSTRAINED_TEMPLATE((!is_key_or_convertible<Iter> && !impl::is_wide_string<Iter>),
+ typename Iter)
+ void insert(Iter begin, Iter end, value_flags flags = preserve_source_value_flags) {
+ if (begin == end) return;
+ for (auto it = begin; it != end; it++) {
+ if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
+ insert(std::move((*it).first), std::move((*it).second), flags);
+ else
+ insert((*it).first, (*it).second, flags);
+ }
+ }
+
+ /// \brief Inserts or assigns a value at a specific key.
+ ///
+ /// \detail \godbolt{ddK563}
+ ///
+ /// \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// for (auto k : { "a", "d" })
+ /// {
+ /// auto result = tbl.insert_or_assign(k, 42);
+ /// std::cout << "value at key '"sv << k
+ /// << "' was "sv << (result.second ? "inserted"sv : "assigned"sv) << "\n";
+ /// }
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// a = 1
+ /// b = 2
+ /// c = 3
+ ///
+ /// value at key 'a' was assigned
+ /// value at key 'd' was inserted
+ /// a = 42
+ /// b = 2
+ /// c = 3
+ /// d = 42
+ /// \eout
+ ///
+ /// \tparam KeyType A toml::key or any compatible string type.
+ /// \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.
+ /// \param flags Value flags to apply to new values.
+ ///
+ /// \returns \conditional_return{Valid input}
+ /// <ul>
+ /// <li>An iterator to the value's position
+ /// <li>`true` if the value was inserted, `false` if it was assigned.
+ /// </ul>
+ /// \conditional_return{Input is a null toml::node_view}
+ /// `{ end(), false }`
+ ///
+ /// \attention The return value will always be `{ end(), false }` if the input value was
+ /// a null toml::node_view, because no insertion or assignment can take place.
+ /// This is the only circumstance in which this can occur.
+ TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
+ typename KeyType, typename ValueType)
+ std::pair<iterator, bool> insert_or_assign(KeyType&& key, ValueType&& val,
+ value_flags flags = preserve_source_value_flags) {
+ static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Insertion using wide-character keys is only supported on Windows with "
+ "TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (is_node_view<ValueType>) {
+ if (!val) return {end(), false};
+ }
+
+ if constexpr (impl::is_wide_string<KeyType>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return insert_or_assign(impl::narrow(static_cast<KeyType&&>(key)),
- static_cast<ValueType&&>(val),
- flags);
+ return insert_or_assign(impl::narrow(static_cast<KeyType&&>(key)),
+ static_cast<ValueType&&>(val), flags);
#else
- static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- const auto key_view = std::string_view{ key };
- map_iterator ipos = get_lower_bound(key_view);
- if (ipos == map_.end() || ipos->first != key_view)
- {
- ipos = insert_with_hint(const_iterator{ ipos },
- toml::key{ static_cast<KeyType&&>(key) },
- impl::make_node(static_cast<ValueType&&>(val), flags));
- return { iterator{ ipos }, true };
- }
- else
- {
- (*ipos).second = impl::make_node(static_cast<ValueType&&>(val), flags);
- return { iterator{ ipos }, false };
- }
- }
- }
-
- /// \brief Emplaces a new value at a specific key if one did not already exist.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "a", 1 },
- /// { "b", 2 },
- /// { "c", 3 }
- /// };
- /// std::cout << tbl << "\n";
- ///
- /// for (auto k : { "a", "d" })
- /// {
- /// // add a string using std::string's substring constructor
- /// auto result = tbl.emplace<std::string>(k, "this is not a drill"sv, 14, 5);
- /// std::cout << "emplaced with key '"sv << k << "': "sv << result.second << "\n";
- /// }
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// { a = 1, b = 2, c = 3 }
- /// emplaced with key 'a': false
- /// emplaced with key 'd': true
- /// { a = 1, b = 2, c = 3, d = "drill" }
- /// \eout
- ///
- /// \tparam ValueType toml::table, toml::array, or any native TOML value type.
- /// \tparam KeyType A toml::key or any compatible string type.
- /// \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: <br>
- /// - An iterator to the emplacement position (or the position of the value that prevented emplacement)
- /// - A boolean indicating if the emplacement was successful.
- ///
- /// \remark There is no difference between insert() and emplace() for trivial value types (floats, ints, bools).
- TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
- typename ValueType = void,
- typename KeyType,
- typename... ValueArgs)
- std::pair<iterator, bool> emplace(KeyType&& key, ValueArgs&&... args)
- {
- static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
- "Emplacement using wide-character keys is only supported on Windows with "
- "TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- using raw_value_type = impl::remove_cvref<ValueType>;
- using value_type = std::
- conditional_t<std::is_void_v<raw_value_type>, impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
-
- if constexpr (impl::is_wide_string<KeyType>)
- {
+ } else {
+ const auto key_view = std::string_view{key};
+ map_iterator ipos = get_lower_bound(key_view);
+ if (ipos == map_.end() || ipos->first != key_view) {
+ ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
+ impl::make_node(static_cast<ValueType&&>(val), flags));
+ return {iterator{ipos}, true};
+ } else {
+ (*ipos).second = impl::make_node(static_cast<ValueType&&>(val), flags);
+ return {iterator{ipos}, false};
+ }
+ }
+ }
+
+ /// \brief Emplaces a new value at a specific key if one did not already exist.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "a", 1 },
+ /// { "b", 2 },
+ /// { "c", 3 }
+ /// };
+ /// std::cout << tbl << "\n";
+ ///
+ /// for (auto k : { "a", "d" })
+ /// {
+ /// // add a string using std::string's substring constructor
+ /// auto result = tbl.emplace<std::string>(k, "this is not a drill"sv, 14, 5);
+ /// std::cout << "emplaced with key '"sv << k << "': "sv << result.second << "\n";
+ /// }
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// { a = 1, b = 2, c = 3 }
+ /// emplaced with key 'a': false
+ /// emplaced with key 'd': true
+ /// { a = 1, b = 2, c = 3, d = "drill" }
+ /// \eout
+ ///
+ /// \tparam ValueType toml::table, toml::array, or any native TOML value type.
+ /// \tparam KeyType A toml::key or any compatible string type.
+ /// \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: <br>
+ /// - An iterator to the emplacement position (or the position of the value that prevented
+ /// emplacement)
+ /// - A boolean indicating if the emplacement was successful.
+ ///
+ /// \remark There is no difference between insert() and emplace() for trivial value types
+ /// (floats, ints, bools).
+ TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
+ typename ValueType = void, typename KeyType, typename... ValueArgs)
+ std::pair<iterator, bool> emplace(KeyType&& key, ValueArgs&&... args) {
+ static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Emplacement using wide-character keys is only supported on Windows with "
+ "TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ using raw_value_type = impl::remove_cvref<ValueType>;
+ using value_type = std::conditional_t<std::is_void_v<raw_value_type>,
+ impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
+
+ if constexpr (impl::is_wide_string<KeyType>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return emplace<value_type>(impl::narrow(static_cast<KeyType&&>(key)),
- static_cast<ValueArgs&&>(args)...);
+ return emplace<value_type>(impl::narrow(static_cast<KeyType&&>(key)),
+ static_cast<ValueArgs&&>(args)...);
#else
- static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
+ static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
- static_assert((impl::is_native<unwrapped_type> || impl::is_one_of<unwrapped_type, table, array>),
- "ValueType argument of table::emplace() must be one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- const auto key_view = std::string_view{ key };
- auto ipos = get_lower_bound(key_view);
- if (ipos == map_.end() || ipos->first != key_view)
- {
- ipos = insert_with_hint(
- const_iterator{ ipos },
- toml::key{ static_cast<KeyType&&>(key) },
- impl::node_ptr{ new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... } });
- return { iterator{ ipos }, true };
- }
- return { iterator{ ipos }, false };
- }
- }
-
- /// @}
-
- /// \name Node views
- /// @{
-
- /// \cond
- using node::operator[]; // inherit operator[toml::path]
- /// \endcond
-
- /// \brief Gets a node_view for the selected value.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if one existed, or an empty node view.
- ///
- /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
- /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
- /// <strong>This is not an error.</strong>
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<node> operator[](std::string_view key) noexcept
- {
- return node_view<node>{ get(key) };
- }
-
- /// \brief Gets a node_view for the selected value (const overload).
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if one existed, or an empty node view.
- ///
- /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
- /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
- /// <strong>This is not an error.</strong>
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<const node> operator[](std::string_view key) const noexcept
- {
- return node_view<const node>{ get(key) };
- }
+ } else {
+ using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
+ static_assert(
+ (impl::is_native<unwrapped_type> || impl::is_one_of<unwrapped_type, table, array>),
+ "ValueType argument of table::emplace() must be one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ const auto key_view = std::string_view{key};
+ auto ipos = get_lower_bound(key_view);
+ if (ipos == map_.end() || ipos->first != key_view) {
+ ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
+ impl::node_ptr{new impl::wrap_node<unwrapped_type>{
+ static_cast<ValueArgs&&>(args)...}});
+ return {iterator{ipos}, true};
+ }
+ return {iterator{ipos}, false};
+ }
+ }
+
+ /// @}
+
+ /// \name Node views
+ /// @{
+
+ /// \cond
+ using node::operator[]; // inherit operator[toml::path]
+ /// \endcond
+
+ /// \brief Gets a node_view for the selected value.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if one existed, or an empty node view.
+ ///
+ /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
+ /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
+ /// <strong>This is not an error.</strong>
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<node> operator[](std::string_view key) noexcept { return node_view<node>{get(key)}; }
+
+ /// \brief Gets a node_view for the selected value (const overload).
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if one existed, or an empty node view.
+ ///
+ /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
+ /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
+ /// <strong>This is not an error.</strong>
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<const node> operator[](std::string_view key) const noexcept {
+ return node_view<const node>{get(key)};
+ }
#if TOML_ENABLE_WINDOWS_COMPAT
- /// \brief Gets a node_view for the selected value.
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if one existed, or an empty node view.
- ///
- /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
- /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
- /// <strong>This is not an error.</strong>
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<node> operator[](std::wstring_view key)
- {
- return node_view<node>{ get(key) };
- }
-
- /// \brief Gets a node_view for the selected value (const overload).
- ///
- /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
- ///
- /// \param key The key used for the lookup.
- ///
- /// \returns A view of the value at the given key if one existed, or an empty node view.
- ///
- /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
- /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
- /// <strong>This is not an error.</strong>
- ///
- /// \see toml::node_view
- TOML_NODISCARD
- node_view<const node> operator[](std::wstring_view key) const
- {
- return node_view<const node>{ get(key) };
- }
-
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
- /// @}
-
- /// \name Equality
- /// @{
-
- private:
- /// \cond
-
- TOML_PURE_GETTER
- TOML_EXPORTED_STATIC_FUNCTION
- static bool TOML_CALLCONV equal(const table&, const table&) noexcept;
-
- /// \endcond
- public:
- /// \brief Equality operator.
- ///
- /// \param lhs The LHS table.
- /// \param rhs The RHS table.
- ///
- /// \returns True if the tables contained the same keys and map.
- TOML_NODISCARD
- friend bool operator==(const table& lhs, const table& rhs) noexcept
- {
- return equal(lhs, rhs);
- }
-
- /// \brief Inequality operator.
- ///
- /// \param lhs The LHS table.
- /// \param rhs The RHS table.
- ///
- /// \returns True if the tables did not contain the same keys and map.
- TOML_NODISCARD
- friend bool operator!=(const table& lhs, const table& rhs) noexcept
- {
- return !equal(lhs, rhs);
- }
-
- /// @}
+ /// \brief Gets a node_view for the selected value.
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if one existed, or an empty node view.
+ ///
+ /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
+ /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
+ /// <strong>This is not an error.</strong>
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<node> operator[](std::wstring_view key) { return node_view<node>{get(key)}; }
+
+ /// \brief Gets a node_view for the selected value (const overload).
+ ///
+ /// \availability This overload is only available when #TOML_ENABLE_WINDOWS_COMPAT is enabled.
+ ///
+ /// \param key The key used for the lookup.
+ ///
+ /// \returns A view of the value at the given key if one existed, or an empty node view.
+ ///
+ /// \remarks std::map::operator[]'s behaviour of default-constructing a value at a key if it
+ /// didn't exist is a crazy bug factory so I've deliberately chosen not to emulate it.
+ /// <strong>This is not an error.</strong>
+ ///
+ /// \see toml::node_view
+ TOML_NODISCARD
+ node_view<const node> operator[](std::wstring_view key) const {
+ return node_view<const node>{get(key)};
+ }
+
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+ /// @}
+
+ /// \name Equality
+ /// @{
+
+ private:
+ /// \cond
+
+ TOML_PURE_GETTER
+ TOML_EXPORTED_STATIC_FUNCTION
+ static bool TOML_CALLCONV equal(const table&, const table&) noexcept;
+
+ /// \endcond
+ public:
+ /// \brief Equality operator.
+ ///
+ /// \param lhs The LHS table.
+ /// \param rhs The RHS table.
+ ///
+ /// \returns True if the tables contained the same keys and map.
+ TOML_NODISCARD
+ friend bool operator==(const table& lhs, const table& rhs) noexcept { return equal(lhs, rhs); }
+
+ /// \brief Inequality operator.
+ ///
+ /// \param lhs The LHS table.
+ /// \param rhs The RHS table.
+ ///
+ /// \returns True if the tables did not contain the same keys and map.
+ TOML_NODISCARD
+ friend bool operator!=(const table& lhs, const table& rhs) noexcept { return !equal(lhs, rhs); }
+
+ /// @}
#if TOML_ENABLE_FORMATTERS
- /// \brief Prints the table out to a stream as formatted TOML.
- ///
- /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
- friend std::ostream& operator<<(std::ostream& lhs, const table& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
+ /// \brief Prints the table out to a stream as formatted TOML.
+ ///
+ /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ friend std::ostream& operator<<(std::ostream& lhs, const table& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
#endif
- };
+ };
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/toml_formatter.hpp b/vendor/toml++/impl/toml_formatter.hpp
index ffd6325..d307277 100644
--- a/vendor/toml++/impl/toml_formatter.hpp
+++ b/vendor/toml++/impl/toml_formatter.hpp
@@ -1,153 +1,149 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
#if TOML_ENABLE_FORMATTERS
-#include "std_vector.hpp"
#include "formatter.hpp"
#include "header_start.hpp"
+#include "std_vector.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A wrapper for printing TOML objects out to a stream as formatted TOML.
- ///
- /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
- ///
- /// \remarks You generally don't need to create an instance of this class explicitly; the stream
- /// operators of the TOML node types already print themselves out using this formatter.
- ///
- /// \detail \cpp
- /// auto tbl = toml::table{
- /// { "description", "This is some TOML, yo." },
- /// { "fruit", toml::array{ "apple", "orange", "pear" } },
- /// { "numbers", toml::array{ 1, 2, 3, 4, 5 } },
- /// { "table", toml::table{ { "foo", "bar" } } }
- /// };
- ///
- /// // these two lines are equivalent:
- /// std::cout << toml::toml_formatter{ tbl } << "\n";
- /// std::cout << tbl << "\n";
- /// \ecpp
- ///
- /// \out
- /// description = "This is some TOML, yo."
- /// fruit = ["apple", "orange", "pear"]
- /// numbers = [1, 2, 3, 4, 5]
- ///
- /// [table]
- /// foo = "bar"
- /// \eout
- class TOML_EXPORTED_CLASS toml_formatter : impl::formatter
- {
- private:
- /// \cond
-
- using base = impl::formatter;
- std::vector<const key*> key_path_;
- bool pending_table_separator_ = false;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_pending_table_separator();
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const key&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_inline(const toml::table&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::array&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::table&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print();
-
- static constexpr impl::formatter_constants constants = { format_flags::none, // mandatory
- format_flags::none, // ignored
- "inf"sv,
- "-inf"sv,
- "nan"sv,
- "true"sv,
- "false"sv };
-
- /// \endcond
-
- public:
- /// \brief The default flags for a toml_formatter.
- static constexpr format_flags default_flags = constants.mandatory_flags //
- | format_flags::allow_literal_strings //
- | format_flags::allow_multi_line_strings //
- | format_flags::allow_unicode_strings //
- | format_flags::allow_real_tabs_in_strings //
- | format_flags::allow_binary_integers //
- | format_flags::allow_octal_integers //
- | format_flags::allow_hexadecimal_integers //
- | format_flags::indentation;
-
- /// \brief Constructs a TOML formatter and binds it to a TOML object.
- ///
- /// \param source The source TOML object.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit toml_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
- : base{ &source, nullptr, constants, { flags, " "sv } }
- {}
+TOML_NAMESPACE_START {
+ /// \brief A wrapper for printing TOML objects out to a stream as formatted TOML.
+ ///
+ /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ ///
+ /// \remarks You generally don't need to create an instance of this class explicitly; the stream
+ /// operators of the TOML node types already print themselves out using this formatter.
+ ///
+ /// \detail \cpp
+ /// auto tbl = toml::table{
+ /// { "description", "This is some TOML, yo." },
+ /// { "fruit", toml::array{ "apple", "orange", "pear" } },
+ /// { "numbers", toml::array{ 1, 2, 3, 4, 5 } },
+ /// { "table", toml::table{ { "foo", "bar" } } }
+ /// };
+ ///
+ /// // these two lines are equivalent:
+ /// std::cout << toml::toml_formatter{ tbl } << "\n";
+ /// std::cout << tbl << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// description = "This is some TOML, yo."
+ /// fruit = ["apple", "orange", "pear"]
+ /// numbers = [1, 2, 3, 4, 5]
+ ///
+ /// [table]
+ /// foo = "bar"
+ /// \eout
+ class TOML_EXPORTED_CLASS toml_formatter : impl::formatter {
+ private:
+ /// \cond
+
+ using base = impl::formatter;
+ std::vector<const key*> key_path_;
+ bool pending_table_separator_ = false;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_pending_table_separator();
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const key&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_inline(const toml::table&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::array&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::table&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print();
+
+ static constexpr impl::formatter_constants constants = {format_flags::none, // mandatory
+ format_flags::none, // ignored
+ "inf"sv,
+ "-inf"sv,
+ "nan"sv,
+ "true"sv,
+ "false"sv};
+
+ /// \endcond
+
+ public:
+ /// \brief The default flags for a toml_formatter.
+ static constexpr format_flags default_flags = constants.mandatory_flags //
+ | format_flags::allow_literal_strings //
+ | format_flags::allow_multi_line_strings //
+ | format_flags::allow_unicode_strings //
+ | format_flags::allow_real_tabs_in_strings //
+ | format_flags::allow_binary_integers //
+ | format_flags::allow_octal_integers //
+ | format_flags::allow_hexadecimal_integers //
+ | format_flags::indentation;
+
+ /// \brief Constructs a TOML formatter and binds it to a TOML object.
+ ///
+ /// \param source The source TOML object.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit toml_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
+ : base{&source, nullptr, constants, {flags, " "sv}} {}
#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
- /// \brief Constructs a TOML formatter and binds it to a toml::parse_result.
- ///
- /// \availability This constructor is only available when exceptions are disabled.
- ///
- /// \attention Formatting a failed parse result will simply dump the error message out as-is.
- /// This will not be valid TOML, but at least gives you something to log or show up in diagnostics:
- /// \cpp
- /// std::cout << toml::toml_formatter{ toml::parse("a = 'b'"sv) } // ok
- /// << "\n\n"
- /// << toml::toml_formatter{ toml::parse("a = "sv) } // malformed
- /// << "\n";
- /// \ecpp
- /// \out
- /// a = 'b'
- ///
- /// Error while parsing key-value pair: encountered end-of-file
- /// (error occurred at line 1, column 5)
- /// \eout
- /// Use the library with exceptions if you want to avoid this scenario.
- ///
- /// \param result The parse result.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit toml_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
- : base{ nullptr, &result, constants, { flags, " "sv } }
- {}
+ /// \brief Constructs a TOML formatter and binds it to a toml::parse_result.
+ ///
+ /// \availability This constructor is only available when exceptions are disabled.
+ ///
+ /// \attention Formatting a failed parse result will simply dump the error message out as-is.
+ /// This will not be valid TOML, but at least gives you something to log or show up in
+ ///diagnostics:
+ /// \cpp
+ /// std::cout << toml::toml_formatter{ toml::parse("a = 'b'"sv) } // ok
+ /// << "\n\n"
+ /// << toml::toml_formatter{ toml::parse("a = "sv) } // malformed
+ /// << "\n";
+ /// \ecpp
+ /// \out
+ /// a = 'b'
+ ///
+ /// Error while parsing key-value pair: encountered end-of-file
+ /// (error occurred at line 1, column 5)
+ /// \eout
+ /// Use the library with exceptions if you want to avoid this scenario.
+ ///
+ /// \param result The parse result.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit toml_formatter(const toml::parse_result& result,
+ format_flags flags = default_flags) noexcept
+ : base{nullptr, &result, constants, {flags, " "sv}} {}
#endif
- /// \brief Prints the bound TOML object out to the stream as formatted TOML.
- friend std::ostream& operator<<(std::ostream& lhs, toml_formatter& rhs)
- {
- rhs.attach(lhs);
- rhs.key_path_.clear();
- rhs.print();
- rhs.detach();
- return lhs;
- }
-
- /// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
- friend std::ostream& operator<<(std::ostream& lhs, toml_formatter&& rhs)
- {
- return lhs << rhs; // as lvalue
- }
- };
+ /// \brief Prints the bound TOML object out to the stream as formatted TOML.
+ friend std::ostream& operator<<(std::ostream& lhs, toml_formatter& rhs) {
+ rhs.attach(lhs);
+ rhs.key_path_.clear();
+ rhs.print();
+ rhs.detach();
+ return lhs;
+ }
+
+ /// \brief Prints the bound TOML object out to the stream as formatted TOML (rvalue overload).
+ friend std::ostream& operator<<(std::ostream& lhs, toml_formatter&& rhs) {
+ return lhs << rhs; // as lvalue
+ }
+ };
}
TOML_NAMESPACE_END;
#include "header_end.hpp"
-#endif // TOML_ENABLE_FORMATTERS
+#endif // TOML_ENABLE_FORMATTERS
diff --git a/vendor/toml++/impl/unicode.hpp b/vendor/toml++/impl/unicode.hpp
index 9bad395..3b399c3 100644
--- a/vendor/toml++/impl/unicode.hpp
+++ b/vendor/toml++/impl/unicode.hpp
@@ -1,195 +1,164 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "unicode_autogenerated.hpp"
#include "header_start.hpp"
+#include "unicode_autogenerated.hpp"
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- TOML_CONST_GETTER
- constexpr bool is_string_delimiter(char32_t c) noexcept
- {
- return c == U'"' || c == U'\'';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_ascii_letter(char32_t c) noexcept
- {
- return (c >= U'a' && c <= U'z') || (c >= U'A' && c <= U'Z');
- }
-
- TOML_CONST_GETTER
- constexpr bool is_binary_digit(char32_t c) noexcept
- {
- return c == U'0' || c == U'1';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_octal_digit(char32_t c) noexcept
- {
- return (c >= U'0' && c <= U'7');
- }
-
- TOML_CONST_GETTER
- constexpr bool is_decimal_digit(char32_t c) noexcept
- {
- return (c >= U'0' && c <= U'9');
- }
-
- TOML_CONST_GETTER
- constexpr bool is_hexadecimal_digit(char32_t c) noexcept
- {
- return U'0' <= c && c <= U'f' && (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
- }
-
- template <typename T>
- TOML_CONST_GETTER
- constexpr uint_least32_t hex_to_dec(const T c) noexcept
- {
- if constexpr (std::is_same_v<remove_cvref<T>, uint_least32_t>)
- return c >= 0x41u // >= 'A'
- ? 10u + (c | 0x20u) - 0x61u // - 'a'
- : c - 0x30u // - '0'
- ;
- else
- return hex_to_dec(static_cast<uint_least32_t>(c));
- }
-
- TOML_CONST_GETTER
- constexpr bool is_horizontal_whitespace(char32_t c) noexcept
- {
- return is_ascii_horizontal_whitespace(c) || is_non_ascii_horizontal_whitespace(c);
- }
-
- TOML_CONST_GETTER
- constexpr bool is_vertical_whitespace(char32_t c) noexcept
- {
- return is_ascii_vertical_whitespace(c) || is_non_ascii_vertical_whitespace(c);
- }
-
- TOML_CONST_GETTER
- constexpr bool is_whitespace(char32_t c) noexcept
- {
- return is_horizontal_whitespace(c) || is_vertical_whitespace(c);
- }
-
- TOML_CONST_GETTER
- constexpr bool is_bare_key_character(char32_t c) noexcept
- {
- return is_ascii_bare_key_character(c)
-#if TOML_LANG_UNRELEASED // toml/pull/891 (unicode bare keys)
- || is_non_ascii_bare_key_character(c)
+TOML_IMPL_NAMESPACE_START {
+ TOML_CONST_GETTER
+ constexpr bool is_string_delimiter(char32_t c) noexcept {
+ return c == U'"' || c == U'\'';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_ascii_letter(char32_t c) noexcept {
+ return (c >= U'a' && c <= U'z') || (c >= U'A' && c <= U'Z');
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_binary_digit(char32_t c) noexcept {
+ return c == U'0' || c == U'1';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_octal_digit(char32_t c) noexcept {
+ return (c >= U'0' && c <= U'7');
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_decimal_digit(char32_t c) noexcept {
+ return (c >= U'0' && c <= U'9');
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_hexadecimal_digit(char32_t c) noexcept {
+ return U'0' <= c && c <= U'f' &&
+ (1ull << (static_cast<uint_least64_t>(c) - 0x30u)) & 0x7E0000007E03FFull;
+ }
+
+ template <typename T>
+ TOML_CONST_GETTER constexpr uint_least32_t hex_to_dec(const T c) noexcept {
+ if constexpr (std::is_same_v<remove_cvref<T>, uint_least32_t>)
+ return c >= 0x41u // >= 'A'
+ ? 10u + (c | 0x20u) - 0x61u // - 'a'
+ : c - 0x30u // - '0'
+ ;
+ else
+ return hex_to_dec(static_cast<uint_least32_t>(c));
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_horizontal_whitespace(char32_t c) noexcept {
+ return is_ascii_horizontal_whitespace(c) || is_non_ascii_horizontal_whitespace(c);
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_vertical_whitespace(char32_t c) noexcept {
+ return is_ascii_vertical_whitespace(c) || is_non_ascii_vertical_whitespace(c);
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_whitespace(char32_t c) noexcept {
+ return is_horizontal_whitespace(c) || is_vertical_whitespace(c);
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_bare_key_character(char32_t c) noexcept {
+ return is_ascii_bare_key_character(c)
+#if TOML_LANG_UNRELEASED // toml/pull/891 (unicode bare keys)
+ || is_non_ascii_bare_key_character(c)
#endif
- ;
- }
-
- TOML_CONST_GETTER
- constexpr bool is_value_terminator(char32_t c) noexcept
- {
- return is_whitespace(c) || c == U']' || c == U'}' || c == U',' || c == U'#';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_control_character(char c) noexcept
- {
- return c <= '\u001F' || c == '\u007F';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_control_character(char32_t c) noexcept
- {
- return c <= U'\u001F' || c == U'\u007F';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_nontab_control_character(char32_t c) noexcept
- {
- return c <= U'\u0008' || (c >= U'\u000A' && c <= U'\u001F') || c == U'\u007F';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_unicode_surrogate(char32_t c) noexcept
- {
- return c >= 0xD800u && c <= 0xDFFF;
- }
-
- struct utf8_decoder
- {
- // utf8_decoder based on this: https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
- // Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-
- uint_least32_t state{};
- char32_t codepoint{};
-
- static constexpr uint8_t state_table[]{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6,
- 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-
- 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 12,
- 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, 12,
- 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
- };
-
- TOML_PURE_INLINE_GETTER
- constexpr bool error() const noexcept
- {
- return state == uint_least32_t{ 12u };
- }
-
- TOML_PURE_INLINE_GETTER
- constexpr bool has_code_point() const noexcept
- {
- return state == uint_least32_t{};
- }
-
- TOML_PURE_INLINE_GETTER
- constexpr bool needs_more_input() const noexcept
- {
- return !has_code_point() && !error();
- }
-
- constexpr void operator()(uint8_t byte) noexcept
- {
- TOML_ASSERT_ASSUME(!error());
-
- const auto type = state_table[byte];
-
- codepoint = static_cast<char32_t>(has_code_point() ? (uint_least32_t{ 255u } >> type) & byte
- : (byte & uint_least32_t{ 63u })
- | (static_cast<uint_least32_t>(codepoint) << 6));
-
- state = state_table[state + uint_least32_t{ 256u } + type];
- }
-
- TOML_ALWAYS_INLINE
- constexpr void operator()(char c) noexcept
- {
- operator()(static_cast<uint8_t>(c));
- }
-
- TOML_ALWAYS_INLINE
- constexpr void reset() noexcept
- {
- state = {};
- }
- };
-
- TOML_PURE_GETTER
- TOML_ATTR(nonnull)
- bool is_ascii(const char* str, size_t len) noexcept;
+ ;
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_value_terminator(char32_t c) noexcept {
+ return is_whitespace(c) || c == U']' || c == U'}' || c == U',' || c == U'#';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_control_character(char c) noexcept {
+ return c <= '\u001F' || c == '\u007F';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_control_character(char32_t c) noexcept {
+ return c <= U'\u001F' || c == U'\u007F';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_nontab_control_character(char32_t c) noexcept {
+ return c <= U'\u0008' || (c >= U'\u000A' && c <= U'\u001F') || c == U'\u007F';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_unicode_surrogate(char32_t c) noexcept {
+ return c >= 0xD800u && c <= 0xDFFF;
+ }
+
+ struct utf8_decoder {
+ // utf8_decoder based on this: https://bjoern.hoehrmann.de/utf-8/decoder/dfa/
+ // Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+
+ uint_least32_t state{};
+ char32_t codepoint{};
+
+ static constexpr uint8_t state_table[]{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6,
+ 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+ 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24,
+ 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12,
+ 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12,
+ 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};
+
+ TOML_PURE_INLINE_GETTER
+ constexpr bool error() const noexcept { return state == uint_least32_t{12u}; }
+
+ TOML_PURE_INLINE_GETTER
+ constexpr bool has_code_point() const noexcept { return state == uint_least32_t{}; }
+
+ TOML_PURE_INLINE_GETTER
+ constexpr bool needs_more_input() const noexcept { return !has_code_point() && !error(); }
+
+ constexpr void operator()(uint8_t byte) noexcept {
+ TOML_ASSERT_ASSUME(!error());
+
+ const auto type = state_table[byte];
+
+ codepoint = static_cast<char32_t>(has_code_point()
+ ? (uint_least32_t{255u} >> type) & byte
+ : (byte & uint_least32_t{63u}) |
+ (static_cast<uint_least32_t>(codepoint) << 6));
+
+ state = state_table[state + uint_least32_t{256u} + type];
+ }
+
+ TOML_ALWAYS_INLINE
+ constexpr void operator()(char c) noexcept { operator()(static_cast<uint8_t>(c)); }
+
+ TOML_ALWAYS_INLINE
+ constexpr void reset() noexcept { state = {}; }
+ };
+
+ TOML_PURE_GETTER
+ TOML_ATTR(nonnull)
+ bool is_ascii(const char* str, size_t len) noexcept;
}
TOML_IMPL_NAMESPACE_END;
diff --git a/vendor/toml++/impl/unicode_autogenerated.hpp b/vendor/toml++/impl/unicode_autogenerated.hpp
index cadd9e7..bbec714 100644
--- a/vendor/toml++/impl/unicode_autogenerated.hpp
+++ b/vendor/toml++/impl/unicode_autogenerated.hpp
@@ -1,176 +1,167 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
-#include "preprocessor.hpp"
#include "header_start.hpp"
+#include "preprocessor.hpp"
/// \cond
#if TOML_GCC && TOML_GCC < 9
#pragma GCC push_options
-#pragma GCC optimize("O1") // codegen bugs
+#pragma GCC optimize("O1") // codegen bugs
#endif
-// the functions in this namespace block are automatically generated by a tool - they are not meant to be hand-edited
-
-TOML_IMPL_NAMESPACE_START
-{
- TOML_CONST_GETTER
- constexpr bool is_ascii_horizontal_whitespace(char32_t c) noexcept
- {
- return c == U'\t' || c == U' ';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_non_ascii_horizontal_whitespace(char32_t c) noexcept
- {
- // 20 code units from 8 ranges (spanning a search area of 65120)
-
- if (c < U'\xA0' || c > U'\uFEFF')
- return false;
-
- const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0xA0ull) / 0x3FAull;
- if ((1ull << child_index_0) & 0x7FFFFFFFFFFFF75Eull)
- return false;
- if (c == U'\xA0' || c == U'\u3000' || c == U'\uFEFF')
- return true;
- switch (child_index_0)
- {
- case 0x05: return c == U'\u1680' || c == U'\u180E';
- case 0x07:
- return (U'\u2000' <= c && c <= U'\u200B') || (U'\u205F' <= c && c <= U'\u2060') || c == U'\u202F';
- default: TOML_UNREACHABLE;
- }
-
- TOML_UNREACHABLE;
- }
-
- TOML_CONST_GETTER
- constexpr bool is_ascii_vertical_whitespace(char32_t c) noexcept
- {
- return c >= U'\n' && c <= U'\r';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_non_ascii_vertical_whitespace(char32_t c) noexcept
- {
- return (U'\u2028' <= c && c <= U'\u2029') || c == U'\x85';
- }
-
- TOML_CONST_GETTER
- constexpr bool is_ascii_bare_key_character(char32_t c) noexcept
- {
-#if TOML_LANG_UNRELEASED // toml/issues/644 ('+' in bare keys)
- if TOML_UNLIKELY(c == U'+')
- return true;
+// the functions in this namespace block are automatically generated by a tool - they are not meant
+// to be hand-edited
+
+TOML_IMPL_NAMESPACE_START {
+ TOML_CONST_GETTER
+ constexpr bool is_ascii_horizontal_whitespace(char32_t c) noexcept {
+ return c == U'\t' || c == U' ';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_non_ascii_horizontal_whitespace(char32_t c) noexcept {
+ // 20 code units from 8 ranges (spanning a search area of 65120)
+
+ if (c < U'\xA0' || c > U'\uFEFF') return false;
+
+ const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0xA0ull) / 0x3FAull;
+ if ((1ull << child_index_0) & 0x7FFFFFFFFFFFF75Eull) return false;
+ if (c == U'\xA0' || c == U'\u3000' || c == U'\uFEFF') return true;
+ switch (child_index_0) {
+ case 0x05:
+ return c == U'\u1680' || c == U'\u180E';
+ case 0x07:
+ return (U'\u2000' <= c && c <= U'\u200B') || (U'\u205F' <= c && c <= U'\u2060') ||
+ c == U'\u202F';
+ default:
+ TOML_UNREACHABLE;
+ }
+
+ TOML_UNREACHABLE;
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_ascii_vertical_whitespace(char32_t c) noexcept {
+ return c >= U'\n' && c <= U'\r';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_non_ascii_vertical_whitespace(char32_t c) noexcept {
+ return (U'\u2028' <= c && c <= U'\u2029') || c == U'\x85';
+ }
+
+ TOML_CONST_GETTER
+ constexpr bool is_ascii_bare_key_character(char32_t c) noexcept {
+#if TOML_LANG_UNRELEASED // toml/issues/644 ('+' in bare keys)
+ if TOML_UNLIKELY (c == U'+') return true;
#endif
- // 64 code units from 5 ranges (spanning a search area of 78)
-
- if (c < U'-' || c > U'z')
- return false;
-
- return (((static_cast<uint_least64_t>(c) - 0x2Dull) / 0x40ull) != 0ull)
- || ((1ull << (static_cast<uint_least64_t>(c) - 0x2Dull)) & 0xFFF43FFFFFF01FF9ull);
- }
-
-#if TOML_LANG_UNRELEASED // toml/pull/891 (unicode bare keys)
-
- TOML_CONST_GETTER
- constexpr bool is_non_ascii_bare_key_character(char32_t c) noexcept
- {
- // 971732 code units from 16 ranges (spanning a search area of 982862)
-
- if (c < U'\xB2' || c > U'\U000EFFFF')
- return false;
-
- const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0xB2ull) / 0x3BFEull;
- if ((1ull << child_index_0) & 0xFFFFFFFFFFFFFFE6ull)
- return true;
- switch (child_index_0)
- {
- case 0x00: // [0] 00B2 - 3CAF
- {
- // 12710 code units from 13 ranges (spanning a search area of 15358)
-
- TOML_ASSUME(c >= U'\xB2' && c <= U'\u3CAF');
-
- constexpr uint_least64_t bitmask_table_1[] = {
- 0xFFFFFFDFFFFFDC83u, 0xFFFFFFFFFFFFFFDFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFEFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0x000000000C003FFFu, 0xC000000000006000u, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x000000003FFFFFFFu,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0xFFFFC00000000000u, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0x0000000000003FFFu, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
- 0x0000000000000000u, 0xFFFFFFFFFFFFC000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0x3FFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFF8000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
- 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x3FFFFFFFFFFFFFFFu,
- };
- return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xB2ull) / 0x40ull]
- & (0x1ull << ((static_cast<uint_least64_t>(c) - 0xB2ull) % 0x40ull));
- }
- case 0x03: return c <= U'\uD7FF';
- case 0x04:
- return (U'\uF900' <= c && c <= U'\uFDCF') || (U'\uFDF0' <= c && c <= U'\uFFFD') || U'\U00010000' <= c;
- default: TOML_UNREACHABLE;
- }
-
- TOML_UNREACHABLE;
- }
-
-#endif // TOML_LANG_UNRELEASED
+ // 64 code units from 5 ranges (spanning a search area of 78)
+
+ if (c < U'-' || c > U'z') return false;
+
+ return (((static_cast<uint_least64_t>(c) - 0x2Dull) / 0x40ull) != 0ull) ||
+ ((1ull << (static_cast<uint_least64_t>(c) - 0x2Dull)) & 0xFFF43FFFFFF01FF9ull);
+ }
+
+#if TOML_LANG_UNRELEASED // toml/pull/891 (unicode bare keys)
+
+ TOML_CONST_GETTER
+ constexpr bool is_non_ascii_bare_key_character(char32_t c) noexcept {
+ // 971732 code units from 16 ranges (spanning a search area of 982862)
+
+ if (c < U'\xB2' || c > U'\U000EFFFF') return false;
+
+ const auto child_index_0 = (static_cast<uint_least64_t>(c) - 0xB2ull) / 0x3BFEull;
+ if ((1ull << child_index_0) & 0xFFFFFFFFFFFFFFE6ull) return true;
+ switch (child_index_0) {
+ case 0x00: // [0] 00B2 - 3CAF
+ {
+ // 12710 code units from 13 ranges (spanning a search area of 15358)
+
+ TOML_ASSUME(c >= U'\xB2' && c <= U'\u3CAF');
+
+ constexpr uint_least64_t bitmask_table_1[] = {
+ 0xFFFFFFDFFFFFDC83u, 0xFFFFFFFFFFFFFFDFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFEFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0x000000000C003FFFu, 0xC000000000006000u, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x000000003FFFFFFFu,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0xFFFFC00000000000u, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0x0000000000003FFFu, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u, 0x0000000000000000u,
+ 0x0000000000000000u, 0xFFFFFFFFFFFFC000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0x3FFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFF8000u, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu,
+ 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0xFFFFFFFFFFFFFFFFu, 0x3FFFFFFFFFFFFFFFu,
+ };
+ return bitmask_table_1[(static_cast<uint_least64_t>(c) - 0xB2ull) / 0x40ull] &
+ (0x1ull << ((static_cast<uint_least64_t>(c) - 0xB2ull) % 0x40ull));
+ }
+ case 0x03:
+ return c <= U'\uD7FF';
+ case 0x04:
+ return (U'\uF900' <= c && c <= U'\uFDCF') || (U'\uFDF0' <= c && c <= U'\uFFFD') ||
+ U'\U00010000' <= c;
+ default:
+ TOML_UNREACHABLE;
+ }
+
+ TOML_UNREACHABLE;
+ }
+
+#endif // TOML_LANG_UNRELEASED
}
TOML_IMPL_NAMESPACE_END;
diff --git a/vendor/toml++/impl/value.hpp b/vendor/toml++/impl/value.hpp
index 6fb35dc..964e90d 100644
--- a/vendor/toml++/impl/value.hpp
+++ b/vendor/toml++/impl/value.hpp
@@ -1,14 +1,14 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "date_time.hpp"
+#include "header_start.hpp"
#include "node.hpp"
#include "print_to_stream.hpp"
#include "std_utility.hpp"
-#include "header_start.hpp"
TOML_DISABLE_ARITHMETIC_WARNINGS;
/// \cond
@@ -74,1136 +74,892 @@ TOML_DISABLE_ARITHMETIC_WARNINGS;
/// \endcond
/// \cond
-TOML_IMPL_NAMESPACE_START
-{
- template <typename T, typename...>
- struct native_value_maker
- {
- template <typename... Args>
- TOML_NODISCARD
- static T make(Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Args&&...>)
- {
- if constexpr (std::is_aggregate_v<T>)
- return T{ static_cast<Args&&>(args)... };
- else
- return T(static_cast<Args&&>(args)...);
- }
- };
-
- template <typename T>
- struct native_value_maker<T, T>
- {
- template <typename U>
- TOML_NODISCARD
- TOML_ALWAYS_INLINE
- static U&& make(U&& val) noexcept
- {
- return static_cast<U&&>(val);
- }
- };
+TOML_IMPL_NAMESPACE_START {
+ template <typename T, typename...>
+ struct native_value_maker {
+ template <typename... Args>
+ TOML_NODISCARD static T make(Args&&... args) noexcept(
+ std::is_nothrow_constructible_v<T, Args&&...>) {
+ if constexpr (std::is_aggregate_v<T>)
+ return T{static_cast<Args&&>(args)...};
+ else
+ return T(static_cast<Args&&>(args)...);
+ }
+ };
+
+ template <typename T>
+ struct native_value_maker<T, T> {
+ template <typename U>
+ TOML_NODISCARD TOML_ALWAYS_INLINE static U&& make(U&& val) noexcept {
+ return static_cast<U&&>(val);
+ }
+ };
#if TOML_HAS_CHAR8 || TOML_ENABLE_WINDOWS_COMPAT
- struct string_maker
- {
- template <typename T>
- TOML_NODISCARD
- static std::string make(T&& arg)
- {
- using arg_type = std::decay_t<T>;
+ struct string_maker {
+ template <typename T>
+ TOML_NODISCARD static std::string make(T&& arg) {
+ using arg_type = std::decay_t<T>;
#if TOML_HAS_CHAR8
- if constexpr (is_one_of<arg_type, char8_t*, const char8_t*>)
- {
- return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg)));
- }
- if constexpr (is_one_of<arg_type, std::u8string, std::u8string_view>)
- {
- return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg.data())),
- arg.length());
- }
+ if constexpr (is_one_of<arg_type, char8_t*, const char8_t*>) {
+ return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg)));
+ }
+ if constexpr (is_one_of<arg_type, std::u8string, std::u8string_view>) {
+ return std::string(reinterpret_cast<const char*>(static_cast<const char8_t*>(arg.data())),
+ arg.length());
+ }
#endif
#if TOML_ENABLE_WINDOWS_COMPAT
- if constexpr (is_wide_string<arg_type>)
- {
- return narrow(static_cast<T&&>(arg));
- }
+ if constexpr (is_wide_string<arg_type>) {
+ return narrow(static_cast<T&&>(arg));
+ }
#endif
- }
- };
+ }
+ };
#if TOML_HAS_CHAR8
- template <>
- struct native_value_maker<std::string, char8_t*> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, const char8_t*> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, std::u8string> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, std::u8string_view> : string_maker
- {};
-#endif // TOML_HAS_CHAR8
+ template <>
+ struct native_value_maker<std::string, char8_t*> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, const char8_t*> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, std::u8string> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, std::u8string_view> : string_maker {};
+#endif // TOML_HAS_CHAR8
#if TOML_ENABLE_WINDOWS_COMPAT
- template <>
- struct native_value_maker<std::string, wchar_t*> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, const wchar_t*> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, std::wstring> : string_maker
- {};
- template <>
- struct native_value_maker<std::string, std::wstring_view> : string_maker
- {};
-#endif // TOML_ENABLE_WINDOWS_COMPAT
-
-#endif // TOML_HAS_CHAR8 || TOML_ENABLE_WINDOWS_COMPAT
-
- template <typename T>
- TOML_CONST_GETTER
- inline optional<T> node_integer_cast(int64_t val) noexcept
- {
- static_assert(node_type_of<T> == node_type::integer);
- static_assert(!is_cvref<T>);
-
- using traits = value_traits<T>;
- if constexpr (!traits::is_signed)
- {
- if constexpr ((sizeof(T) * CHAR_BIT) < 63) // 63 bits == int64_max
- {
- using common_t = decltype(int64_t{} + T{});
- if (val < int64_t{} || static_cast<common_t>(val) > static_cast<common_t>(traits::max))
- return {};
- }
- else
- {
- if (val < int64_t{})
- return {};
- }
- }
- else
- {
- if (val < traits::min || val > traits::max)
- return {};
- }
- return { static_cast<T>(val) };
- }
-
- template <typename...>
- struct value_variadic_ctor_allowed : std::true_type
- {};
-
- template <typename T, typename... Args>
- struct value_variadic_ctor_allowed<value<T>, value<T>, Args...> : std::false_type
- {};
+ template <>
+ struct native_value_maker<std::string, wchar_t*> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, const wchar_t*> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, std::wstring> : string_maker {};
+ template <>
+ struct native_value_maker<std::string, std::wstring_view> : string_maker {};
+#endif // TOML_ENABLE_WINDOWS_COMPAT
+
+#endif // TOML_HAS_CHAR8 || TOML_ENABLE_WINDOWS_COMPAT
+
+ template <typename T>
+ TOML_CONST_GETTER inline optional<T> node_integer_cast(int64_t val) noexcept {
+ static_assert(node_type_of<T> == node_type::integer);
+ static_assert(!is_cvref<T>);
+
+ using traits = value_traits<T>;
+ if constexpr (!traits::is_signed) {
+ if constexpr ((sizeof(T) * CHAR_BIT) < 63) // 63 bits == int64_max
+ {
+ using common_t = decltype(int64_t{} + T{});
+ if (val < int64_t{} || static_cast<common_t>(val) > static_cast<common_t>(traits::max))
+ return {};
+ } else {
+ if (val < int64_t{}) return {};
+ }
+ } else {
+ if (val < traits::min || val > traits::max) return {};
+ }
+ return {static_cast<T>(val)};
+ }
+
+ template <typename...>
+ struct value_variadic_ctor_allowed : std::true_type {};
+
+ template <typename T, typename... Args>
+ struct value_variadic_ctor_allowed<value<T>, value<T>, Args...> : std::false_type {};
}
TOML_IMPL_NAMESPACE_END;
/// \endcond
-TOML_NAMESPACE_START
-{
- /// \brief A TOML value.
- ///
- /// \tparam ValueType The value's native TOML data type. Can be one of:
- /// - std::string
- /// - toml::date
- /// - toml::time
- /// - toml::date_time
- /// - int64_t
- /// - double
- /// - bool
- template <typename ValueType>
- class value : public node
- {
- static_assert(impl::is_native<ValueType> && !impl::is_cvref<ValueType>,
- "A toml::value<> must model one of the native TOML value types:" TOML_SA_NATIVE_VALUE_TYPE_LIST);
-
- private:
- /// \cond
-
- friend class TOML_PARSER_TYPENAME;
-
- template <typename T, typename U>
- TOML_CONST_INLINE_GETTER
- static auto as_value([[maybe_unused]] U* ptr) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return ptr;
- else
- return nullptr;
- }
-
- ValueType val_;
- value_flags flags_ = value_flags::none;
-
- /// \endcond
-
- public:
- /// \brief The value's underlying data type.
- using value_type = ValueType;
-
- /// \brief A type alias for 'value arguments'.
- /// \details This differs according to the value's type argument:
- /// - ints, floats, booleans: `value_type`
- /// - strings: `string_view`
- /// - everything else: `const value_type&`
- using value_arg = POXY_IMPLEMENTATION_DETAIL(
- std::conditional_t<
- std::is_same_v<value_type, std::string>,
- std::string_view,
- std::conditional_t<impl::is_one_of<value_type, double, int64_t, bool>, value_type, const value_type&>>);
-
- /// \brief Constructs a toml value.
- ///
- /// \tparam Args Constructor argument types.
- /// \param args Arguments to forward to the internal value's constructor.
- TOML_HIDDEN_CONSTRAINT(
- (impl::value_variadic_ctor_allowed<value<ValueType>, impl::remove_cvref<Args>...>::value),
- typename... Args)
- TOML_NODISCARD_CTOR
- explicit value(Args&&... args) noexcept(noexcept(value_type(
- impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...))))
- : val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(static_cast<Args&&>(args)...))
- {
+TOML_NAMESPACE_START {
+ /// \brief A TOML value.
+ ///
+ /// \tparam ValueType The value's native TOML data type. Can be one of:
+ /// - std::string
+ /// - toml::date
+ /// - toml::time
+ /// - toml::date_time
+ /// - int64_t
+ /// - double
+ /// - bool
+ template <typename ValueType>
+ class value : public node {
+ static_assert(impl::is_native<ValueType> && !impl::is_cvref<ValueType>,
+ "A toml::value<> must model one of the native TOML value "
+ "types:" TOML_SA_NATIVE_VALUE_TYPE_LIST);
+
+ private:
+ /// \cond
+
+ friend class TOML_PARSER_TYPENAME;
+
+ template <typename T, typename U>
+ TOML_CONST_INLINE_GETTER static auto as_value([[maybe_unused]] U* ptr) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return ptr;
+ else
+ return nullptr;
+ }
+
+ ValueType val_;
+ value_flags flags_ = value_flags::none;
+
+ /// \endcond
+
+ public:
+ /// \brief The value's underlying data type.
+ using value_type = ValueType;
+
+ /// \brief A type alias for 'value arguments'.
+ /// \details This differs according to the value's type argument:
+ /// - ints, floats, booleans: `value_type`
+ /// - strings: `string_view`
+ /// - everything else: `const value_type&`
+ using value_arg = POXY_IMPLEMENTATION_DETAIL(
+ std::conditional_t<std::is_same_v<value_type, std::string>, std::string_view,
+ std::conditional_t<impl::is_one_of<value_type, double, int64_t, bool>,
+ value_type, const value_type&>>);
+
+ /// \brief Constructs a toml value.
+ ///
+ /// \tparam Args Constructor argument types.
+ /// \param args Arguments to forward to the internal value's constructor.
+ TOML_HIDDEN_CONSTRAINT(
+ (impl::value_variadic_ctor_allowed<value<ValueType>, impl::remove_cvref<Args>...>::value),
+ typename... Args)
+ TOML_NODISCARD_CTOR
+ explicit value(Args&&... args) noexcept(
+ noexcept(value_type(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(
+ static_cast<Args&&>(args)...))))
+ : val_(impl::native_value_maker<value_type, std::decay_t<Args>...>::make(
+ static_cast<Args&&>(args)...)) {
#if TOML_LIFETIME_HOOKS
- TOML_VALUE_CREATED;
+ TOML_VALUE_CREATED;
#endif
- }
-
- /// \brief Copy constructor.
- TOML_NODISCARD_CTOR
- value(const value& other) noexcept //
- : node(other),
- val_{ other.val_ },
- flags_{ other.flags_ }
- {
+ }
+
+ /// \brief Copy constructor.
+ TOML_NODISCARD_CTOR
+ value(const value& other) noexcept //
+ : node(other), val_{other.val_}, flags_{other.flags_} {
#if TOML_LIFETIME_HOOKS
- TOML_VALUE_CREATED;
+ TOML_VALUE_CREATED;
#endif
- }
-
- /// \brief Copy constructor with flags override.
- TOML_NODISCARD_CTOR
- value(const value& other, value_flags flags) noexcept //
- : node(other),
- val_{ other.val_ },
- flags_{ flags == preserve_source_value_flags ? other.flags_ : flags }
- {
+ }
+
+ /// \brief Copy constructor with flags override.
+ TOML_NODISCARD_CTOR
+ value(const value& other, value_flags flags) noexcept //
+ : node(other),
+ val_{other.val_},
+ flags_{flags == preserve_source_value_flags ? other.flags_ : flags} {
#if TOML_LIFETIME_HOOKS
- TOML_VALUE_CREATED;
+ TOML_VALUE_CREATED;
#endif
- }
-
- /// \brief Move constructor.
- TOML_NODISCARD_CTOR
- value(value&& other) noexcept //
- : node(std::move(other)),
- val_{ std::move(other.val_) },
- flags_{ std::exchange(other.flags_, value_flags{}) }
- {
+ }
+
+ /// \brief Move constructor.
+ TOML_NODISCARD_CTOR
+ value(value&& other) noexcept //
+ : node(std::move(other)),
+ val_{std::move(other.val_)},
+ flags_{std::exchange(other.flags_, value_flags{})} {
#if TOML_LIFETIME_HOOKS
- TOML_VALUE_CREATED;
+ TOML_VALUE_CREATED;
#endif
- }
-
- /// \brief Move constructor with flags override.
- TOML_NODISCARD_CTOR
- value(value&& other, value_flags flags) noexcept //
- : node(std::move(other)),
- val_{ std::move(other.val_) },
- flags_{ flags == preserve_source_value_flags ? other.flags_ : flags }
- {
+ }
+
+ /// \brief Move constructor with flags override.
+ TOML_NODISCARD_CTOR
+ value(value&& other, value_flags flags) noexcept //
+ : node(std::move(other)),
+ val_{std::move(other.val_)},
+ flags_{flags == preserve_source_value_flags ? other.flags_ : flags} {
#if TOML_LIFETIME_HOOKS
- TOML_VALUE_CREATED;
+ TOML_VALUE_CREATED;
#endif
- other.flags_ = {};
- }
-
- /// \brief Copy-assignment operator.
- value& operator=(const value& rhs) noexcept
- {
- node::operator=(rhs);
- val_ = rhs.val_;
- flags_ = rhs.flags_;
- return *this;
- }
-
- /// \brief Move-assignment operator.
- value& operator=(value&& rhs) noexcept
- {
- if (&rhs != this)
- {
- node::operator=(std::move(rhs));
- val_ = std::move(rhs.val_);
- flags_ = std::exchange(rhs.flags_, value_flags{});
- }
- return *this;
- }
+ other.flags_ = {};
+ }
+
+ /// \brief Copy-assignment operator.
+ value& operator=(const value& rhs) noexcept {
+ node::operator=(rhs);
+ val_ = rhs.val_;
+ flags_ = rhs.flags_;
+ return *this;
+ }
+
+ /// \brief Move-assignment operator.
+ value& operator=(value&& rhs) noexcept {
+ if (&rhs != this) {
+ node::operator=(std::move(rhs));
+ val_ = std::move(rhs.val_);
+ flags_ = std::exchange(rhs.flags_, value_flags{});
+ }
+ return *this;
+ }
#if TOML_LIFETIME_HOOKS
- ~value() noexcept
- {
- TOML_VALUE_DESTROYED;
- }
+ ~value() noexcept { TOML_VALUE_DESTROYED; }
#endif
- /// \name Type checks
- /// @{
-
- /// \brief Returns the value's node type identifier.
- ///
- /// \returns One of:
- /// - node_type::string
- /// - node_type::integer
- /// - node_type::floating_point
- /// - node_type::boolean
- /// - node_type::date
- /// - node_type::time
- /// - node_type::date_time
- TOML_CONST_INLINE_GETTER
- node_type type() const noexcept final
- {
- return impl::node_type_of<value_type>;
- }
-
- TOML_PURE_GETTER
- bool is_homogeneous(node_type ntype) const noexcept final
- {
- return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
- }
-
- TOML_PURE_GETTER
- bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final
- {
- if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
- {
- first_nonmatch = this;
- return false;
- }
- return true;
- }
-
- TOML_PURE_GETTER
- bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final
- {
- if (ntype != node_type::none && ntype != impl::node_type_of<value_type>)
- {
- first_nonmatch = this;
- return false;
- }
- return true;
- }
-
- /// \cond
- template <typename ElemType = void>
- TOML_PURE_GETTER
- bool is_homogeneous() const noexcept
- {
- using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
- static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
- "The template type argument of value::is_homogeneous() must be void or one "
- "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
-
- if constexpr (std::is_void_v<type>)
- return true;
- else
- return impl::node_type_of<type> == impl::node_type_of<value_type>;
- }
- /// \endcond
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_table() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_array() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `false`.
- TOML_CONST_INLINE_GETTER
- bool is_array_of_tables() const noexcept final
- {
- return false;
- }
-
- /// \brief Returns `true`.
- TOML_CONST_INLINE_GETTER
- bool is_value() const noexcept final
- {
- return true;
- }
-
- /// \brief Returns `true` if the #value_type is std::string.
- TOML_CONST_INLINE_GETTER
- bool is_string() const noexcept final
- {
- return std::is_same_v<value_type, std::string>;
- }
-
- /// \brief Returns `true` if the #value_type is int64_t.
- TOML_CONST_INLINE_GETTER
- bool is_integer() const noexcept final
- {
- return std::is_same_v<value_type, int64_t>;
- }
-
- /// \brief Returns `true` if the #value_type is `double`.
- TOML_CONST_INLINE_GETTER
- bool is_floating_point() const noexcept final
- {
- return std::is_same_v<value_type, double>;
- }
-
- /// \brief Returns `true` if the #value_type is int64_t or `double`.
- TOML_CONST_INLINE_GETTER
- bool is_number() const noexcept final
- {
- return impl::is_one_of<value_type, int64_t, double>;
- }
-
- /// \brief Returns `true` if the #value_type is `bool`.
- TOML_CONST_INLINE_GETTER
- bool is_boolean() const noexcept final
- {
- return std::is_same_v<value_type, bool>;
- }
-
- /// \brief Returns `true` if the #value_type is toml::date.
- TOML_CONST_INLINE_GETTER
- bool is_date() const noexcept final
- {
- return std::is_same_v<value_type, date>;
- }
-
- /// \brief Returns `true` if the #value_type is toml::time.
- TOML_CONST_INLINE_GETTER
- bool is_time() const noexcept final
- {
- return std::is_same_v<value_type, time>;
- }
-
- /// \brief Returns `true` if the #value_type is toml_date_time.
- TOML_CONST_INLINE_GETTER
- bool is_date_time() const noexcept final
- {
- return std::is_same_v<value_type, date_time>;
- }
-
- /// @}
-
- /// \name Type casts
- /// @{
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- table* as_table() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- array* as_array() noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns a pointer to the value if it is a value<std::string>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<std::string>* as_string() noexcept final
- {
- return as_value<std::string>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<int64_t>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<int64_t>* as_integer() noexcept final
- {
- return as_value<int64_t>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<double>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<double>* as_floating_point() noexcept final
- {
- return as_value<double>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<bool>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<bool>* as_boolean() noexcept final
- {
- return as_value<bool>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<date>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<date>* as_date() noexcept final
- {
- return as_value<date>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<time>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<time>* as_time() noexcept final
- {
- return as_value<time>(this);
- }
-
- /// \brief Returns a pointer to the value if it is a value<date_time>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- value<date_time>* as_date_time() noexcept final
- {
- return as_value<date_time>(this);
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const table* as_table() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns `nullptr`.
- TOML_CONST_INLINE_GETTER
- const array* as_array() const noexcept final
- {
- return nullptr;
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<std::string>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<std::string>* as_string() const noexcept final
- {
- return as_value<std::string>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<int64_t>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<int64_t>* as_integer() const noexcept final
- {
- return as_value<int64_t>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<double>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<double>* as_floating_point() const noexcept final
- {
- return as_value<double>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<bool>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<bool>* as_boolean() const noexcept final
- {
- return as_value<bool>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<date>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<date>* as_date() const noexcept final
- {
- return as_value<date>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<time>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<time>* as_time() const noexcept final
- {
- return as_value<time>(this);
- }
-
- /// \brief Returns a const-qualified pointer to the value if it is a value<date_time>, otherwise `nullptr`.
- TOML_CONST_INLINE_GETTER
- const value<date_time>* as_date_time() const noexcept final
- {
- return as_value<date_time>(this);
- }
-
- /// @}
-
- /// \name Value retrieval
- /// @{
-
- /// \brief Returns a reference to the underlying value.
- TOML_PURE_INLINE_GETTER
- value_type& get() & noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (rvalue overload).
- TOML_PURE_INLINE_GETTER
- value_type&& get() && noexcept
- {
- return static_cast<value_type&&>(val_);
- }
-
- /// \brief Returns a reference to the underlying value (const overload).
- TOML_PURE_INLINE_GETTER
- const value_type& get() const& noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (const rvalue overload).
- TOML_PURE_INLINE_GETTER
- const value_type&& get() const&& noexcept
- {
- return static_cast<const value_type&&>(val_);
- }
-
- /// \brief Returns a reference to the underlying value.
- TOML_PURE_INLINE_GETTER
- value_type& operator*() & noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (rvalue overload).
- TOML_PURE_INLINE_GETTER
- value_type&& operator*() && noexcept
- {
- return static_cast<value_type&&>(val_);
- }
-
- /// \brief Returns a reference to the underlying value (const overload).
- TOML_PURE_INLINE_GETTER
- const value_type& operator*() const& noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (const rvalue overload).
- TOML_PURE_INLINE_GETTER
- const value_type&& operator*() const&& noexcept
- {
- return static_cast<const value_type&&>(val_);
- }
-
- /// \brief Returns a reference to the underlying value.
- TOML_PURE_INLINE_GETTER
- explicit operator value_type&() & noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (rvalue overload).
- TOML_PURE_INLINE_GETTER
- explicit operator value_type&&() && noexcept
- {
- return static_cast<value_type&&>(val_);
- }
-
- /// \brief Returns a reference to the underlying value (const overload).
- TOML_PURE_INLINE_GETTER
- explicit operator const value_type&() const& noexcept
- {
- return val_;
- }
-
- /// \brief Returns a reference to the underlying value (const rvalue overload).
- TOML_PURE_INLINE_GETTER
- explicit operator const value_type&&() && noexcept
- {
- return static_cast<const value_type&&>(val_);
- }
-
- /// \brief Returns a pointer to the underlying value.
- ///
- /// \availability This operator is only available when #value_type is a class/struct.
- TOML_HIDDEN_CONSTRAINT(std::is_class_v<T>, typename T = value_type)
- TOML_PURE_INLINE_GETTER
- value_type* operator->() noexcept
- {
- return &val_;
- }
-
- /// \brief Returns a pointer to the underlying value (const overload).
- ///
- /// \availability This operator is only available when #value_type is a class/struct.
- TOML_HIDDEN_CONSTRAINT(std::is_class_v<T>, typename T = value_type)
- TOML_PURE_INLINE_GETTER
- const value_type* operator->() const noexcept
- {
- return &val_;
- }
-
- /// @}
-
- /// \name Metadata
- /// @{
-
- /// \brief Returns the metadata flags associated with this value.
- TOML_NODISCARD
- value_flags flags() const noexcept
- {
- return flags_;
- }
-
- /// \brief Sets the metadata flags associated with this value.
- /// \returns A reference to the value object.
- value& flags(value_flags new_flags) noexcept
- {
- flags_ = new_flags;
- return *this;
- }
-
- /// @}
-
- /// \brief Value-assignment operator.
- value& operator=(value_arg rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, std::string>)
- val_.assign(rhs);
- else
- val_ = rhs;
- return *this;
- }
-
- TOML_CONSTRAINED_TEMPLATE((std::is_same_v<T, std::string>), typename T = value_type)
- value& operator=(std::string&& rhs) noexcept
- {
- val_ = std::move(rhs);
- return *this;
- }
-
- /// \name Equality and Comparison
- /// @{
-
- /// \brief Value equality operator.
- TOML_PURE_GETTER
- friend bool operator==(const value& lhs, value_arg rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, double>)
- {
- const auto lhs_nan = impl::fpclassify(lhs.val_) == impl::fp_class::nan;
- const auto rhs_nan = impl::fpclassify(rhs) == impl::fp_class::nan;
- if (lhs_nan != rhs_nan)
- return false;
- if (lhs_nan)
- return true;
- }
- return lhs.val_ == rhs;
- }
- TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg, );
-
- /// \brief Value less-than operator.
- TOML_PURE_GETTER
- friend bool operator<(const value& lhs, value_arg rhs) noexcept
- {
- return lhs.val_ < rhs;
- }
-
- /// \brief Value less-than operator.
- TOML_PURE_GETTER
- friend bool operator<(value_arg lhs, const value& rhs) noexcept
- {
- return lhs < rhs.val_;
- }
-
- /// \brief Value less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend bool operator<=(const value& lhs, value_arg rhs) noexcept
- {
- return lhs.val_ <= rhs;
- }
-
- /// \brief Value less-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend bool operator<=(value_arg lhs, const value& rhs) noexcept
- {
- return lhs <= rhs.val_;
- }
-
- /// \brief Value greater-than operator.
- TOML_PURE_GETTER
- friend bool operator>(const value& lhs, value_arg rhs) noexcept
- {
- return lhs.val_ > rhs;
- }
-
- /// \brief Value greater-than operator.
- TOML_PURE_GETTER
- friend bool operator>(value_arg lhs, const value& rhs) noexcept
- {
- return lhs > rhs.val_;
- }
-
- /// \brief Value greater-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend bool operator>=(const value& lhs, value_arg rhs) noexcept
- {
- return lhs.val_ >= rhs;
- }
-
- /// \brief Value greater-than-or-equal-to operator.
- TOML_PURE_GETTER
- friend bool operator>=(value_arg lhs, const value& rhs) noexcept
- {
- return lhs >= rhs.val_;
- }
-
- /// \brief Equality operator.
- ///
- /// \param lhs The LHS value.
- /// \param rhs The RHS value.
- ///
- /// \returns True if the values were of the same type and contained the same value.
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator==(const value& lhs, const value<T>& rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return lhs == rhs.val_; // calls asymmetrical value-equality operator defined above
- else
- return false;
- }
-
- /// \brief Inequality operator.
- ///
- /// \param lhs The LHS value.
- /// \param rhs The RHS value.
- ///
- /// \returns True if the values were not of the same type, or did not contain the same value.
- template <typename T>
- TOML_PURE_INLINE_GETTER
- friend bool operator!=(const value& lhs, const value<T>& rhs) noexcept
- {
- return !(lhs == rhs);
- }
-
- /// \brief Less-than operator.
- ///
- /// \param lhs The LHS toml::value.
- /// \param rhs The RHS toml::value.
- ///
- /// \returns \conditional_return{Same value types}
- /// `lhs.get() < rhs.get()`
- /// \conditional_return{Different value types}
- /// `lhs.type() < rhs.type()`
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator<(const value& lhs, const value<T>& rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return lhs.val_ < rhs.val_;
- else
- return impl::node_type_of<value_type> < impl::node_type_of<T>;
- }
-
- /// \brief Less-than-or-equal-to operator.
- ///
- /// \param lhs The LHS toml::value.
- /// \param rhs The RHS toml::value.
- ///
- /// \returns \conditional_return{Same value types}
- /// `lhs.get() <= rhs.get()`
- /// \conditional_return{Different value types}
- /// `lhs.type() <= rhs.type()`
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator<=(const value& lhs, const value<T>& rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return lhs.val_ <= rhs.val_;
- else
- return impl::node_type_of<value_type> <= impl::node_type_of<T>;
- }
-
- /// \brief Greater-than operator.
- ///
- /// \param lhs The LHS toml::value.
- /// \param rhs The RHS toml::value.
- ///
- /// \returns \conditional_return{Same value types}
- /// `lhs.get() > rhs.get()`
- /// \conditional_return{Different value types}
- /// `lhs.type() > rhs.type()`
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator>(const value& lhs, const value<T>& rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return lhs.val_ > rhs.val_;
- else
- return impl::node_type_of<value_type> > impl::node_type_of<T>;
- }
-
- /// \brief Greater-than-or-equal-to operator.
- ///
- /// \param lhs The LHS toml::value.
- /// \param rhs The RHS toml::value.
- ///
- /// \returns \conditional_return{Same value types}
- /// `lhs.get() >= rhs.get()`
- /// \conditional_return{Different value types}
- /// `lhs.type() >= rhs.type()`
- template <typename T>
- TOML_PURE_GETTER
- friend bool operator>=(const value& lhs, const value<T>& rhs) noexcept
- {
- if constexpr (std::is_same_v<value_type, T>)
- return lhs.val_ >= rhs.val_;
- else
- return impl::node_type_of<value_type> >= impl::node_type_of<T>;
- }
-
- /// @}
+ /// \name Type checks
+ /// @{
+
+ /// \brief Returns the value's node type identifier.
+ ///
+ /// \returns One of:
+ /// - node_type::string
+ /// - node_type::integer
+ /// - node_type::floating_point
+ /// - node_type::boolean
+ /// - node_type::date
+ /// - node_type::time
+ /// - node_type::date_time
+ TOML_CONST_INLINE_GETTER
+ node_type type() const noexcept final { return impl::node_type_of<value_type>; }
+
+ TOML_PURE_GETTER
+ bool is_homogeneous(node_type ntype) const noexcept final {
+ return ntype == node_type::none || ntype == impl::node_type_of<value_type>;
+ }
+
+ TOML_PURE_GETTER
+ bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final {
+ if (ntype != node_type::none && ntype != impl::node_type_of<value_type>) {
+ first_nonmatch = this;
+ return false;
+ }
+ return true;
+ }
+
+ TOML_PURE_GETTER
+ bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final {
+ if (ntype != node_type::none && ntype != impl::node_type_of<value_type>) {
+ first_nonmatch = this;
+ return false;
+ }
+ return true;
+ }
+
+ /// \cond
+ template <typename ElemType = void>
+ TOML_PURE_GETTER bool is_homogeneous() const noexcept {
+ using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
+ static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
+ "The template type argument of value::is_homogeneous() must be void or one "
+ "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
+
+ if constexpr (std::is_void_v<type>)
+ return true;
+ else
+ return impl::node_type_of<type> == impl::node_type_of<value_type>;
+ }
+ /// \endcond
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_table() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_array() const noexcept final { return false; }
+
+ /// \brief Returns `false`.
+ TOML_CONST_INLINE_GETTER
+ bool is_array_of_tables() const noexcept final { return false; }
+
+ /// \brief Returns `true`.
+ TOML_CONST_INLINE_GETTER
+ bool is_value() const noexcept final { return true; }
+
+ /// \brief Returns `true` if the #value_type is std::string.
+ TOML_CONST_INLINE_GETTER
+ bool is_string() const noexcept final { return std::is_same_v<value_type, std::string>; }
+
+ /// \brief Returns `true` if the #value_type is int64_t.
+ TOML_CONST_INLINE_GETTER
+ bool is_integer() const noexcept final { return std::is_same_v<value_type, int64_t>; }
+
+ /// \brief Returns `true` if the #value_type is `double`.
+ TOML_CONST_INLINE_GETTER
+ bool is_floating_point() const noexcept final { return std::is_same_v<value_type, double>; }
+
+ /// \brief Returns `true` if the #value_type is int64_t or `double`.
+ TOML_CONST_INLINE_GETTER
+ bool is_number() const noexcept final { return impl::is_one_of<value_type, int64_t, double>; }
+
+ /// \brief Returns `true` if the #value_type is `bool`.
+ TOML_CONST_INLINE_GETTER
+ bool is_boolean() const noexcept final { return std::is_same_v<value_type, bool>; }
+
+ /// \brief Returns `true` if the #value_type is toml::date.
+ TOML_CONST_INLINE_GETTER
+ bool is_date() const noexcept final { return std::is_same_v<value_type, date>; }
+
+ /// \brief Returns `true` if the #value_type is toml::time.
+ TOML_CONST_INLINE_GETTER
+ bool is_time() const noexcept final { return std::is_same_v<value_type, time>; }
+
+ /// \brief Returns `true` if the #value_type is toml_date_time.
+ TOML_CONST_INLINE_GETTER
+ bool is_date_time() const noexcept final { return std::is_same_v<value_type, date_time>; }
+
+ /// @}
+
+ /// \name Type casts
+ /// @{
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ table* as_table() noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ array* as_array() noexcept final { return nullptr; }
+
+ /// \brief Returns a pointer to the value if it is a value<std::string>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<std::string>* as_string() noexcept final { return as_value<std::string>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<int64_t>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<int64_t>* as_integer() noexcept final { return as_value<int64_t>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<double>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<double>* as_floating_point() noexcept final { return as_value<double>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<bool>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<bool>* as_boolean() noexcept final { return as_value<bool>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<date>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<date>* as_date() noexcept final { return as_value<date>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<time>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<time>* as_time() noexcept final { return as_value<time>(this); }
+
+ /// \brief Returns a pointer to the value if it is a value<date_time>, otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ value<date_time>* as_date_time() noexcept final { return as_value<date_time>(this); }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const table* as_table() const noexcept final { return nullptr; }
+
+ /// \brief Returns `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const array* as_array() const noexcept final { return nullptr; }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<std::string>,
+ /// otherwise `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<std::string>* as_string() const noexcept final {
+ return as_value<std::string>(this);
+ }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<int64_t>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<int64_t>* as_integer() const noexcept final { return as_value<int64_t>(this); }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<double>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<double>* as_floating_point() const noexcept final { return as_value<double>(this); }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<bool>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<bool>* as_boolean() const noexcept final { return as_value<bool>(this); }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<date>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<date>* as_date() const noexcept final { return as_value<date>(this); }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<time>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<time>* as_time() const noexcept final { return as_value<time>(this); }
+
+ /// \brief Returns a const-qualified pointer to the value if it is a value<date_time>, otherwise
+ /// `nullptr`.
+ TOML_CONST_INLINE_GETTER
+ const value<date_time>* as_date_time() const noexcept final {
+ return as_value<date_time>(this);
+ }
+
+ /// @}
+
+ /// \name Value retrieval
+ /// @{
+
+ /// \brief Returns a reference to the underlying value.
+ TOML_PURE_INLINE_GETTER
+ value_type& get() & noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ value_type&& get() && noexcept { return static_cast<value_type&&>(val_); }
+
+ /// \brief Returns a reference to the underlying value (const overload).
+ TOML_PURE_INLINE_GETTER
+ const value_type& get() const& noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (const rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ const value_type&& get() const&& noexcept { return static_cast<const value_type&&>(val_); }
+
+ /// \brief Returns a reference to the underlying value.
+ TOML_PURE_INLINE_GETTER
+ value_type& operator*() & noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ value_type&& operator*() && noexcept { return static_cast<value_type&&>(val_); }
+
+ /// \brief Returns a reference to the underlying value (const overload).
+ TOML_PURE_INLINE_GETTER
+ const value_type& operator*() const& noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (const rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ const value_type&& operator*() const&& noexcept {
+ return static_cast<const value_type&&>(val_);
+ }
+
+ /// \brief Returns a reference to the underlying value.
+ TOML_PURE_INLINE_GETTER
+ explicit operator value_type&() & noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ explicit operator value_type&&() && noexcept { return static_cast<value_type&&>(val_); }
+
+ /// \brief Returns a reference to the underlying value (const overload).
+ TOML_PURE_INLINE_GETTER
+ explicit operator const value_type&() const& noexcept { return val_; }
+
+ /// \brief Returns a reference to the underlying value (const rvalue overload).
+ TOML_PURE_INLINE_GETTER
+ explicit operator const value_type&&() && noexcept {
+ return static_cast<const value_type&&>(val_);
+ }
+
+ /// \brief Returns a pointer to the underlying value.
+ ///
+ /// \availability This operator is only available when #value_type is a class/struct.
+ TOML_HIDDEN_CONSTRAINT(std::is_class_v<T>, typename T = value_type)
+ TOML_PURE_INLINE_GETTER
+ value_type* operator->() noexcept { return &val_; }
+
+ /// \brief Returns a pointer to the underlying value (const overload).
+ ///
+ /// \availability This operator is only available when #value_type is a class/struct.
+ TOML_HIDDEN_CONSTRAINT(std::is_class_v<T>, typename T = value_type)
+ TOML_PURE_INLINE_GETTER
+ const value_type* operator->() const noexcept { return &val_; }
+
+ /// @}
+
+ /// \name Metadata
+ /// @{
+
+ /// \brief Returns the metadata flags associated with this value.
+ TOML_NODISCARD
+ value_flags flags() const noexcept { return flags_; }
+
+ /// \brief Sets the metadata flags associated with this value.
+ /// \returns A reference to the value object.
+ value& flags(value_flags new_flags) noexcept {
+ flags_ = new_flags;
+ return *this;
+ }
+
+ /// @}
+
+ /// \brief Value-assignment operator.
+ value& operator=(value_arg rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, std::string>)
+ val_.assign(rhs);
+ else
+ val_ = rhs;
+ return *this;
+ }
+
+ TOML_CONSTRAINED_TEMPLATE((std::is_same_v<T, std::string>), typename T = value_type)
+ value& operator=(std::string&& rhs) noexcept {
+ val_ = std::move(rhs);
+ return *this;
+ }
+
+ /// \name Equality and Comparison
+ /// @{
+
+ /// \brief Value equality operator.
+ TOML_PURE_GETTER
+ friend bool operator==(const value& lhs, value_arg rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, double>) {
+ const auto lhs_nan = impl::fpclassify(lhs.val_) == impl::fp_class::nan;
+ const auto rhs_nan = impl::fpclassify(rhs) == impl::fp_class::nan;
+ if (lhs_nan != rhs_nan) return false;
+ if (lhs_nan) return true;
+ }
+ return lhs.val_ == rhs;
+ }
+ TOML_ASYMMETRICAL_EQUALITY_OPS(const value&, value_arg, );
+
+ /// \brief Value less-than operator.
+ TOML_PURE_GETTER
+ friend bool operator<(const value& lhs, value_arg rhs) noexcept { return lhs.val_ < rhs; }
+
+ /// \brief Value less-than operator.
+ TOML_PURE_GETTER
+ friend bool operator<(value_arg lhs, const value& rhs) noexcept { return lhs < rhs.val_; }
+
+ /// \brief Value less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend bool operator<=(const value& lhs, value_arg rhs) noexcept { return lhs.val_ <= rhs; }
+
+ /// \brief Value less-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend bool operator<=(value_arg lhs, const value& rhs) noexcept { return lhs <= rhs.val_; }
+
+ /// \brief Value greater-than operator.
+ TOML_PURE_GETTER
+ friend bool operator>(const value& lhs, value_arg rhs) noexcept { return lhs.val_ > rhs; }
+
+ /// \brief Value greater-than operator.
+ TOML_PURE_GETTER
+ friend bool operator>(value_arg lhs, const value& rhs) noexcept { return lhs > rhs.val_; }
+
+ /// \brief Value greater-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend bool operator>=(const value& lhs, value_arg rhs) noexcept { return lhs.val_ >= rhs; }
+
+ /// \brief Value greater-than-or-equal-to operator.
+ TOML_PURE_GETTER
+ friend bool operator>=(value_arg lhs, const value& rhs) noexcept { return lhs >= rhs.val_; }
+
+ /// \brief Equality operator.
+ ///
+ /// \param lhs The LHS value.
+ /// \param rhs The RHS value.
+ ///
+ /// \returns True if the values were of the same type and contained the same value.
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator==(const value& lhs, const value<T>& rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return lhs == rhs.val_; // calls asymmetrical value-equality operator defined above
+ else
+ return false;
+ }
+
+ /// \brief Inequality operator.
+ ///
+ /// \param lhs The LHS value.
+ /// \param rhs The RHS value.
+ ///
+ /// \returns True if the values were not of the same type, or did not contain the same value.
+ template <typename T>
+ TOML_PURE_INLINE_GETTER friend bool operator!=(const value& lhs, const value<T>& rhs) noexcept {
+ return !(lhs == rhs);
+ }
+
+ /// \brief Less-than operator.
+ ///
+ /// \param lhs The LHS toml::value.
+ /// \param rhs The RHS toml::value.
+ ///
+ /// \returns \conditional_return{Same value types}
+ /// `lhs.get() < rhs.get()`
+ /// \conditional_return{Different value types}
+ /// `lhs.type() < rhs.type()`
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator<(const value& lhs, const value<T>& rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return lhs.val_ < rhs.val_;
+ else
+ return impl::node_type_of<value_type> < impl::node_type_of<T>;
+ }
+
+ /// \brief Less-than-or-equal-to operator.
+ ///
+ /// \param lhs The LHS toml::value.
+ /// \param rhs The RHS toml::value.
+ ///
+ /// \returns \conditional_return{Same value types}
+ /// `lhs.get() <= rhs.get()`
+ /// \conditional_return{Different value types}
+ /// `lhs.type() <= rhs.type()`
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator<=(const value& lhs, const value<T>& rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return lhs.val_ <= rhs.val_;
+ else
+ return impl::node_type_of<value_type> <= impl::node_type_of<T>;
+ }
+
+ /// \brief Greater-than operator.
+ ///
+ /// \param lhs The LHS toml::value.
+ /// \param rhs The RHS toml::value.
+ ///
+ /// \returns \conditional_return{Same value types}
+ /// `lhs.get() > rhs.get()`
+ /// \conditional_return{Different value types}
+ /// `lhs.type() > rhs.type()`
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator>(const value& lhs, const value<T>& rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return lhs.val_ > rhs.val_;
+ else
+ return impl::node_type_of<value_type> > impl::node_type_of<T>;
+ }
+
+ /// \brief Greater-than-or-equal-to operator.
+ ///
+ /// \param lhs The LHS toml::value.
+ /// \param rhs The RHS toml::value.
+ ///
+ /// \returns \conditional_return{Same value types}
+ /// `lhs.get() >= rhs.get()`
+ /// \conditional_return{Different value types}
+ /// `lhs.type() >= rhs.type()`
+ template <typename T>
+ TOML_PURE_GETTER friend bool operator>=(const value& lhs, const value<T>& rhs) noexcept {
+ if constexpr (std::is_same_v<value_type, T>)
+ return lhs.val_ >= rhs.val_;
+ else
+ return impl::node_type_of<value_type> >= impl::node_type_of<T>;
+ }
+
+ /// @}
#if TOML_ENABLE_FORMATTERS
- /// \brief Prints the value out to a stream as formatted TOML.
- ///
- /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
- friend std::ostream& operator<<(std::ostream& lhs, const value& rhs)
- {
- impl::print_to_stream(lhs, rhs);
- return lhs;
- }
+ /// \brief Prints the value out to a stream as formatted TOML.
+ ///
+ /// \availability This operator is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ friend std::ostream& operator<<(std::ostream& lhs, const value& rhs) {
+ impl::print_to_stream(lhs, rhs);
+ return lhs;
+ }
#endif
- };
-
- /// \cond
-
- template <typename T>
- value(T) -> value<impl::native_type_of<impl::remove_cvref<T>>>;
- template <typename T>
- value(T, value_flags) -> value<impl::native_type_of<impl::remove_cvref<T>>>;
-
- template <typename T>
- TOML_NODISCARD
- inline decltype(auto) node::get_value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- using namespace impl;
-
- static_assert(node_type_of<T> != node_type::none);
- static_assert(node_type_of<T> != node_type::table);
- static_assert(node_type_of<T> != node_type::array);
- static_assert(is_native<T> || can_represent_native<T>);
- static_assert(!is_cvref<T>);
- TOML_ASSERT(this->type() == node_type_of<T>);
-
- if constexpr (node_type_of<T> == node_type::string)
- {
- const auto& str = *ref_cast<std::string>();
- if constexpr (std::is_same_v<T, std::string>)
- return str;
- else if constexpr (std::is_same_v<T, std::string_view>)
- return T{ str };
- else if constexpr (std::is_same_v<T, const char*>)
- return str.c_str();
-
- else if constexpr (std::is_same_v<T, std::wstring>)
- {
+ };
+
+ /// \cond
+
+ template <typename T>
+ value(T) -> value<impl::native_type_of<impl::remove_cvref<T>>>;
+ template <typename T>
+ value(T, value_flags) -> value<impl::native_type_of<impl::remove_cvref<T>>>;
+
+ template <typename T>
+ TOML_NODISCARD inline decltype(auto) node::get_value_exact()
+ const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ using namespace impl;
+
+ static_assert(node_type_of<T> != node_type::none);
+ static_assert(node_type_of<T> != node_type::table);
+ static_assert(node_type_of<T> != node_type::array);
+ static_assert(is_native<T> || can_represent_native<T>);
+ static_assert(!is_cvref<T>);
+ TOML_ASSERT(this->type() == node_type_of<T>);
+
+ if constexpr (node_type_of<T> == node_type::string) {
+ const auto& str = *ref_cast<std::string>();
+ if constexpr (std::is_same_v<T, std::string>)
+ return str;
+ else if constexpr (std::is_same_v<T, std::string_view>)
+ return T{str};
+ else if constexpr (std::is_same_v<T, const char*>)
+ return str.c_str();
+
+ else if constexpr (std::is_same_v<T, std::wstring>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- return widen(str);
+ return widen(str);
#else
- static_assert(always_false<T>, "Evaluated unreachable branch!");
+ static_assert(always_false<T>, "Evaluated unreachable branch!");
#endif
- }
+ }
#if TOML_HAS_CHAR8
- // char -> char8_t (potentially unsafe - the feature is 'experimental'!)
- else if constexpr (is_one_of<T, std::u8string, std::u8string_view>)
- return T(reinterpret_cast<const char8_t*>(str.c_str()), str.length());
- else if constexpr (std::is_same_v<T, const char8_t*>)
- return reinterpret_cast<const char8_t*>(str.c_str());
- else
- static_assert(always_false<T>, "Evaluated unreachable branch!");
+ // char -> char8_t (potentially unsafe - the feature is 'experimental'!)
+ else if constexpr (is_one_of<T, std::u8string, std::u8string_view>)
+ return T(reinterpret_cast<const char8_t*>(str.c_str()), str.length());
+ else if constexpr (std::is_same_v<T, const char8_t*>)
+ return reinterpret_cast<const char8_t*>(str.c_str());
+ else
+ static_assert(always_false<T>, "Evaluated unreachable branch!");
#endif
- }
- else
- return static_cast<T>(*ref_cast<native_type_of<T>>());
- }
-
- template <typename T>
- TOML_NODISCARD
- inline optional<T> node::value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- using namespace impl;
-
- static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Retrieving values as wide-character strings with node::value_exact() is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- static_assert((is_native<T> || can_represent_native<T>)&&!is_cvref<T>,
- TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::value_exact()"));
-
- // prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
- if constexpr ((is_native<T> || can_represent_native<T>)&&!is_cvref<T>)
- {
- if (type() == node_type_of<T>)
- return { this->get_value_exact<T>() };
- else
- return {};
- }
- }
-
- template <typename T>
- TOML_NODISCARD
- inline optional<T> node::value() const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- using namespace impl;
-
- static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Retrieving values as wide-character strings with node::value() is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
- static_assert((is_native<T> || can_represent_native<T> || can_partially_represent_native<T>)&&!is_cvref<T>,
- TOML_SA_VALUE_FUNC_MESSAGE("return type of node::value()"));
-
- // when asking for strings, dates, times and date_times there's no 'fuzzy' conversion
- // semantics to be mindful of so the exact retrieval is enough.
- if constexpr (is_natively_one_of<T, std::string, time, date, date_time>)
- {
- if (type() == node_type_of<T>)
- return { this->get_value_exact<T>() };
- else
- return {};
- }
-
- // everything else requires a bit of logicking.
- else
- {
- switch (type())
- {
- // int -> *
- case node_type::integer:
- {
- // int -> int
- if constexpr (is_natively_one_of<T, int64_t>)
- {
- if constexpr (is_native<T> || can_represent_native<T>)
- return static_cast<T>(*ref_cast<int64_t>());
- else
- return node_integer_cast<T>(*ref_cast<int64_t>());
- }
-
- // int -> float
- else if constexpr (is_natively_one_of<T, double>)
- {
- const int64_t val = *ref_cast<int64_t>();
- if constexpr (std::numeric_limits<T>::digits < 64)
- {
- constexpr auto largest_whole_float = (int64_t{ 1 } << std::numeric_limits<T>::digits);
- if (val < -largest_whole_float || val > largest_whole_float)
- return {};
- }
- return static_cast<T>(val);
- }
-
- // int -> bool
- else if constexpr (is_natively_one_of<T, bool>)
- return static_cast<bool>(*ref_cast<int64_t>());
-
- // int -> anything else
- else
- return {};
- }
-
- // float -> *
- case node_type::floating_point:
- {
- // float -> float
- if constexpr (is_natively_one_of<T, double>)
- {
- if constexpr (is_native<T> || can_represent_native<T>)
- return { static_cast<T>(*ref_cast<double>()) };
- else
- {
- const double val = *ref_cast<double>();
- if (impl::fpclassify(val) == fp_class::ok
- && (val < (std::numeric_limits<T>::lowest)() || val > (std::numeric_limits<T>::max)()))
- return {};
- return { static_cast<T>(val) };
- }
- }
-
- // float -> int
- else if constexpr (is_natively_one_of<T, int64_t>)
- {
- const double val = *ref_cast<double>();
- if (impl::fpclassify(val) == fp_class::ok
- && static_cast<double>(static_cast<int64_t>(val)) == val)
- return node_integer_cast<T>(static_cast<int64_t>(val));
- else
- return {};
- }
-
- // float -> anything else
- else
- return {};
- }
-
- // bool -> *
- case node_type::boolean:
- {
- // bool -> bool
- if constexpr (is_natively_one_of<T, bool>)
- return { *ref_cast<bool>() };
-
- // bool -> int
- else if constexpr (is_natively_one_of<T, int64_t>)
- return { static_cast<T>(*ref_cast<bool>()) };
-
- // bool -> anything else
- else
- return {};
- }
- }
-
- // non-values, or 'exact' types covered above
- return {};
- }
- }
-
- template <typename T>
- TOML_NODISCARD
- inline auto node::value_or(T && default_value) const noexcept(impl::value_retrieval_is_nothrow<T>)
- {
- using namespace impl;
-
- static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
- "Retrieving values as wide-character strings with node::value_or() is only "
- "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
-
- if constexpr (is_wide_string<T>)
- {
+ } else
+ return static_cast<T>(*ref_cast<native_type_of<T>>());
+ }
+
+ template <typename T>
+ TOML_NODISCARD inline optional<T> node::value_exact()
+ const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ using namespace impl;
+
+ static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Retrieving values as wide-character strings with node::value_exact() is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ static_assert((is_native<T> || can_represent_native<T>) && !is_cvref<T>,
+ TOML_SA_VALUE_EXACT_FUNC_MESSAGE("return type of node::value_exact()"));
+
+ // prevent additional compiler error spam when the static_assert fails by gating behind if
+ // constexpr
+ if constexpr ((is_native<T> || can_represent_native<T>) && !is_cvref<T>) {
+ if (type() == node_type_of<T>)
+ return {this->get_value_exact<T>()};
+ else
+ return {};
+ }
+ }
+
+ template <typename T>
+ TOML_NODISCARD inline optional<T> node::value()
+ const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ using namespace impl;
+
+ static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Retrieving values as wide-character strings with node::value() is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+ static_assert((is_native<T> || can_represent_native<T> || can_partially_represent_native<T>) &&
+ !is_cvref<T>,
+ TOML_SA_VALUE_FUNC_MESSAGE("return type of node::value()"));
+
+ // when asking for strings, dates, times and date_times there's no 'fuzzy' conversion
+ // semantics to be mindful of so the exact retrieval is enough.
+ if constexpr (is_natively_one_of<T, std::string, time, date, date_time>) {
+ if (type() == node_type_of<T>)
+ return {this->get_value_exact<T>()};
+ else
+ return {};
+ }
+
+ // everything else requires a bit of logicking.
+ else {
+ switch (type()) {
+ // int -> *
+ case node_type::integer: {
+ // int -> int
+ if constexpr (is_natively_one_of<T, int64_t>) {
+ if constexpr (is_native<T> || can_represent_native<T>)
+ return static_cast<T>(*ref_cast<int64_t>());
+ else
+ return node_integer_cast<T>(*ref_cast<int64_t>());
+ }
+
+ // int -> float
+ else if constexpr (is_natively_one_of<T, double>) {
+ const int64_t val = *ref_cast<int64_t>();
+ if constexpr (std::numeric_limits<T>::digits < 64) {
+ constexpr auto largest_whole_float = (int64_t{1} << std::numeric_limits<T>::digits);
+ if (val < -largest_whole_float || val > largest_whole_float) return {};
+ }
+ return static_cast<T>(val);
+ }
+
+ // int -> bool
+ else if constexpr (is_natively_one_of<T, bool>)
+ return static_cast<bool>(*ref_cast<int64_t>());
+
+ // int -> anything else
+ else
+ return {};
+ }
+
+ // float -> *
+ case node_type::floating_point: {
+ // float -> float
+ if constexpr (is_natively_one_of<T, double>) {
+ if constexpr (is_native<T> || can_represent_native<T>)
+ return {static_cast<T>(*ref_cast<double>())};
+ else {
+ const double val = *ref_cast<double>();
+ if (impl::fpclassify(val) == fp_class::ok &&
+ (val < (std::numeric_limits<T>::lowest)() ||
+ val > (std::numeric_limits<T>::max)()))
+ return {};
+ return {static_cast<T>(val)};
+ }
+ }
+
+ // float -> int
+ else if constexpr (is_natively_one_of<T, int64_t>) {
+ const double val = *ref_cast<double>();
+ if (impl::fpclassify(val) == fp_class::ok &&
+ static_cast<double>(static_cast<int64_t>(val)) == val)
+ return node_integer_cast<T>(static_cast<int64_t>(val));
+ else
+ return {};
+ }
+
+ // float -> anything else
+ else
+ return {};
+ }
+
+ // bool -> *
+ case node_type::boolean: {
+ // bool -> bool
+ if constexpr (is_natively_one_of<T, bool>) return {*ref_cast<bool>()};
+
+ // bool -> int
+ else if constexpr (is_natively_one_of<T, int64_t>)
+ return {static_cast<T>(*ref_cast<bool>())};
+
+ // bool -> anything else
+ else
+ return {};
+ }
+ }
+
+ // non-values, or 'exact' types covered above
+ return {};
+ }
+ }
+
+ template <typename T>
+ TOML_NODISCARD inline auto node::value_or(T && default_value)
+ const noexcept(impl::value_retrieval_is_nothrow<T>) {
+ using namespace impl;
+
+ static_assert(!is_wide_string<T> || TOML_ENABLE_WINDOWS_COMPAT,
+ "Retrieving values as wide-character strings with node::value_or() is only "
+ "supported on Windows with TOML_ENABLE_WINDOWS_COMPAT enabled.");
+
+ if constexpr (is_wide_string<T>) {
#if TOML_ENABLE_WINDOWS_COMPAT
- if (type() == node_type::string)
- return widen(*ref_cast<std::string>());
- return std::wstring{ static_cast<T&&>(default_value) };
+ if (type() == node_type::string) return widen(*ref_cast<std::string>());
+ return std::wstring{static_cast<T&&>(default_value)};
#else
- static_assert(always_false<T>, "Evaluated unreachable branch!");
+ static_assert(always_false<T>, "Evaluated unreachable branch!");
#endif
- }
- else
- {
- using value_type =
- std::conditional_t<std::is_pointer_v<std::decay_t<T>>,
- std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
- std::decay_t<T>>;
- using traits = value_traits<value_type>;
+ } else {
+ using value_type = std::conditional_t<
+ std::is_pointer_v<std::decay_t<T>>,
+ std::add_pointer_t<std::add_const_t<std::remove_pointer_t<std::decay_t<T>>>>,
+ std::decay_t<T>>;
+ using traits = value_traits<value_type>;
- // clang-format off
+ // clang-format off
static_assert(
traits::is_native || traits::can_represent_native || traits::can_partially_represent_native,
@@ -1243,27 +999,25 @@ TOML_NAMESPACE_START
TOML_SA_LIST_END
);
- // clang-format on
-
- // prevent additional compiler error spam when the static_assert fails by gating behind if constexpr
- if constexpr (traits::is_native || traits::can_represent_native || traits::can_partially_represent_native)
- {
- if constexpr (traits::is_native)
- {
- if (type() == node_type_of<value_type>)
- return *ref_cast<typename traits::native_type>();
- }
- if (auto val = this->value<value_type>())
- return *val;
- if constexpr (std::is_pointer_v<value_type>)
- return value_type{ default_value };
- else
- return static_cast<T&&>(default_value);
- }
- }
- }
-
- /// \endcond
+ // clang-format on
+
+ // prevent additional compiler error spam when the static_assert fails by gating behind if
+ // constexpr
+ if constexpr (traits::is_native || traits::can_represent_native ||
+ traits::can_partially_represent_native) {
+ if constexpr (traits::is_native) {
+ if (type() == node_type_of<value_type>) return *ref_cast<typename traits::native_type>();
+ }
+ if (auto val = this->value<value_type>()) return *val;
+ if constexpr (std::is_pointer_v<value_type>)
+ return value_type{default_value};
+ else
+ return static_cast<T&&>(default_value);
+ }
+ }
+ }
+
+ /// \endcond
}
TOML_NAMESPACE_END;
diff --git a/vendor/toml++/impl/version.hpp b/vendor/toml++/impl/version.hpp
index 626691f..63a49be 100644
--- a/vendor/toml++/impl/version.hpp
+++ b/vendor/toml++/impl/version.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#define TOML_LIB_MAJOR 3
diff --git a/vendor/toml++/impl/yaml_formatter.hpp b/vendor/toml++/impl/yaml_formatter.hpp
index 1a3d24f..8d57156 100644
--- a/vendor/toml++/impl/yaml_formatter.hpp
+++ b/vendor/toml++/impl/yaml_formatter.hpp
@@ -1,7 +1,7 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#pragma once
#include "preprocessor.hpp"
@@ -10,130 +10,125 @@
#include "formatter.hpp"
#include "header_start.hpp"
-TOML_NAMESPACE_START
-{
- /// \brief A wrapper for printing TOML objects out to a stream as formatted YAML.
- ///
- /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
- ///
- /// \detail \cpp
- /// auto some_toml = toml::parse(R"(
- /// [fruit]
- /// apple.color = "red"
- /// apple.taste.sweet = true
- ///
- /// [fruit.apple.texture]
- /// smooth = true
- /// )"sv);
- /// std::cout << toml::yaml_formatter{ some_toml } << "\n";
- /// \ecpp
- ///
- /// \out
- /// fruit:
- /// apple:
- /// color: red
- /// taste:
- /// sweet: true
- /// texture:
- /// smooth: true
- /// \eout
- class TOML_EXPORTED_CLASS yaml_formatter : impl::formatter
- {
- private:
- /// \cond
-
- using base = impl::formatter;
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print_yaml_string(const value<std::string>&);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::table&, bool = false);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print(const toml::array&, bool = false);
-
- TOML_EXPORTED_MEMBER_FUNCTION
- void print();
-
- static constexpr impl::formatter_constants constants = {
- //
- format_flags::quote_dates_and_times | format_flags::indentation, // mandatory
- format_flags::allow_multi_line_strings, // ignored
- ".inf"sv,
- "-.inf"sv,
- ".NAN"sv,
- "true"sv,
- "false"sv
- };
-
- /// \endcond
-
- public:
- /// \brief The default flags for a yaml_formatter.
- static constexpr format_flags default_flags = constants.mandatory_flags //
- | format_flags::allow_literal_strings //
- | format_flags::allow_unicode_strings //
- | format_flags::allow_octal_integers //
- | format_flags::allow_hexadecimal_integers;
-
- /// \brief Constructs a YAML formatter and binds it to a TOML object.
- ///
- /// \param source The source TOML object.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit yaml_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
- : base{ &source, nullptr, constants, { flags, " "sv } }
- {}
+TOML_NAMESPACE_START {
+ /// \brief A wrapper for printing TOML objects out to a stream as formatted YAML.
+ ///
+ /// \availability This class is only available when #TOML_ENABLE_FORMATTERS is enabled.
+ ///
+ /// \detail \cpp
+ /// auto some_toml = toml::parse(R"(
+ /// [fruit]
+ /// apple.color = "red"
+ /// apple.taste.sweet = true
+ ///
+ /// [fruit.apple.texture]
+ /// smooth = true
+ /// )"sv);
+ /// std::cout << toml::yaml_formatter{ some_toml } << "\n";
+ /// \ecpp
+ ///
+ /// \out
+ /// fruit:
+ /// apple:
+ /// color: red
+ /// taste:
+ /// sweet: true
+ /// texture:
+ /// smooth: true
+ /// \eout
+ class TOML_EXPORTED_CLASS yaml_formatter : impl::formatter {
+ private:
+ /// \cond
+
+ using base = impl::formatter;
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print_yaml_string(const value<std::string>&);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::table&, bool = false);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print(const toml::array&, bool = false);
+
+ TOML_EXPORTED_MEMBER_FUNCTION
+ void print();
+
+ static constexpr impl::formatter_constants constants = {
+ //
+ format_flags::quote_dates_and_times | format_flags::indentation, // mandatory
+ format_flags::allow_multi_line_strings, // ignored
+ ".inf"sv,
+ "-.inf"sv,
+ ".NAN"sv,
+ "true"sv,
+ "false"sv};
+
+ /// \endcond
+
+ public:
+ /// \brief The default flags for a yaml_formatter.
+ static constexpr format_flags default_flags = constants.mandatory_flags //
+ | format_flags::allow_literal_strings //
+ | format_flags::allow_unicode_strings //
+ | format_flags::allow_octal_integers //
+ | format_flags::allow_hexadecimal_integers;
+
+ /// \brief Constructs a YAML formatter and binds it to a TOML object.
+ ///
+ /// \param source The source TOML object.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit yaml_formatter(const toml::node& source, format_flags flags = default_flags) noexcept
+ : base{&source, nullptr, constants, {flags, " "sv}} {}
#if TOML_DOXYGEN || (TOML_ENABLE_PARSER && !TOML_EXCEPTIONS)
- /// \brief Constructs a YAML formatter and binds it to a toml::parse_result.
- ///
- /// \availability This constructor is only available when exceptions are disabled.
- ///
- /// \attention Formatting a failed parse result will simply dump the error message out as-is.
- /// This will not be valid YAML, but at least gives you something to log or show up in diagnostics:
- /// \cpp
- /// std::cout << toml::yaml_formatter{ toml::parse("a = 'b'"sv) } // ok
- /// << "\n\n"
- /// << toml::yaml_formatter{ toml::parse("a = "sv) } // malformed
- /// << "\n";
- /// \ecpp
- /// \out
- /// a: b
- ///
- /// Error while parsing key-value pair: encountered end-of-file
- /// (error occurred at line 1, column 5)
- /// \eout
- /// Use the library with exceptions if you want to avoid this scenario.
- ///
- /// \param result The parse result.
- /// \param flags Format option flags.
- TOML_NODISCARD_CTOR
- explicit yaml_formatter(const toml::parse_result& result, format_flags flags = default_flags) noexcept
- : base{ nullptr, &result, constants, { flags, " "sv } }
- {}
+ /// \brief Constructs a YAML formatter and binds it to a toml::parse_result.
+ ///
+ /// \availability This constructor is only available when exceptions are disabled.
+ ///
+ /// \attention Formatting a failed parse result will simply dump the error message out as-is.
+ /// This will not be valid YAML, but at least gives you something to log or show up in
+ ///diagnostics:
+ /// \cpp
+ /// std::cout << toml::yaml_formatter{ toml::parse("a = 'b'"sv) } // ok
+ /// << "\n\n"
+ /// << toml::yaml_formatter{ toml::parse("a = "sv) } // malformed
+ /// << "\n";
+ /// \ecpp
+ /// \out
+ /// a: b
+ ///
+ /// Error while parsing key-value pair: encountered end-of-file
+ /// (error occurred at line 1, column 5)
+ /// \eout
+ /// Use the library with exceptions if you want to avoid this scenario.
+ ///
+ /// \param result The parse result.
+ /// \param flags Format option flags.
+ TOML_NODISCARD_CTOR
+ explicit yaml_formatter(const toml::parse_result& result,
+ format_flags flags = default_flags) noexcept
+ : base{nullptr, &result, constants, {flags, " "sv}} {}
#endif
- /// \brief Prints the bound TOML object out to the stream as YAML.
- friend std::ostream& TOML_CALLCONV operator<<(std::ostream& lhs, yaml_formatter& rhs)
- {
- rhs.attach(lhs);
- rhs.print();
- rhs.detach();
- return lhs;
- }
-
- /// \brief Prints the bound TOML object out to the stream as YAML (rvalue overload).
- friend std::ostream& TOML_CALLCONV operator<<(std::ostream& lhs, yaml_formatter&& rhs)
- {
- return lhs << rhs; // as lvalue
- }
- };
+ /// \brief Prints the bound TOML object out to the stream as YAML.
+ friend std::ostream& TOML_CALLCONV operator<<(std::ostream& lhs, yaml_formatter& rhs) {
+ rhs.attach(lhs);
+ rhs.print();
+ rhs.detach();
+ return lhs;
+ }
+
+ /// \brief Prints the bound TOML object out to the stream as YAML (rvalue overload).
+ friend std::ostream& TOML_CALLCONV operator<<(std::ostream& lhs, yaml_formatter&& rhs) {
+ return lhs << rhs; // as lvalue
+ }
+ };
}
TOML_NAMESPACE_END;
#include "header_end.hpp"
-#endif // TOML_ENABLE_FORMATTERS
+#endif // TOML_ENABLE_FORMATTERS
diff --git a/vendor/toml++/toml.hpp b/vendor/toml++/toml.hpp
index 7783f24..a25cef5 100644
--- a/vendor/toml++/toml.hpp
+++ b/vendor/toml++/toml.hpp
@@ -1,12 +1,12 @@
-//# This file is a part of toml++ and is subject to the the terms of the MIT license.
-//# Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
-//# See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
-// SPDX-License-Identifier: MIT
+// # This file is a part of toml++ and is subject to the the terms of the MIT license.
+// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
+// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
+// SPDX-License-Identifier: MIT
#ifndef TOMLPLUSPLUS_HPP
#define TOMLPLUSPLUS_HPP
-#define INCLUDE_TOMLPLUSPLUS_H // old guard name used pre-v3
-#define TOMLPLUSPLUS_H // guard name used in the legacy toml.h
+#define INCLUDE_TOMLPLUSPLUS_H // old guard name used pre-v3
+#define TOMLPLUSPLUS_H // guard name used in the legacy toml.h
#include "impl/preprocessor.hpp"
@@ -17,9 +17,9 @@ TOML_DISABLE_SUGGEST_ATTR_WARNINGS;
// misc warning false-positives
#if TOML_MSVC
-#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch
+#pragma warning(disable : 5031) // #pragma warning(pop): likely mismatch
#if TOML_SHARED_LIB
-#pragma warning(disable : 4251) // dll exports for std lib types
+#pragma warning(disable : 4251) // dll exports for std lib types
#endif
#elif TOML_CLANG
TOML_PRAGMA_CLANG(diagnostic ignored "-Wheader-hygiene")
@@ -31,49 +31,49 @@ TOML_PRAGMA_CLANG(diagnostic ignored "-Wreserved-identifier")
#endif
#endif
-#include "impl/std_new.hpp"
-#include "impl/std_string.hpp"
-#include "impl/std_optional.hpp"
-#include "impl/forward_declarations.hpp"
-#include "impl/print_to_stream.hpp"
-#include "impl/source_region.hpp"
-#include "impl/date_time.hpp"
+#include "impl/array.hpp"
#include "impl/at_path.hpp"
-#include "impl/path.hpp"
+#include "impl/date_time.hpp"
+#include "impl/formatter.hpp"
+#include "impl/forward_declarations.hpp"
+#include "impl/json_formatter.hpp"
+#include "impl/key.hpp"
+#include "impl/make_node.hpp"
#include "impl/node.hpp"
#include "impl/node_view.hpp"
-#include "impl/value.hpp"
-#include "impl/make_node.hpp"
-#include "impl/array.hpp"
-#include "impl/key.hpp"
-#include "impl/table.hpp"
-#include "impl/unicode_autogenerated.hpp"
-#include "impl/unicode.hpp"
#include "impl/parse_error.hpp"
#include "impl/parse_result.hpp"
#include "impl/parser.hpp"
-#include "impl/formatter.hpp"
+#include "impl/path.hpp"
+#include "impl/print_to_stream.hpp"
+#include "impl/source_region.hpp"
+#include "impl/std_new.hpp"
+#include "impl/std_optional.hpp"
+#include "impl/std_string.hpp"
+#include "impl/table.hpp"
#include "impl/toml_formatter.hpp"
-#include "impl/json_formatter.hpp"
+#include "impl/unicode.hpp"
+#include "impl/unicode_autogenerated.hpp"
+#include "impl/value.hpp"
#include "impl/yaml_formatter.hpp"
#if TOML_IMPLEMENTATION
-#include "impl/std_string.inl"
-#include "impl/print_to_stream.inl"
-#include "impl/node.inl"
+#include "impl/array.inl"
#include "impl/at_path.inl"
+#include "impl/formatter.inl"
+#include "impl/json_formatter.inl"
+#include "impl/node.inl"
+#include "impl/parser.inl"
#include "impl/path.inl"
-#include "impl/array.inl"
+#include "impl/print_to_stream.inl"
+#include "impl/std_string.inl"
#include "impl/table.inl"
-#include "impl/unicode.inl"
-#include "impl/parser.inl"
-#include "impl/formatter.inl"
#include "impl/toml_formatter.inl"
-#include "impl/json_formatter.inl"
+#include "impl/unicode.inl"
#include "impl/yaml_formatter.inl"
-#endif // TOML_IMPLEMENTATION
+#endif // TOML_IMPLEMENTATION
TOML_POP_WARNINGS;
@@ -228,4 +228,4 @@ TOML_POP_WARNINGS;
#undef TOML_WINDOWS
#endif
-#endif // TOMLPLUSPLUS_HPP
+#endif // TOMLPLUSPLUS_HPP