Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
table.hpp
Go to the documentation of this file.
1// # This file is a part of toml++ and is subject to the the terms of the MIT license.
2// # Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
3// # See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
4// SPDX-License-Identifier: MIT
5#pragma once
6
7#include "array.hpp"
9#include "header_start.hpp"
10#include "key.hpp"
11#include "make_node.hpp"
12#include "node_view.hpp"
14#include "std_map.hpp"
15
18 template <bool IsConst>
19 struct table_proxy_pair {
20 using value_type = std::conditional_t<IsConst, const node, node>;
21
22 const toml::key& first;
23 value_type& second;
24 };
25
26 template <bool IsConst>
27 class table_iterator {
28 private:
29 template <bool>
30 friend class table_iterator;
31
32 using proxy_type = table_proxy_pair<IsConst>;
33 using mutable_map_iterator = std::map<toml::key, node_ptr, std::less<>>::iterator;
34 using const_map_iterator = std::map<toml::key, node_ptr, std::less<>>::const_iterator;
35 using map_iterator = std::conditional_t<IsConst, const_map_iterator, mutable_map_iterator>;
36
37 mutable map_iterator iter_;
38 alignas(proxy_type) mutable unsigned char proxy_[sizeof(proxy_type)];
39 mutable bool proxy_instantiated_ = false;
40
42 proxy_type* get_proxy() const noexcept {
43 if (!proxy_instantiated_) {
44 auto p = ::new (static_cast<void*>(proxy_)) proxy_type{iter_->first, *iter_->second.get()};
45 proxy_instantiated_ = true;
46 return p;
47 } else
48 return TOML_LAUNDER(reinterpret_cast<proxy_type*>(proxy_));
49 }
50
51 public:
53 table_iterator() noexcept = default;
54
56 explicit table_iterator(mutable_map_iterator iter) noexcept //
57 : iter_{iter} {}
58
59 TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
61 explicit table_iterator(const_map_iterator iter) noexcept //
62 : iter_{iter} {}
63
64 TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
66 table_iterator(const table_iterator<false>& other) noexcept //
67 : iter_{other.iter_} {}
68
70 table_iterator(const table_iterator& other) noexcept //
71 : iter_{other.iter_} {}
72
73 table_iterator& operator=(const table_iterator& rhs) noexcept {
74 iter_ = rhs.iter_;
75 proxy_instantiated_ = false;
76 return *this;
77 }
78
79 using value_type = table_proxy_pair<IsConst>;
80 using reference = value_type&;
81 using pointer = value_type*;
82 using difference_type = typename std::iterator_traits<map_iterator>::difference_type;
83 using iterator_category = typename std::iterator_traits<map_iterator>::iterator_category;
84
85 table_iterator& operator++() noexcept // ++pre
86 {
87 ++iter_;
88 proxy_instantiated_ = false;
89 return *this;
90 }
91
92 table_iterator operator++(int) noexcept // post++
93 {
94 table_iterator out{iter_};
95 ++iter_;
96 proxy_instantiated_ = false;
97 return out;
98 }
99
100 table_iterator& operator--() noexcept // --pre
101 {
102 --iter_;
103 proxy_instantiated_ = false;
104 return *this;
105 }
106
107 table_iterator operator--(int) noexcept // post--
108 {
109 table_iterator out{iter_};
110 --iter_;
111 proxy_instantiated_ = false;
112 return out;
113 }
114
116 reference operator*() const noexcept { return *get_proxy(); }
117
119 pointer operator->() const noexcept { return get_proxy(); }
120
122 explicit operator const map_iterator&() const noexcept { return iter_; }
123
124 TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
126 explicit operator const const_map_iterator() const noexcept { return iter_; }
127
129 friend bool operator==(const table_iterator& lhs, const table_iterator& rhs) noexcept {
130 return lhs.iter_ == rhs.iter_;
131 }
132
134 friend bool operator!=(const table_iterator& lhs, const table_iterator& rhs) noexcept {
135 return lhs.iter_ != rhs.iter_;
136 }
137 };
138
139 struct table_init_pair {
140 mutable toml::key key;
141 mutable node_ptr value;
142
143 template <typename K, typename V>
144 TOML_NODISCARD_CTOR table_init_pair(K&& k, V&& v,
146 : key{static_cast<K&&>(k)}, value{make_node(static_cast<V&&>(v), flags)} {}
147 };
148}
151
154 using table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<false>);
155
157 using const_table_iterator = POXY_IMPLEMENTATION_DETAIL(impl::table_iterator<true>);
158
190 class TOML_EXPORTED_CLASS table : public node {
191 private:
193
194 using map_type = std::map<toml::key, impl::node_ptr, std::less<>>;
195 using map_pair = std::pair<const toml::key, impl::node_ptr>;
196 using map_iterator = typename map_type::iterator;
197 using const_map_iterator = typename map_type::const_iterator;
198 map_type map_;
199
200 bool inline_ = false;
201
204 table(const impl::table_init_pair*, const impl::table_init_pair*);
205
207
208 public:
212 table() noexcept;
213
215 ~table() noexcept;
216
220 table(const table&);
221
225 table(table&& other) noexcept;
226
245 explicit table(std::initializer_list<impl::table_init_pair> kvps) //
246 : table(kvps.begin(), kvps.end()) {}
247
251
254 table& operator=(table&& rhs) noexcept;
255
258
261 node_type type() const noexcept final { return node_type::table; }
262
265 bool is_homogeneous(node_type ntype) const noexcept final;
266
269 bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
270
273 bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
274
276 template <typename ElemType = void>
277 TOML_PURE_GETTER bool is_homogeneous() const noexcept {
278 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
279 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
280 "The template type argument of table::is_homogeneous() must be void or one "
281 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
282
283 return is_homogeneous(impl::node_type_of<type>);
284 }
286
289 bool is_table() const noexcept final { return true; }
290
293 bool is_array() const noexcept final { return false; }
294
297 bool is_array_of_tables() const noexcept final { return false; }
298
301 bool is_value() const noexcept final { return false; }
302
305 bool is_string() const noexcept final { return false; }
306
309 bool is_integer() const noexcept final { return false; }
310
313 bool is_floating_point() const noexcept final { return false; }
314
317 bool is_number() const noexcept final { return false; }
318
321 bool is_boolean() const noexcept final { return false; }
322
325 bool is_date() const noexcept final { return false; }
326
329 bool is_time() const noexcept final { return false; }
330
333 bool is_date_time() const noexcept final { return false; }
334
336
339
342 table* as_table() noexcept final { return this; }
343
346 array* as_array() noexcept final { return nullptr; }
347
350 toml::value<std::string>* as_string() noexcept final { return nullptr; }
351
354 toml::value<int64_t>* as_integer() noexcept final { return nullptr; }
355
358 toml::value<double>* as_floating_point() noexcept final { return nullptr; }
359
362 toml::value<bool>* as_boolean() noexcept final { return nullptr; }
363
366 toml::value<date>* as_date() noexcept final { return nullptr; }
367
370 toml::value<time>* as_time() noexcept final { return nullptr; }
371
374 toml::value<date_time>* as_date_time() noexcept final { return nullptr; }
375
378 const table* as_table() const noexcept final { return this; }
379
382 const array* as_array() const noexcept final { return nullptr; }
383
386 const toml::value<std::string>* as_string() const noexcept final { return nullptr; }
387
390 const toml::value<int64_t>* as_integer() const noexcept final { return nullptr; }
391
394 const toml::value<double>* as_floating_point() const noexcept final { return nullptr; }
395
398 const toml::value<bool>* as_boolean() const noexcept final { return nullptr; }
399
402 const toml::value<date>* as_date() const noexcept final { return nullptr; }
403
406 const toml::value<time>* as_time() const noexcept final { return nullptr; }
407
410 const toml::value<date_time>* as_date_time() const noexcept final { return nullptr; }
411
413
416
422 bool is_inline() const noexcept { return inline_; }
423
462 void is_inline(bool val) noexcept { inline_ = val; }
463
465
468
495 node* get(std::string_view key) noexcept;
496
503 const node* get(std::string_view key) const noexcept {
504 return const_cast<table&>(*this).get(key);
505 }
506
507#if TOML_ENABLE_WINDOWS_COMPAT
508
517 node* get(std::wstring_view key) {
518 if (empty()) return nullptr;
519
520 return get(impl::narrow(key));
521 }
522
531 const node* get(std::wstring_view key) const { return const_cast<table&>(*this).get(key); }
532
533#endif // TOML_ENABLE_WINDOWS_COMPAT
534
555 template <typename T>
556 TOML_PURE_GETTER impl::wrap_node<T>* get_as(std::string_view key) noexcept {
557 const auto n = this->get(key);
558 return n ? n->template as<T>() : nullptr;
559 }
560
568 template <typename T>
569 TOML_PURE_GETTER const impl::wrap_node<T>* get_as(std::string_view key) const noexcept {
570 return const_cast<table&>(*this).template get_as<T>(key);
571 }
572
573#if TOML_ENABLE_WINDOWS_COMPAT
574
584 template <typename T>
585 TOML_NODISCARD impl::wrap_node<T>* get_as(std::wstring_view key) {
586 if (empty()) return nullptr;
587
588 return get_as<T>(impl::narrow(key));
589 }
590
600 template <typename T>
601 TOML_NODISCARD const impl::wrap_node<T>* get_as(std::wstring_view key) const {
602 return const_cast<table&>(*this).template get_as<T>(key);
603 }
604
605#endif // TOML_ENABLE_WINDOWS_COMPAT
606
611 node& at(std::string_view key);
612
616 const node& at(std::string_view key) const { return const_cast<table&>(*this).at(key); }
617
618#if TOML_ENABLE_WINDOWS_COMPAT
619
625 node& at(std::wstring_view key) { return at(impl::narrow(key)); }
626
632 const node& at(std::wstring_view key) const { return const_cast<table&>(*this).at(key); }
633
634#endif // TOML_ENABLE_WINDOWS_COMPAT
635
637
640
642 using iterator = toml::table_iterator;
643
645 using const_iterator = toml::const_table_iterator;
646
649 iterator begin() noexcept { return iterator{map_.begin()}; }
650
653 const_iterator begin() const noexcept { return const_iterator{map_.cbegin()}; }
654
657 const_iterator cbegin() const noexcept { return const_iterator{map_.cbegin()}; }
658
661 iterator end() noexcept { return iterator{map_.end()}; }
662
665 const_iterator end() const noexcept { return const_iterator{map_.cend()}; }
666
669 const_iterator cend() const noexcept { return const_iterator{map_.cend()}; }
670
671 private:
673
674 template <typename T, typename Table>
675 using for_each_value_ref =
676 impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Table>;
677
678 template <typename Func, typename Table, typename T>
679 using can_for_each =
680 std::disjunction<std::is_invocable<Func, const key&, for_each_value_ref<T, Table>>, //
681 std::is_invocable<Func, for_each_value_ref<T, Table>>>;
682
683 template <typename Func, typename Table, typename T>
684 using can_for_each_nothrow = std::conditional_t<
685 // first form
686 std::is_invocable_v<Func, const key&, for_each_value_ref<T, Table>>,
687 std::is_nothrow_invocable<Func, const key&, for_each_value_ref<T, Table>>,
688 std::conditional_t<
689 // second form
690 std::is_invocable_v<Func, for_each_value_ref<T, Table>>,
691 std::is_nothrow_invocable<Func, for_each_value_ref<T, Table>>, std::false_type>>;
692
693 template <typename Func, typename Table>
694 using can_for_each_any =
695 std::disjunction<can_for_each<Func, Table, table>, can_for_each<Func, Table, array>,
696 can_for_each<Func, Table, std::string>, can_for_each<Func, Table, int64_t>,
697 can_for_each<Func, Table, double>, can_for_each<Func, Table, bool>,
698 can_for_each<Func, Table, date>, can_for_each<Func, Table, time>,
699 can_for_each<Func, Table, date_time>>;
700
701 template <typename Func, typename Table, typename T>
702 using for_each_is_nothrow_one =
703 std::disjunction<std::negation<can_for_each<Func, Table, T>>, //
704 can_for_each_nothrow<Func, Table, T>>;
705
706 template <typename Func, typename Table>
707 using for_each_is_nothrow = std::conjunction<
708 for_each_is_nothrow_one<Func, Table, table>, for_each_is_nothrow_one<Func, Table, array>,
709 for_each_is_nothrow_one<Func, Table, std::string>,
710 for_each_is_nothrow_one<Func, Table, int64_t>, for_each_is_nothrow_one<Func, Table, double>,
711 for_each_is_nothrow_one<Func, Table, bool>, for_each_is_nothrow_one<Func, Table, date>,
712 for_each_is_nothrow_one<Func, Table, time>,
713 for_each_is_nothrow_one<Func, Table, date_time>>;
714
715 template <typename Func, typename Table>
716 static void do_for_each(Func&& visitor, Table&& tbl) //
717 noexcept(for_each_is_nothrow<Func&&, Table&&>::value) {
718 static_assert(
719 can_for_each_any<Func&&, Table&&>::value,
720 "TOML table for_each visitors must be invocable for at least one of the toml::node "
721 "specializations:" TOML_SA_NODE_TYPE_LIST);
722
723 using kvp_type = impl::copy_cv<map_pair, std::remove_reference_t<Table>>;
724
725 for (kvp_type& kvp : tbl.map_) {
726 using node_ref = impl::copy_cvref<toml::node, Table&&>;
727 static_assert(std::is_reference_v<node_ref>);
728
729#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
730
731#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
732 static_assert(impl::always_false<Func, Table, kvp_type, node_ref>, //
733 TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
734#endif
735
736 static_cast<node_ref>(*kvp.second)
737 .visit([&]([[maybe_unused]] auto&& v) //
738 noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value) {
739 using value_ref = for_each_value_ref<decltype(v), Table&&>;
740 static_assert(std::is_reference_v<value_ref>);
741
742 // func(key, val)
743 if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>) {
744 static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
745 static_cast<value_ref>(v));
746 }
747
748 // func(val)
749 else if constexpr (std::is_invocable_v<Func&&, value_ref>) {
750 static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
751 }
752 });
753
754#else
755 const auto keep_going =
756 static_cast<node_ref>(*kvp.second)
757 .visit([&]([[maybe_unused]] auto&& v) //
758 noexcept(for_each_is_nothrow_one<Func&&, Table&&, decltype(v)>::value) {
759 using value_ref = for_each_value_ref<decltype(v), Table&&>;
760 static_assert(std::is_reference_v<value_ref>);
761
762 // func(key, val)
763 if constexpr (std::is_invocable_v<Func&&, const key&, value_ref>) {
764 using return_type = decltype(static_cast<Func&&>(visitor)(
765 static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
766
767 if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
768 return static_cast<bool>(static_cast<Func&&>(visitor)(
769 static_cast<const key&>(kvp.first), static_cast<value_ref>(v)));
770 } else {
771 static_cast<Func&&>(visitor)(static_cast<const key&>(kvp.first),
772 static_cast<value_ref>(v));
773 return true;
774 }
775 }
776
777 // func(val)
778 else if constexpr (std::is_invocable_v<Func&&, value_ref>) {
779 using return_type =
780 decltype(static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
781
782 if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
783 return static_cast<bool>(
784 static_cast<Func&&>(visitor)(static_cast<value_ref>(v)));
785 } else {
786 static_cast<Func&&>(visitor)(static_cast<value_ref>(v));
787 return true;
788 }
789 }
790
791 // visitor not compatible with this particular type
792 else
793 return true;
794 });
795
796 if (!keep_going) return;
797#endif
798 }
799 }
800
802
803 public:
886 template <typename Func>
887 table& for_each(Func&& visitor) & //
888 noexcept(for_each_is_nothrow<Func&&, table&>::value) {
889 do_for_each(static_cast<Func&&>(visitor), *this);
890 return *this;
891 }
892
894 template <typename Func>
895 table&& for_each(Func&& visitor) && //
896 noexcept(for_each_is_nothrow<Func&&, table&&>::value) {
897 do_for_each(static_cast<Func&&>(visitor), static_cast<table&&>(*this));
898 return static_cast<table&&>(*this);
899 }
900
902 template <typename Func>
903 const table& for_each(Func&& visitor) const& //
904 noexcept(for_each_is_nothrow<Func&&, const table&>::value) {
905 do_for_each(static_cast<Func&&>(visitor), *this);
906 return *this;
907 }
908
910 template <typename Func>
911 const table&& for_each(Func&& visitor) const&& //
912 noexcept(for_each_is_nothrow<Func&&, const table&&>::value) {
913 do_for_each(static_cast<Func&&>(visitor), static_cast<const table&&>(*this));
914 return static_cast<const table&&>(*this);
915 }
916
918
921
924 bool empty() const noexcept { return map_.empty(); }
925
928 size_t size() const noexcept { return map_.size(); }
929
931
934
935 private:
937
940 map_iterator get_lower_bound(std::string_view) noexcept;
941
943
944 public:
950 iterator lower_bound(std::string_view key) noexcept { return iterator{get_lower_bound(key)}; }
951
957 const_iterator lower_bound(std::string_view key) const noexcept {
958 return const_iterator{const_cast<table&>(*this).get_lower_bound(key)};
959 }
960
961#if TOML_ENABLE_WINDOWS_COMPAT
962
970 iterator lower_bound(std::wstring_view key) {
971 if (empty()) return end();
972
973 return lower_bound(impl::narrow(key));
974 }
975
983 const_iterator lower_bound(std::wstring_view key) const {
984 if (empty()) return end();
985
986 return lower_bound(impl::narrow(key));
987 }
988
989#endif // TOML_ENABLE_WINDOWS_COMPAT
990
998 iterator find(std::string_view key) noexcept;
999
1007 const_iterator find(std::string_view key) const noexcept;
1008
1011 bool contains(std::string_view key) const noexcept { return get(key) != nullptr; }
1012
1013#if TOML_ENABLE_WINDOWS_COMPAT
1014
1023 iterator find(std::wstring_view key) {
1024 if (empty()) return end();
1025
1026 return find(impl::narrow(key));
1027 }
1028
1037 const_iterator find(std::wstring_view key) const { return find(impl::narrow(key)); }
1038
1043 bool contains(std::wstring_view key) const { return contains(impl::narrow(key)); }
1044
1045#endif // TOML_ENABLE_WINDOWS_COMPAT
1046
1048
1051
1052 private:
1054
1056 map_iterator erase(const_map_iterator) noexcept;
1057
1059 map_iterator erase(const_map_iterator, const_map_iterator) noexcept;
1060
1062
1063 public:
1087 iterator erase(iterator pos) noexcept { return iterator{erase(const_map_iterator{pos})}; }
1088
1112 iterator erase(const_iterator pos) noexcept { return iterator{erase(const_map_iterator{pos})}; }
1113
1140 return iterator{erase(const_map_iterator{begin}, const_map_iterator{end})};
1141 }
1142
1169 size_t erase(std::string_view key) noexcept;
1170
1171#if TOML_ENABLE_WINDOWS_COMPAT
1172
1180 size_t erase(std::wstring_view key) {
1181 if (empty()) return false;
1182
1183 return erase(impl::narrow(key));
1184 }
1185
1186#endif // TOML_ENABLE_WINDOWS_COMPAT
1187
1208 table& prune(bool recursive = true) & noexcept;
1209
1215 table&& prune(bool recursive = true) && noexcept {
1216 return static_cast<toml::table&&>(this->prune(recursive));
1217 }
1218
1221 void clear() noexcept;
1222
1224
1227
1228 private:
1230
1232 map_iterator insert_with_hint(const_iterator, key&&, impl::node_ptr&&);
1233
1235
1236 public:
1251 TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
1252 typename ValueType = void, typename KeyType, typename... ValueArgs)
1253 iterator emplace_hint(const_iterator hint, KeyType&& key, ValueArgs&&... args) {
1254 static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
1255 "Emplacement using wide-character keys is only supported on Windows with "
1256 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
1257
1258 using raw_value_type = impl::remove_cvref<ValueType>;
1259 using value_type = std::conditional_t<std::is_void_v<raw_value_type>,
1260 impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
1261
1262 if constexpr (impl::is_wide_string<KeyType>) {
1263#if TOML_ENABLE_WINDOWS_COMPAT
1264 return emplace_hint<value_type>(hint, impl::narrow(static_cast<KeyType&&>(key)),
1265 static_cast<ValueArgs&&>(args)...);
1266#else
1267 static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
1268#endif
1269 } else {
1270 static constexpr auto moving_node_ptr =
1271 std::is_same_v<value_type, impl::node_ptr> //
1272 && sizeof...(ValueArgs) == 1u //
1273 && impl::first_is_same<impl::node_ptr&&, ValueArgs&&...>;
1274 using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
1275
1276 static_assert(moving_node_ptr //
1277 || impl::is_native<unwrapped_type> //
1278 || impl::is_one_of<unwrapped_type, table, array>, //
1279 "ValueType argument of table::emplace_hint() must be one "
1280 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
1281
1282 map_iterator ipos = insert_with_hint(hint, toml::key{static_cast<KeyType&&>(key)}, nullptr);
1283
1284 // if second is nullptr then we successully claimed the key and inserted the empty sentinel,
1285 // so now we have to construct the actual value
1286 if (!ipos->second) {
1287 if constexpr (moving_node_ptr)
1288 ipos->second = std::move(static_cast<ValueArgs&&>(args)...);
1289 else {
1290#if TOML_COMPILER_HAS_EXCEPTIONS
1291 try {
1292#endif
1293 ipos->second.reset(
1294 new impl::wrap_node<unwrapped_type>{static_cast<ValueArgs&&>(args)...});
1295#if TOML_COMPILER_HAS_EXCEPTIONS
1296 } catch (...) {
1297 erase(const_map_iterator{ipos}); // strong exception guarantee
1298 throw;
1299 }
1300#endif
1301 }
1302 }
1303 return iterator{ipos};
1304 }
1305 }
1306
1358 TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
1359 typename KeyType, typename ValueType)
1360 std::pair<iterator, bool> insert(KeyType&& key, ValueType&& val,
1362 static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
1363 "Insertion using wide-character keys is only supported on Windows with "
1364 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
1365
1366 if constexpr (is_node_view<ValueType>) {
1367 if (!val) return {end(), false};
1368 }
1369
1370 if constexpr (impl::is_wide_string<KeyType>) {
1371#if TOML_ENABLE_WINDOWS_COMPAT
1372 return insert(impl::narrow(static_cast<KeyType&&>(key)), static_cast<ValueType&&>(val),
1373 flags);
1374#else
1375 static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
1376#endif
1377 } else {
1378 const auto key_view = std::string_view{key};
1379 map_iterator ipos = get_lower_bound(key_view);
1380 if (ipos == map_.end() || ipos->first != key_view) {
1381 ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
1382 impl::make_node(static_cast<ValueType&&>(val), flags));
1383 return {iterator{ipos}, true};
1384 }
1385 return {iterator{ipos}, false};
1386 }
1387 }
1388
1428 TOML_CONSTRAINED_TEMPLATE((!is_key_or_convertible<Iter> && !impl::is_wide_string<Iter>),
1429 typename Iter)
1431 if (begin == end) return;
1432 for (auto it = begin; it != end; it++) {
1433 if constexpr (std::is_rvalue_reference_v<decltype(*it)>)
1434 insert(std::move((*it).first), std::move((*it).second), flags);
1435 else
1436 insert((*it).first, (*it).second, flags);
1437 }
1438 }
1439
1492 TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
1493 typename KeyType, typename ValueType)
1494 std::pair<iterator, bool> insert_or_assign(KeyType&& key, ValueType&& val,
1496 static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
1497 "Insertion using wide-character keys is only supported on Windows with "
1498 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
1499
1500 if constexpr (is_node_view<ValueType>) {
1501 if (!val) return {end(), false};
1502 }
1503
1504 if constexpr (impl::is_wide_string<KeyType>) {
1505#if TOML_ENABLE_WINDOWS_COMPAT
1506 return insert_or_assign(impl::narrow(static_cast<KeyType&&>(key)),
1507 static_cast<ValueType&&>(val), flags);
1508#else
1509 static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
1510#endif
1511 } else {
1512 const auto key_view = std::string_view{key};
1513 map_iterator ipos = get_lower_bound(key_view);
1514 if (ipos == map_.end() || ipos->first != key_view) {
1515 ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
1516 impl::make_node(static_cast<ValueType&&>(val), flags));
1517 return {iterator{ipos}, true};
1518 } else {
1519 (*ipos).second = impl::make_node(static_cast<ValueType&&>(val), flags);
1520 return {iterator{ipos}, false};
1521 }
1522 }
1523 }
1524
1564 TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible<KeyType&&> || impl::is_wide_string<KeyType>),
1565 typename ValueType = void, typename KeyType, typename... ValueArgs)
1566 std::pair<iterator, bool> emplace(KeyType&& key, ValueArgs&&... args) {
1567 static_assert(!impl::is_wide_string<KeyType> || TOML_ENABLE_WINDOWS_COMPAT,
1568 "Emplacement using wide-character keys is only supported on Windows with "
1569 "TOML_ENABLE_WINDOWS_COMPAT enabled.");
1570
1571 using raw_value_type = impl::remove_cvref<ValueType>;
1572 using value_type = std::conditional_t<std::is_void_v<raw_value_type>,
1573 impl::emplaced_type_of<ValueArgs&&...>, raw_value_type>;
1574
1575 if constexpr (impl::is_wide_string<KeyType>) {
1576#if TOML_ENABLE_WINDOWS_COMPAT
1577 return emplace<value_type>(impl::narrow(static_cast<KeyType&&>(key)),
1578 static_cast<ValueArgs&&>(args)...);
1579#else
1580 static_assert(impl::always_false<KeyType>, "Evaluated unreachable branch!");
1581#endif
1582 } else {
1583 using unwrapped_type = impl::remove_cvref<impl::unwrap_node<value_type>>;
1584 static_assert(
1585 (impl::is_native<unwrapped_type> || impl::is_one_of<unwrapped_type, table, array>),
1586 "ValueType argument of table::emplace() must be one "
1587 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
1588
1589 const auto key_view = std::string_view{key};
1590 auto ipos = get_lower_bound(key_view);
1591 if (ipos == map_.end() || ipos->first != key_view) {
1592 ipos = insert_with_hint(const_iterator{ipos}, toml::key{static_cast<KeyType&&>(key)},
1593 impl::node_ptr{new impl::wrap_node<unwrapped_type>{
1594 static_cast<ValueArgs&&>(args)...}});
1595 return {iterator{ipos}, true};
1596 }
1597 return {iterator{ipos}, false};
1598 }
1599 }
1600
1602
1605
1607 using node::operator[]; // inherit operator[toml::path]
1609
1622 node_view<node> operator[](std::string_view key) noexcept { return node_view<node>{get(key)}; }
1623
1636 node_view<const node> operator[](std::string_view key) const noexcept {
1637 return node_view<const node>{get(key)};
1638 }
1639
1640#if TOML_ENABLE_WINDOWS_COMPAT
1641
1656 node_view<node> operator[](std::wstring_view key) { return node_view<node>{get(key)}; }
1657
1672 node_view<const node> operator[](std::wstring_view key) const {
1673 return node_view<const node>{get(key)};
1674 }
1675
1676#endif // TOML_ENABLE_WINDOWS_COMPAT
1677
1679
1682
1683 private:
1685
1688 static bool TOML_CALLCONV equal(const table&, const table&) noexcept;
1689
1691 public:
1699 friend bool operator==(const table& lhs, const table& rhs) noexcept { return equal(lhs, rhs); }
1700
1708 friend bool operator!=(const table& lhs, const table& rhs) noexcept { return !equal(lhs, rhs); }
1709
1711
1712#if TOML_ENABLE_FORMATTERS
1713
1717 friend std::ostream& operator<<(std::ostream& lhs, const table& rhs) {
1718 impl::print_to_stream(lhs, rhs);
1719 return lhs;
1720 }
1721
1722#endif
1723 };
1724}
1726
1727#include "header_end.hpp"
#define k
Definition 17.names.cpp:128
#define rhs
Definition 17.names.cpp:536
#define hint
Definition 17.names.cpp:473
#define v
Definition 17.names.cpp:138
#define lhs
Definition 17.names.cpp:489
#define n
Definition 17.names.cpp:130
#define val
Definition 17.names.cpp:570
#define p
Definition 17.names.cpp:132
#define V
Definition 17.names.cpp:165
#define pos
Definition 17.names.cpp:518
bool equal(const T &x, const U &y)
#define flags
const plus_asgn< T > & operator*(const plus_asgn< T > &lhs, const plus_asgn< T > &rhs)
T value(const T &val)
const int end
const int out
std::ostream_iterator< int, char, std::char_traits< char > > Iter
Definition alg7.cpp:64
A TOML array.
Definition array.hpp:258
A TOML table.
Definition table.hpp:190
TOML_PURE_INLINE_GETTER const_iterator begin() const noexcept
Returns an iterator to the first key-value pair.
Definition table.hpp:653
TOML_EXPORTED_MEMBER_FUNCTION table & prune(bool recursive=true) &noexcept
Removes empty child arrays and tables.
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, node *&first_nonmatch) noexcept final
TOML_NODISCARD const impl::wrap_node< T > * get_as(std::wstring_view key) const
Gets the node at a specific key if it is a particular type (const overload).
Definition table.hpp:601
TOML_CONST_INLINE_GETTER bool is_date_time() const noexcept final
Returns false.
Definition table.hpp:333
TOML_NODISCARD node * get(std::wstring_view key)
Gets the node at a specific key.
Definition table.hpp:517
TOML_NODISCARD const node & at(std::string_view key) const
Gets a reference to the element at a specific key, throwing std::out_of_range if none existed.
Definition table.hpp:616
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION node & at(std::string_view key)
Gets a reference to the element at a specific key, throwing std::out_of_range if none existed.
TOML_CONST_INLINE_GETTER bool is_string() const noexcept final
Returns false.
Definition table.hpp:305
TOML_PURE_INLINE_GETTER const node * get(std::string_view key) const noexcept
Gets the node at a specific key (const overload).
Definition table.hpp:503
TOML_CONST_INLINE_GETTER const toml::value< std::string > * as_string() const noexcept final
Returns nullptr.
Definition table.hpp:386
TOML_NODISCARD bool contains(std::wstring_view key) const
Returns true if the table contains a node at the given key.
Definition table.hpp:1043
TOML_CONST_INLINE_GETTER bool is_number() const noexcept final
Returns false.
Definition table.hpp:317
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION table() noexcept
Default constructor.
TOML_NODISCARD impl::wrap_node< T > * get_as(std::wstring_view key)
Gets the node at a specific key if it is a particular type.
Definition table.hpp:585
iterator erase(const_iterator pos) noexcept
Removes the specified key-value pair from the table (const iterator overload).
Definition table.hpp:1112
table && for_each(Func &&visitor) &&noexcept(for_each_is_nothrow< Func &&, table && >::value)
Invokes a visitor on each key-value pair in the table (rvalue overload).
Definition table.hpp:895
TOML_CONST_INLINE_GETTER const toml::value< double > * as_floating_point() const noexcept final
Returns nullptr.
Definition table.hpp:394
TOML_CONST_INLINE_GETTER toml::value< bool > * as_boolean() noexcept final
Returns nullptr.
Definition table.hpp:362
size_t erase(std::wstring_view key)
Removes the value with the given key from the table.
Definition table.hpp:1180
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION node * get(std::string_view key) noexcept
Gets the node at a specific key.
TOML_CONST_INLINE_GETTER const toml::value< int64_t > * as_integer() const noexcept final
Returns nullptr.
Definition table.hpp:390
table & for_each(Func &&visitor) &noexcept(for_each_is_nothrow< Func &&, table & >::value)
Invokes a visitor on each key-value pair in the table.
Definition table.hpp:887
TOML_PURE_INLINE_GETTER bool empty() const noexcept
Returns true if the table is empty.
Definition table.hpp:924
TOML_CONST_INLINE_GETTER const toml::value< time > * as_time() const noexcept final
Returns nullptr.
Definition table.hpp:406
TOML_NODISCARD node_view< node > operator[](std::wstring_view key)
Gets a node_view for the selected value.
Definition table.hpp:1656
TOML_PURE_GETTER bool contains(std::string_view key) const noexcept
Returns true if the table contains a node at the given key.
Definition table.hpp:1011
const table && for_each(Func &&visitor) const &&noexcept(for_each_is_nothrow< Func &&, const table && >::value)
Invokes a visitor on each key-value pair in the table (const rvalue overload).
Definition table.hpp:911
TOML_CONST_INLINE_GETTER bool is_array() const noexcept final
Returns false.
Definition table.hpp:293
TOML_CONST_INLINE_GETTER node_type type() const noexcept final
Returns #toml::node_type::table.
Definition table.hpp:261
TOML_CONSTRAINED_TEMPLATE((!is_key_or_convertible< Iter > &&!impl::is_wide_string< Iter >), typename Iter) void insert(Iter begin
Inserts a series of key-value pairs into the table.
TOML_CONST_INLINE_GETTER array * as_array() noexcept final
Returns nullptr.
Definition table.hpp:346
iterator erase(const_iterator begin, const_iterator end) noexcept
Removes the key-value pairs in the range [first, last) from the table.
Definition table.hpp:1139
TOML_NODISCARD const node & at(std::wstring_view key) const
Gets a reference to the element at a specific key, throwing std::out_of_range if none existed.
Definition table.hpp:632
toml::const_table_iterator const_iterator
A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
Definition table.hpp:645
TOML_NODISCARD node_view< const node > operator[](std::wstring_view key) const
Gets a node_view for the selected value (const overload).
Definition table.hpp:1672
TOML_EXPORTED_MEMBER_FUNCTION table & operator=(table &&rhs) noexcept
Move-assignment operator.
TOML_EXPORTED_MEMBER_FUNCTION size_t erase(std::string_view key) noexcept
Removes the value with the given key from the table.
TOML_PURE_GETTER impl::wrap_node< T > * get_as(std::string_view key) noexcept
Gets the node at a specific key if it is a particular type.
Definition table.hpp:556
TOML_EXPORTED_MEMBER_FUNCTION void clear() noexcept
Removes all key-value pairs from the table.
toml::table_iterator iterator
A BidirectionalIterator for iterating over key-value pairs in a toml::table.
Definition table.hpp:642
TOML_NODISCARD node_view< node > operator[](std::string_view key) noexcept
Gets a node_view for the selected value.
Definition table.hpp:1622
impl::remove_cvref< ValueType > raw_value_type
Definition table.hpp:1258
TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible< KeyType && >||impl::is_wide_string< KeyType >), typename ValueType=void, typename KeyType, typename... ValueArgs) std
Emplaces a new value at a specific key if one did not already exist.
Definition table.hpp:1564
TOML_PURE_GETTER const_iterator lower_bound(std::string_view key) const noexcept
Returns a const iterator to the first key-value pair with key that is not less than the given key.
Definition table.hpp:957
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype) const noexcept final
TOML_CONST_INLINE_GETTER table * as_table() noexcept final
Returns a pointer to the table.
Definition table.hpp:342
TOML_EXPORTED_MEMBER_FUNCTION table & operator=(const table &)
Copy-assignment operator.
TOML_CONST_INLINE_GETTER toml::value< time > * as_time() noexcept final
Returns nullptr.
Definition table.hpp:370
TOML_PURE_INLINE_GETTER const_iterator end() const noexcept
Returns an iterator to one-past-the-last key-value pair.
Definition table.hpp:665
TOML_CONST_INLINE_GETTER const toml::value< date_time > * as_date_time() const noexcept final
Returns nullptr.
Definition table.hpp:410
TOML_PURE_INLINE_GETTER iterator begin() noexcept
Returns an iterator to the first key-value pair.
Definition table.hpp:649
TOML_NODISCARD node_view< const node > operator[](std::string_view key) const noexcept
Gets a node_view for the selected value (const overload).
Definition table.hpp:1636
TOML_CONST_INLINE_GETTER bool is_table() const noexcept final
Returns true.
Definition table.hpp:289
TOML_CONST_INLINE_GETTER bool is_value() const noexcept final
Returns false.
Definition table.hpp:301
TOML_NODISCARD friend bool operator==(const table &lhs, const table &rhs) noexcept
Equality operator.
Definition table.hpp:1699
TOML_CONST_INLINE_GETTER const table * as_table() const noexcept final
Returns a const-qualified pointer to the table.
Definition table.hpp:378
friend std::ostream & operator<<(std::ostream &lhs, const table &rhs)
Prints the table out to a stream as formatted TOML.
Definition table.hpp:1717
TOML_CONST_INLINE_GETTER bool is_boolean() const noexcept final
Returns false.
Definition table.hpp:321
TOML_CONSTRAINED_TEMPLATE((is_key_or_convertible< KeyType && >||impl::is_wide_string< KeyType >), typename KeyType, typename ValueType) std
Inserts a new value at a specific key if one did not already exist.
Definition table.hpp:1358
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION const_iterator find(std::string_view key) const noexcept
Gets an iterator to the node at a specific key (const overload)
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION iterator find(std::string_view key) noexcept
Gets an iterator to the node at a specific key.
TOML_NODISCARD iterator find(std::wstring_view key)
Gets an iterator to the node at a specific key.
Definition table.hpp:1023
TOML_CONST_INLINE_GETTER toml::value< int64_t > * as_integer() noexcept final
Returns nullptr.
Definition table.hpp:354
TOML_NODISCARD const_iterator lower_bound(std::wstring_view key) const
Returns a const iterator to the first key-value pair with key that is not less than the given key.
Definition table.hpp:983
const table & for_each(Func &&visitor) const &noexcept(for_each_is_nothrow< Func &&, const table & >::value)
Invokes a visitor on each key-value pair in the table (const lvalue overload).
Definition table.hpp:903
table && prune(bool recursive=true) &&noexcept
Removes empty child arrays and tables (rvalue overload).
Definition table.hpp:1215
TOML_CONST_INLINE_GETTER bool is_floating_point() const noexcept final
Returns false.
Definition table.hpp:313
TOML_PURE_INLINE_GETTER const_iterator cbegin() const noexcept
Returns an iterator to the first key-value pair.
Definition table.hpp:657
TOML_CONST_INLINE_GETTER bool is_date() const noexcept final
Returns false.
Definition table.hpp:325
TOML_PURE_INLINE_GETTER iterator end() noexcept
Returns an iterator to one-past-the-last key-value pair.
Definition table.hpp:661
impl::remove_cvref< impl::unwrap_node< value_type > > unwrapped_type
Definition table.hpp:1274
TOML_CONST_INLINE_GETTER toml::value< date > * as_date() noexcept final
Returns nullptr.
Definition table.hpp:366
TOML_PURE_INLINE_GETTER bool is_inline() const noexcept
Returns true if this table is an inline table.
Definition table.hpp:422
TOML_CONST_INLINE_GETTER const array * as_array() const noexcept final
Returns nullptr.
Definition table.hpp:382
TOML_PURE_GETTER const impl::wrap_node< T > * get_as(std::string_view key) const noexcept
Gets the node at a specific key if it is a particular type (const overload).
Definition table.hpp:569
TOML_NODISCARD friend bool operator!=(const table &lhs, const table &rhs) noexcept
Inequality operator.
Definition table.hpp:1708
TOML_CONST_INLINE_GETTER const toml::value< date > * as_date() const noexcept final
Returns nullptr.
Definition table.hpp:402
TOML_NODISCARD const_iterator find(std::wstring_view key) const
Gets an iterator to the node at a specific key (const overload).
Definition table.hpp:1037
TOML_CONST_INLINE_GETTER toml::value< double > * as_floating_point() noexcept final
Returns nullptr.
Definition table.hpp:358
TOML_PURE_GETTER iterator lower_bound(std::string_view key) noexcept
Returns an iterator to the first key-value pair with key that is not less than the given key.
Definition table.hpp:950
TOML_CONST_INLINE_GETTER toml::value< date_time > * as_date_time() noexcept final
Returns nullptr.
Definition table.hpp:374
TOML_NODISCARD iterator lower_bound(std::wstring_view key)
Returns an iterator to the first key-value pair with key that is not less than the given key.
Definition table.hpp:970
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, const node *&first_nonmatch) const noexcept final
TOML_PURE_GETTER bool is_array_of_tables() const noexcept final
Returns false.
Definition table.hpp:297
TOML_CONST_INLINE_GETTER bool is_integer() const noexcept final
Returns false.
Definition table.hpp:309
TOML_CONST_INLINE_GETTER const toml::value< bool > * as_boolean() const noexcept final
Returns nullptr.
Definition table.hpp:398
void is_inline(bool val) noexcept
Sets whether this table is a TOML inline table.
Definition table.hpp:462
TOML_PURE_INLINE_GETTER const_iterator cend() const noexcept
Returns an iterator to one-past-the-last key-value pair.
Definition table.hpp:669
TOML_NODISCARD const node * get(std::wstring_view key) const
Gets the node at a specific key (const overload).
Definition table.hpp:531
TOML_CONST_INLINE_GETTER bool is_time() const noexcept final
Returns false.
Definition table.hpp:329
TOML_CONST_INLINE_GETTER toml::value< std::string > * as_string() noexcept final
Returns nullptr.
Definition table.hpp:350
std::conditional_t< std::is_void_v< raw_value_type >, impl::emplaced_type_of< ValueArgs &&... >, raw_value_type > value_type
Definition table.hpp:1260
TOML_NODISCARD node & at(std::wstring_view key)
Gets a reference to the element at a specific key, throwing std::out_of_range if none existed.
Definition table.hpp:625
iterator erase(iterator pos) noexcept
Removes the specified key-value pair from the table.
Definition table.hpp:1087
TOML_PURE_INLINE_GETTER size_t size() const noexcept
Returns the number of key-value pairs in the table.
Definition table.hpp:928
enum TOML_OPEN_FLAGS_ENUM value_flags
Metadata associated with TOML values.
constexpr value_flags preserve_source_value_flags
Special #toml::value_flags constant used for array + table insert functions to specify that any value...
#define TOML_CALLCONV
Calling convention to apply to exported free/static functions. \detail Not defined by default (let th...
#define TOML_EXPORTED_CLASS
An 'export' annotation to add to classes. \detail Not defined by default.
#define TOML_EXPORTED_STATIC_FUNCTION
An 'export' annotation to add to static class member functions. \detail Not defined by default.
#define TOML_ENABLE_WINDOWS_COMPAT
Enables the use of wide strings (wchar_t, std::wstring) in various places throughout the library when...
#define TOML_EXPORTED_MEMBER_FUNCTION
An 'export' annotation to add to non-static class member functions. \detail Not defined by default.
bool operator==(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14737
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14762
constexpr bool is_key_or_convertible
Metafunction for determining if a type is, or is a reference to, a toml::key, or is implicitly or exp...
Definition key.hpp:252
Definition json.h:5363
#define TOML_NODISCARD_CTOR
#define POXY_IMPLEMENTATION_DETAIL(...)
#define TOML_CONSTRAINED_TEMPLATE(condition,...)
#define TOML_NODISCARD
#define TOML_PURE_GETTER
#define TOML_PURE_INLINE_GETTER
#define TOML_IMPL_NAMESPACE_END
#define TOML_IMPL_NAMESPACE_START
#define TOML_CONST_INLINE_GETTER
#define TOML_LAUNDER(x)
Definition std_new.hpp:18
TOML_NAMESPACE_START
Definition table.hpp:152
POXY_IMPLEMENTATION_DETAIL(impl::table_iterator< true >) const_table_iterator
A BidirectionalIterator for iterating over const key-value pairs in a toml::table.
Definition table.hpp:157
TOML_NAMESPACE_END
Definition table.hpp:1725