Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
array.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 "header_start.hpp"
8#include "make_node.hpp"
10#include "std_utility.hpp"
11#include "std_vector.hpp"
12#include "value.hpp"
13
14#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
15#if TOML_GCC && TOML_GCC <= 7
16#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN 1
17#else
18#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN 0
19#endif
20#endif
21
22#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN && \
23 !defined(TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED)
24#define TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE \
25 "If you're seeing this error it's because you're using one of toml++'s for_each() functions on " \
26 "a compiler with " \
27 "known bugs in that area (e.g. GCC 7). On these compilers returning a bool (or " \
28 "bool-convertible) value from the " \
29 "for_each() callable causes spurious compilation failures, while returning nothing (void) " \
30 "works fine. " \
31 "If you believe this message is incorrect for your compiler, you can try your luck by " \
32 "#defining " \
33 "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN as 0 and recompiling - if it works, great! Let me know " \
34 "at " \
35 "https://github.com/marzer/tomlplusplus/issues. Alternatively, if you don't have any need for " \
36 "early-exiting from " \
37 "for_each(), you can suppress this error by #defining " \
38 "TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED " \
39 "and moving on with your life."
40#endif
41
44 template <bool IsConst>
45 class TOML_TRIVIAL_ABI array_iterator {
46 private:
47 template <bool>
48 friend class array_iterator;
49
50 using mutable_vector_iterator = std::vector<node_ptr>::iterator;
51 using const_vector_iterator = std::vector<node_ptr>::const_iterator;
52 using vector_iterator =
53 std::conditional_t<IsConst, const_vector_iterator, mutable_vector_iterator>;
54
55 mutable vector_iterator iter_;
56
57 public:
58 using value_type = std::conditional_t<IsConst, const node, node>;
59 using reference = value_type&;
60 using pointer = value_type*;
61 using difference_type = ptrdiff_t;
62 using iterator_category = typename std::iterator_traits<vector_iterator>::iterator_category;
63
65 array_iterator() noexcept = default;
66
68 explicit array_iterator(mutable_vector_iterator iter) noexcept //
69 : iter_{iter} {}
70
71 TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
73 explicit array_iterator(const_vector_iterator iter) noexcept //
74 : iter_{iter} {}
75
76 TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
78 array_iterator(const array_iterator<false>& other) noexcept //
79 : iter_{other.iter_} {}
80
82 array_iterator(const array_iterator&) noexcept = default;
83
84 array_iterator& operator=(const array_iterator&) noexcept = default;
85
86 array_iterator& operator++() noexcept // ++pre
87 {
88 ++iter_;
89 return *this;
90 }
91
92 array_iterator operator++(int) noexcept // post++
93 {
94 array_iterator out{iter_};
95 ++iter_;
96 return out;
97 }
98
99 array_iterator& operator--() noexcept // --pre
100 {
101 --iter_;
102 return *this;
103 }
104
105 array_iterator operator--(int) noexcept // post--
106 {
107 array_iterator out{iter_};
108 --iter_;
109 return out;
110 }
111
113 reference operator*() const noexcept { return *iter_->get(); }
114
116 pointer operator->() const noexcept { return iter_->get(); }
117
119 explicit operator const vector_iterator&() const noexcept { return iter_; }
120
121 TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
123 explicit operator const const_vector_iterator() const noexcept { return iter_; }
124
125 array_iterator& operator+=(ptrdiff_t rhs) noexcept {
126 iter_ += rhs;
127 return *this;
128 }
129
130 array_iterator& operator-=(ptrdiff_t rhs) noexcept {
131 iter_ -= rhs;
132 return *this;
133 }
134
136 friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept {
137 return array_iterator{lhs.iter_ + rhs};
138 }
139
141 friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept {
142 return array_iterator{rhs.iter_ + lhs};
143 }
144
146 friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept {
147 return array_iterator{lhs.iter_ - rhs};
148 }
149
151 friend ptrdiff_t operator-(const array_iterator& lhs, const array_iterator& rhs) noexcept {
152 return lhs.iter_ - rhs.iter_;
153 }
154
156 friend bool operator==(const array_iterator& lhs, const array_iterator& rhs) noexcept {
157 return lhs.iter_ == rhs.iter_;
158 }
159
161 friend bool operator!=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
162 return lhs.iter_ != rhs.iter_;
163 }
164
166 friend bool operator<(const array_iterator& lhs, const array_iterator& rhs) noexcept {
167 return lhs.iter_ < rhs.iter_;
168 }
169
171 friend bool operator<=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
172 return lhs.iter_ <= rhs.iter_;
173 }
174
176 friend bool operator>(const array_iterator& lhs, const array_iterator& rhs) noexcept {
177 return lhs.iter_ > rhs.iter_;
178 }
179
181 friend bool operator>=(const array_iterator& lhs, const array_iterator& rhs) noexcept {
182 return lhs.iter_ >= rhs.iter_;
183 }
184
186 reference operator[](ptrdiff_t idx) const noexcept { return *(iter_ + idx)->get(); }
187 };
188
189 struct array_init_elem {
190 mutable node_ptr value;
191
192 template <typename T>
193 TOML_NODISCARD_CTOR array_init_elem(T&& val,
195 : value{make_node(static_cast<T&&>(val), flags)} {}
196 };
197}
200
203 using array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<false>);
204
206 using const_array_iterator = POXY_IMPLEMENTATION_DETAIL(impl::array_iterator<true>);
207
258 class TOML_EXPORTED_CLASS array : public node {
259 private:
261
262 using vector_type = std::vector<impl::node_ptr>;
263 using vector_iterator = typename vector_type::iterator;
264 using const_vector_iterator = typename vector_type::const_iterator;
265 vector_type elems_;
266
269 array(const impl::array_init_elem*, const impl::array_init_elem*);
270
272 array(std::false_type, std::initializer_list<impl::array_init_elem> elems) //
273 : array{elems.begin(), elems.end()} {}
274
276 void preinsertion_resize(size_t idx, size_t count);
277
279 void insert_at_back(impl::node_ptr&&);
280
282 vector_iterator insert_at(const_vector_iterator, impl::node_ptr&&);
283
284 template <typename T>
285 void emplace_back_if_not_empty_view(T&& val, value_flags flags) {
286 if constexpr (is_node_view<T>) {
287 if (!val) return;
288 }
289 insert_at_back(impl::make_node(static_cast<T&&>(val), flags));
290 }
291
294 size_t total_leaf_count() const noexcept;
295
297 void flatten_child(array&& child, size_t& dest_index) noexcept;
298
300
301 public:
302 using value_type = node;
303 using size_type = size_t;
304 using difference_type = ptrdiff_t;
305 using reference = node&;
306 using const_reference = const node&;
307
311 array() noexcept;
312
314 ~array() noexcept;
315
319 array(const array&);
320
324 array(array&& other) noexcept;
325
358 TOML_CONSTRAINED_TEMPLATE((sizeof...(ElemTypes) > 0 ||
359 !std::is_same_v<impl::remove_cvref<ElemType>, array>),
360 typename ElemType, typename... ElemTypes)
362 explicit array(ElemType&& val, ElemTypes&&... vals)
363 : array{std::false_type{},
364 std::initializer_list<impl::array_init_elem>{static_cast<ElemType&&>(val),
365 static_cast<ElemTypes&&>(vals)...}} {}
366
369 array& operator=(const array&);
370
373 array& operator=(array&& rhs) noexcept;
374
377
380 node_type type() const noexcept final { return node_type::array; }
381
384 bool is_homogeneous(node_type ntype) const noexcept final;
385
388 bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept final;
389
392 bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept final;
393
395 template <typename ElemType = void>
396 TOML_PURE_GETTER bool is_homogeneous() const noexcept {
397 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
398 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
399 "The template type argument of array::is_homogeneous() must be void or one "
400 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
401
402 return is_homogeneous(impl::node_type_of<type>);
403 }
405
408 bool is_table() const noexcept final { return false; }
409
412 bool is_array() const noexcept final { return true; }
413
416 bool is_array_of_tables() const noexcept final { return is_homogeneous(node_type::table); }
417
420 bool is_value() const noexcept final { return false; }
421
424 bool is_string() const noexcept final { return false; }
425
428 bool is_integer() const noexcept final { return false; }
429
432 bool is_floating_point() const noexcept final { return false; }
433
436 bool is_number() const noexcept final { return false; }
437
440 bool is_boolean() const noexcept final { return false; }
441
444 bool is_date() const noexcept final { return false; }
445
448 bool is_time() const noexcept final { return false; }
449
452 bool is_date_time() const noexcept final { return false; }
453
455
458
461 table* as_table() noexcept final { return nullptr; }
462
465 array* as_array() noexcept final { return this; }
466
469 toml::value<std::string>* as_string() noexcept final { return nullptr; }
470
473 toml::value<int64_t>* as_integer() noexcept final { return nullptr; }
474
477 toml::value<double>* as_floating_point() noexcept final { return nullptr; }
478
481 toml::value<bool>* as_boolean() noexcept final { return nullptr; }
482
485 toml::value<date>* as_date() noexcept final { return nullptr; }
486
489 toml::value<time>* as_time() noexcept final { return nullptr; }
490
493 toml::value<date_time>* as_date_time() noexcept final { return nullptr; }
494
497 const table* as_table() const noexcept final { return nullptr; }
498
501 const array* as_array() const noexcept final { return this; }
502
505 const toml::value<std::string>* as_string() const noexcept final { return nullptr; }
506
509 const toml::value<int64_t>* as_integer() const noexcept final { return nullptr; }
510
513 const toml::value<double>* as_floating_point() const noexcept final { return nullptr; }
514
517 const toml::value<bool>* as_boolean() const noexcept final { return nullptr; }
518
521 const toml::value<date>* as_date() const noexcept final { return nullptr; }
522
525 const toml::value<time>* as_time() const noexcept final { return nullptr; }
526
529 const toml::value<date_time>* as_date_time() const noexcept final { return nullptr; }
530
532
535
558 node* get(size_t index) noexcept {
559 return index < elems_.size() ? elems_[index].get() : nullptr;
560 }
561
568 const node* get(size_t index) const noexcept { return const_cast<array&>(*this).get(index); }
569
587 template <typename ElemType>
588 TOML_NODISCARD impl::wrap_node<ElemType>* get_as(size_t index) noexcept {
589 if (auto val = get(index)) return val->template as<ElemType>();
590 return nullptr;
591 }
592
601 template <typename ElemType>
602 TOML_NODISCARD const impl::wrap_node<ElemType>* get_as(size_t index) const noexcept {
603 return const_cast<array&>(*this).template get_as<ElemType>(index);
604 }
605
607 using node::operator[]; // inherit operator[toml::path]
609
612 node& operator[](size_t index) noexcept { return *elems_[index]; }
613
616 const node& operator[](size_t index) const noexcept { return *elems_[index]; }
617
622 node& at(size_t index);
623
627 const node& at(size_t index) const { return const_cast<array&>(*this).at(index); }
628
631 node& front() noexcept { return *elems_.front(); }
632
635 const node& front() const noexcept { return *elems_.front(); }
636
639 node& back() noexcept { return *elems_.back(); }
640
643 const node& back() const noexcept { return *elems_.back(); }
644
646
649
651 using iterator = array_iterator;
652
655
658 iterator begin() noexcept { return iterator{elems_.begin()}; }
659
662 const_iterator begin() const noexcept { return const_iterator{elems_.cbegin()}; }
663
666 const_iterator cbegin() const noexcept { return const_iterator{elems_.cbegin()}; }
667
670 iterator end() noexcept { return iterator{elems_.end()}; }
671
674 const_iterator end() const noexcept { return const_iterator{elems_.cend()}; }
675
678 const_iterator cend() const noexcept { return const_iterator{elems_.cend()}; }
679
680 private:
682
683 template <typename T, typename Array>
684 using for_each_elem_ref =
685 impl::copy_cvref<impl::wrap_node<impl::remove_cvref<impl::unwrap_node<T>>>, Array>;
686
687 template <typename Func, typename Array, typename T>
688 using can_for_each =
689 std::disjunction<std::is_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
690 std::is_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
691 std::is_invocable<Func, for_each_elem_ref<T, Array>>>;
692
693 template <typename Func, typename Array, typename T>
694 using can_for_each_nothrow = std::conditional_t<
695 // first form
696 std::is_invocable_v<Func, for_each_elem_ref<T, Array>, size_t>,
697 std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>, size_t>,
698 std::conditional_t<
699 // second form
700 std::is_invocable_v<Func, size_t, for_each_elem_ref<T, Array>>,
701 std::is_nothrow_invocable<Func, size_t, for_each_elem_ref<T, Array>>,
702 std::conditional_t<
703 // third form
704 std::is_invocable_v<Func, for_each_elem_ref<T, Array>>,
705 std::is_nothrow_invocable<Func, for_each_elem_ref<T, Array>>, std::false_type>>>;
706
707 template <typename Func, typename Array>
708 using can_for_each_any =
709 std::disjunction<can_for_each<Func, Array, table>, can_for_each<Func, Array, array>,
710 can_for_each<Func, Array, std::string>, can_for_each<Func, Array, int64_t>,
711 can_for_each<Func, Array, double>, can_for_each<Func, Array, bool>,
712 can_for_each<Func, Array, date>, can_for_each<Func, Array, time>,
713 can_for_each<Func, Array, date_time>>;
714
715 template <typename Func, typename Array, typename T>
716 using for_each_is_nothrow_one =
717 std::disjunction<std::negation<can_for_each<Func, Array, T>>, //
718 can_for_each_nothrow<Func, Array, T>>;
719
720 template <typename Func, typename Array>
721 using for_each_is_nothrow = std::conjunction<
722 for_each_is_nothrow_one<Func, Array, table>, for_each_is_nothrow_one<Func, Array, array>,
723 for_each_is_nothrow_one<Func, Array, std::string>,
724 for_each_is_nothrow_one<Func, Array, int64_t>, for_each_is_nothrow_one<Func, Array, double>,
725 for_each_is_nothrow_one<Func, Array, bool>, for_each_is_nothrow_one<Func, Array, date>,
726 for_each_is_nothrow_one<Func, Array, time>,
727 for_each_is_nothrow_one<Func, Array, date_time>>;
728
729 template <typename Func, typename Array>
730 static void do_for_each(Func&& visitor, Array&& arr) //
731 noexcept(for_each_is_nothrow<Func&&, Array&&>::value) {
732 static_assert(
733 can_for_each_any<Func&&, Array&&>::value,
734 "TOML array for_each visitors must be invocable for at least one of the toml::node "
735 "specializations:" TOML_SA_NODE_TYPE_LIST);
736
737 for (size_t i = 0; i < arr.size(); i++) {
738 using node_ref = impl::copy_cvref<toml::node, Array&&>;
739 static_assert(std::is_reference_v<node_ref>);
740
741#if TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN
742
743#ifndef TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_ACKNOWLEDGED
744 static_assert(impl::always_false<Func, Array, node_ref>, //
745 TOML_RETURN_BOOL_FROM_FOR_EACH_BROKEN_MESSAGE);
746#endif
747
748 static_cast<node_ref>(static_cast<Array&&>(arr)[i])
749 .visit([&]([[maybe_unused]] auto&& elem) //
750 noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value) {
751 using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
752 static_assert(std::is_reference_v<elem_ref>);
753
754 // func(elem, i)
755 if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>) {
756 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
757 }
758
759 // func(i, elem)
760 else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>) {
761 static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
762 }
763
764 // func(elem)
765 else if constexpr (std::is_invocable_v<Func&&, elem_ref>) {
766 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
767 }
768 });
769
770#else
771 const auto keep_going =
772 static_cast<node_ref>(static_cast<Array&&>(arr)[i])
773 .visit(
774 [&]([[maybe_unused]] auto&& elem) //
775 noexcept(for_each_is_nothrow_one<Func&&, Array&&, decltype(elem)>::value) {
776 using elem_ref = for_each_elem_ref<decltype(elem), Array&&>;
777 static_assert(std::is_reference_v<elem_ref>);
778
779 // func(elem, i)
780 if constexpr (std::is_invocable_v<Func&&, elem_ref, size_t>) {
781 using return_type =
782 decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
783
784 if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
785 return static_cast<bool>(
786 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i));
787 } else {
788 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem), i);
789 return true;
790 }
791 }
792
793 // func(i, elem)
794 else if constexpr (std::is_invocable_v<Func&&, size_t, elem_ref>) {
795 using return_type =
796 decltype(static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
797
798 if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
799 return static_cast<bool>(
800 static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem)));
801 } else {
802 static_cast<Func&&>(visitor)(i, static_cast<elem_ref>(elem));
803 return true;
804 }
805 }
806
807 // func(elem)
808 else if constexpr (std::is_invocable_v<Func&&, elem_ref>) {
809 using return_type =
810 decltype(static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
811
812 if constexpr (impl::is_constructible_or_convertible<bool, return_type>) {
813 return static_cast<bool>(
814 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem)));
815 } else {
816 static_cast<Func&&>(visitor)(static_cast<elem_ref>(elem));
817 return true;
818 }
819 }
820
821 // visitor not compatible with this particular type
822 else
823 return true;
824 });
825
826 if (!keep_going) return;
827#endif
828 }
829 }
830
832
833 public:
894 template <typename Func>
895 array& for_each(Func&& visitor) & //
896 noexcept(for_each_is_nothrow<Func&&, array&>::value) {
897 do_for_each(static_cast<Func&&>(visitor), *this);
898 return *this;
899 }
900
902 template <typename Func>
903 array&& for_each(Func&& visitor) && //
904 noexcept(for_each_is_nothrow<Func&&, array&&>::value) {
905 do_for_each(static_cast<Func&&>(visitor), static_cast<array&&>(*this));
906 return static_cast<array&&>(*this);
907 }
908
910 template <typename Func>
911 const array& for_each(Func&& visitor) const& //
912 noexcept(for_each_is_nothrow<Func&&, const array&>::value) {
913 do_for_each(static_cast<Func&&>(visitor), *this);
914 return *this;
915 }
916
918 template <typename Func>
919 const array&& for_each(Func&& visitor) const&& //
920 noexcept(for_each_is_nothrow<Func&&, const array&&>::value) {
921 do_for_each(static_cast<Func&&>(visitor), static_cast<const array&&>(*this));
922 return static_cast<const array&&>(*this);
923 }
924
926
929
932 bool empty() const noexcept { return elems_.empty(); }
933
936 size_t size() const noexcept { return elems_.size(); }
937
941 size_t max_size() const noexcept { return elems_.max_size(); }
942
946 size_t capacity() const noexcept { return elems_.capacity(); }
947
950 void reserve(size_t new_capacity);
951
955
979 void truncate(size_t new_size);
980
1010 template <typename ElemType>
1011 void resize(size_t new_size, ElemType&& default_init_val,
1012 value_flags default_init_flags = preserve_source_value_flags) {
1013 static_assert(
1014 !is_node_view<ElemType>,
1015 "The default element type argument to toml::array::resize may not be toml::node_view.");
1016
1017 if (!new_size)
1018 clear();
1019 else if (new_size > elems_.size())
1020 insert(cend(), new_size - elems_.size(), static_cast<ElemType&&>(default_init_val),
1021 default_init_flags);
1022 else
1023 truncate(new_size);
1024 }
1025
1027
1030
1051
1073
1096
1099 array&& flatten() && { return static_cast<toml::array&&>(this->flatten()); }
1100
1121 array& prune(bool recursive = true) & noexcept;
1122
1128 array&& prune(bool recursive = true) && noexcept {
1129 return static_cast<toml::array&&>(this->prune(recursive));
1130 }
1131
1134 void pop_back() noexcept;
1135
1138 void clear() noexcept;
1139
1141
1144
1172 template <typename ElemType>
1173 iterator insert(const_iterator pos, ElemType&& val,
1175 if constexpr (is_node_view<ElemType>) {
1176 if (!val) return end();
1177 }
1178 return iterator{insert_at(const_vector_iterator{pos},
1179 impl::make_node(static_cast<ElemType&&>(val), flags))};
1180 }
1181
1220 template <typename ElemType>
1223 if constexpr (is_node_view<ElemType>) {
1224 if (!val) return end();
1225 }
1226 switch (count) {
1227 case 0:
1228 return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
1229 case 1:
1230 return insert(pos, static_cast<ElemType&&>(val), flags);
1231 default: {
1232 const auto start_idx = static_cast<size_t>(const_vector_iterator{pos} - elems_.cbegin());
1233 preinsertion_resize(start_idx, count);
1234 size_t i = start_idx;
1235 for (size_t e = start_idx + count - 1u; i < e; i++)
1236 elems_[i] = impl::make_node(val, flags);
1237
1238 // # potentially move the initial value into the last element
1239 elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags);
1240 return iterator{elems_.begin() + static_cast<ptrdiff_t>(start_idx)};
1241 }
1242 }
1243 }
1244
1259 template <typename Iter>
1262 const auto distance = std::distance(first, last);
1263 if (distance <= 0)
1264 return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
1265 else {
1266 auto count = distance;
1267 using deref_type = decltype(*first);
1268 if constexpr (is_node_view<deref_type>) {
1269 for (auto it = first; it != last; it++)
1270 if (!(*it)) count--;
1271 if (!count)
1272 return iterator{elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin())};
1273 }
1274 const auto start_idx = static_cast<size_t>(const_vector_iterator{pos} - elems_.cbegin());
1275 preinsertion_resize(start_idx, static_cast<size_t>(count));
1276 size_t i = start_idx;
1277 for (auto it = first; it != last; it++) {
1278 if constexpr (is_node_view<deref_type>) {
1279 if (!(*it)) continue;
1280 }
1281 if constexpr (std::is_rvalue_reference_v<deref_type>)
1282 elems_[i++] = impl::make_node(std::move(*it), flags);
1283 else
1284 elems_[i++] = impl::make_node(*it, flags);
1285 }
1286 return iterator{elems_.begin() + static_cast<ptrdiff_t>(start_idx)};
1287 }
1288 }
1289
1304 template <typename ElemType>
1305 iterator insert(const_iterator pos, std::initializer_list<ElemType> ilist,
1307 return insert(pos, ilist.begin(), ilist.end(), flags);
1308 }
1309
1333 template <typename ElemType = void, typename... Args>
1335 using raw_elem_type = impl::remove_cvref<ElemType>;
1336 using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
1337 impl::emplaced_type_of<Args&&...>, raw_elem_type>;
1338
1339 using type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
1340 static_assert(impl::is_native<type> || impl::is_one_of<type, table, array>,
1341 "Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
1342
1343 return iterator{
1344 insert_at(const_vector_iterator{pos},
1345 impl::node_ptr{new impl::wrap_node<type>{static_cast<Args&&>(args)...}})};
1346 }
1347
1376 template <typename ElemType>
1379 TOML_ASSERT(pos >= cbegin() && pos < cend());
1380
1381 if constexpr (is_node_view<ElemType>) {
1382 if (!val) return end();
1383 }
1384
1385 const auto it = elems_.begin() + (const_vector_iterator{pos} - elems_.cbegin());
1386 *it = impl::make_node(static_cast<ElemType&&>(val), flags);
1387 return iterator{it};
1388 }
1389
1411 template <typename ElemType>
1413 emplace_back_if_not_empty_view(static_cast<ElemType&&>(val), flags);
1414 }
1415
1436 template <typename ElemType = void, typename... Args>
1437 decltype(auto) emplace_back(Args&&... args) {
1438 using raw_elem_type = impl::remove_cvref<ElemType>;
1439 using elem_type = std::conditional_t<std::is_void_v<raw_elem_type>, //
1440 impl::emplaced_type_of<Args&&...>, raw_elem_type>;
1441
1442 static constexpr auto moving_node_ptr = std::is_same_v<elem_type, impl::node_ptr> //
1443 && sizeof...(Args) == 1u //
1444 && impl::first_is_same<impl::node_ptr&&, Args&&...>;
1445
1446 using unwrapped_type = impl::remove_cvref<impl::unwrap_node<elem_type>>;
1447
1448 static_assert(moving_node_ptr //
1449 || impl::is_native<unwrapped_type> //
1450 || impl::is_one_of<unwrapped_type, table, array>, //
1451 "ElemType argument of array::emplace_back() must be one "
1452 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
1453
1454 if constexpr (moving_node_ptr) {
1455 insert_at_back(static_cast<Args&&>(args)...);
1456 return *elems_.back();
1457 } else {
1458 auto ptr = new impl::wrap_node<unwrapped_type>{static_cast<Args&&>(args)...};
1459 insert_at_back(impl::node_ptr{ptr});
1460 return *ptr;
1461 }
1462 }
1463
1465
1466 private:
1468
1471 static bool TOML_CALLCONV equal(const array&, const array&) noexcept;
1472
1473 template <typename T>
1474 TOML_NODISCARD static bool equal_to_container(const array& lhs, const T& rhs) noexcept {
1475 using element_type = std::remove_const_t<typename T::value_type>;
1476 static_assert(impl::is_losslessly_convertible_to_native<element_type>,
1477 "Container element type must be losslessly convertible one of the native TOML "
1478 "value types");
1479
1480 if (lhs.size() != rhs.size()) return false;
1481 if (rhs.size() == 0u) return true;
1482
1483 size_t i{};
1484 for (auto& list_elem : rhs) {
1485 const auto elem = lhs.get_as<impl::native_type_of<element_type>>(i++);
1486 if (!elem || *elem != list_elem) return false;
1487 }
1488
1489 return true;
1490 }
1491
1493
1494 public:
1497
1505 friend bool operator==(const array& lhs, const array& rhs) noexcept { return equal(lhs, rhs); }
1506
1514 friend bool operator!=(const array& lhs, const array& rhs) noexcept { return !equal(lhs, rhs); }
1515
1517 template <typename T>
1519 const std::initializer_list<T>& rhs) noexcept {
1520 return equal_to_container(lhs, rhs);
1521 }
1522 TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::initializer_list<T>&,
1523 template <typename T>);
1524
1526 template <typename T>
1527 TOML_NODISCARD friend bool operator==(const array& lhs, const std::vector<T>& rhs) noexcept {
1528 return equal_to_container(lhs, rhs);
1529 }
1530 TOML_ASYMMETRICAL_EQUALITY_OPS(const array&, const std::vector<T>&, template <typename T>);
1531
1533
1534#if TOML_ENABLE_FORMATTERS
1535
1539 friend std::ostream& operator<<(std::ostream& lhs, const array& rhs) {
1540 impl::print_to_stream(lhs, rhs);
1541 return lhs;
1542 }
1543
1544#endif
1545 };
1546}
1548
1549#include "header_end.hpp"
void count(T, T, const U &,...)
void distance(T, T,...)
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define rhs
Definition 17.names.cpp:536
#define u
Definition 17.names.cpp:137
#define e
Definition 17.names.cpp:118
#define ptr
Definition 17.names.cpp:525
#define last
Definition 17.names.cpp:487
#define index
Definition 17.names.cpp:482
#define array
Definition 17.names.cpp:447
#define lhs
Definition 17.names.cpp:489
#define val
Definition 17.names.cpp:570
#define pos
Definition 17.names.cpp:518
bool equal(const T &x, const U &y)
#define flags
std::size_t new_capacity
const minus< T > & operator-(const minus< T > &lhs, const minus< T > &rhs)
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
void operator+(typename A< T >::I, const A< T > &)
std::ostream_iterator< int, char, std::char_traits< char > > Iter
Definition alg7.cpp:64
TOML_NAMESPACE_START
Definition array.hpp:201
POXY_IMPLEMENTATION_DETAIL(impl::array_iterator< true >) const_array_iterator
A RandomAccessIterator for iterating over const elements in a toml::array.
Definition array.hpp:206
TOML_NAMESPACE_END
Definition array.hpp:1547
A TOML array.
Definition array.hpp:258
TOML_NODISCARD iterator begin() noexcept
Returns an iterator to the first element.
Definition array.hpp:658
TOML_CONST_INLINE_GETTER table * as_table() noexcept final
Returns nullptr.
Definition array.hpp:461
TOML_PURE_INLINE_GETTER node * get(size_t index) noexcept
Gets a pointer to the element at a specific index.
Definition array.hpp:558
const node & const_reference
Definition array.hpp:306
TOML_EXPORTED_MEMBER_FUNCTION void reserve(size_t new_capacity)
Reserves internal storage capacity up to a pre-determined number of elements.
TOML_NODISCARD friend bool operator==(const array &lhs, const std::initializer_list< T > &rhs) noexcept
Initializer list equality operator.
Definition array.hpp:1518
TOML_CONST_INLINE_GETTER bool is_boolean() const noexcept final
Returns false.
Definition array.hpp:440
TOML_CONST_INLINE_GETTER bool is_array() const noexcept final
Returns true.
Definition array.hpp:412
TOML_CONST_INLINE_GETTER bool is_date_time() const noexcept final
Returns false.
Definition array.hpp:452
TOML_NODISCARD friend bool operator==(const array &lhs, const std::vector< T > &rhs) noexcept
Vector equality operator.
Definition array.hpp:1527
TOML_EXPORTED_MEMBER_FUNCTION array & operator=(array &&rhs) noexcept
Move-assignment operator.
TOML_CONST_INLINE_GETTER toml::value< double > * as_floating_point() noexcept final
Returns nullptr.
Definition array.hpp:477
TOML_CONST_INLINE_GETTER const toml::value< bool > * as_boolean() const noexcept final
Returns nullptr.
Definition array.hpp:517
TOML_NODISCARD iterator end() noexcept
Returns an iterator to one-past-the-last element.
Definition array.hpp:670
const array & for_each(Func &&visitor) const &noexcept(for_each_is_nothrow< Func &&, const array & >::value)
Invokes a visitor on each element in the array (const lvalue overload).
Definition array.hpp:911
TOML_CONST_INLINE_GETTER bool is_string() const noexcept final
Returns false.
Definition array.hpp:424
TOML_NODISCARD const_iterator cbegin() const noexcept
Returns an iterator to the first element.
Definition array.hpp:666
TOML_CONST_INLINE_GETTER toml::value< std::string > * as_string() noexcept final
Returns nullptr.
Definition array.hpp:469
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, const node *&first_nonmatch) const noexcept final
TOML_NODISCARD node & back() noexcept
Returns a reference to the last element in the array.
Definition array.hpp:639
array && prune(bool recursive=true) &&noexcept
Removes empty child arrays and tables (rvalue overload).
Definition array.hpp:1128
TOML_NODISCARD size_t capacity() const noexcept
Returns the current max number of elements that may be held in the array's internal storage.
Definition array.hpp:946
iterator insert(const_iterator pos, size_t count, ElemType &&val, value_flags flags=preserve_source_value_flags)
Repeatedly inserts a new element starting at a specific position in the array.
Definition array.hpp:1221
TOML_NODISCARD friend bool operator!=(const array &lhs, const array &rhs) noexcept
Inequality operator.
Definition array.hpp:1514
TOML_CONST_INLINE_GETTER bool is_floating_point() const noexcept final
Returns false.
Definition array.hpp:432
TOML_CONST_INLINE_GETTER toml::value< bool > * as_boolean() noexcept final
Returns nullptr.
Definition array.hpp:481
TOML_PURE_INLINE_GETTER const node * get(size_t index) const noexcept
Gets a pointer to the element at a specific index (const overload).
Definition array.hpp:568
TOML_EXPORTED_MEMBER_FUNCTION iterator erase(const_iterator pos) noexcept
Removes the specified element from the array.
TOML_ASYMMETRICAL_EQUALITY_OPS(const array &, const std::vector< T > &, template< typename T >)
node & reference
Definition array.hpp:305
array && for_each(Func &&visitor) &&noexcept(for_each_is_nothrow< Func &&, array && >::value)
Invokes a visitor on each element in the array (rvalue overload).
Definition array.hpp:903
decltype(auto) emplace_back(Args &&... args)
Emplaces a new element at the end of the array.
Definition array.hpp:1437
TOML_ASYMMETRICAL_EQUALITY_OPS(const array &, const std::initializer_list< T > &, template< typename T >)
TOML_NODISCARD const node & operator[](size_t index) const noexcept
Gets a reference to the element at a specific index.
Definition array.hpp:616
TOML_NODISCARD const_iterator cend() const noexcept
Returns an iterator to one-past-the-last element.
Definition array.hpp:678
TOML_EXPORTED_MEMBER_FUNCTION void pop_back() noexcept
Removes the last element from the array.
TOML_CONST_INLINE_GETTER const toml::value< time > * as_time() const noexcept final
Returns nullptr.
Definition array.hpp:525
TOML_CONST_INLINE_GETTER bool is_time() const noexcept final
Returns false.
Definition array.hpp:448
TOML_NODISCARD TOML_EXPORTED_MEMBER_FUNCTION node & at(size_t index)
Gets a reference to the element at a specific index, throwing std::out_of_range if none existed.
TOML_CONST_INLINE_GETTER const toml::value< date_time > * as_date_time() const noexcept final
Returns nullptr.
Definition array.hpp:529
TOML_CONST_INLINE_GETTER bool is_integer() const noexcept final
Returns false.
Definition array.hpp:428
TOML_EXPORTED_MEMBER_FUNCTION array & prune(bool recursive=true) &noexcept
Removes empty child arrays and tables.
array && flatten() &&
Flattens this array, recursively hoisting the contents of child arrays up into itself (rvalue overloa...
Definition array.hpp:1099
TOML_CONST_INLINE_GETTER toml::value< int64_t > * as_integer() noexcept final
Returns nullptr.
Definition array.hpp:473
TOML_PURE_GETTER bool is_array_of_tables() const noexcept final
Returns true if the array contains only tables.
Definition array.hpp:416
TOML_NODISCARD const_iterator begin() const noexcept
Returns an iterator to the first element.
Definition array.hpp:662
TOML_NODISCARD const_iterator end() const noexcept
Returns an iterator to one-past-the-last element.
Definition array.hpp:674
TOML_CONST_INLINE_GETTER const array * as_array() const noexcept final
Returns a const-qualified pointer to the array.
Definition array.hpp:501
iterator insert(const_iterator pos, std::initializer_list< ElemType > ilist, value_flags flags=preserve_source_value_flags)
Inserts a range of elements into the array at a specific position.
Definition array.hpp:1305
const array && for_each(Func &&visitor) const &&noexcept(for_each_is_nothrow< Func &&, const array && >::value)
Invokes a visitor on each element in the array (const rvalue overload).
Definition array.hpp:919
TOML_EXPORTED_MEMBER_FUNCTION iterator erase(const_iterator first, const_iterator last) noexcept
Removes the elements in the range [first, last) from the array.
TOML_EXPORTED_MEMBER_FUNCTION void truncate(size_t new_size)
Shrinks the array to the given size.
TOML_NODISCARD friend bool operator==(const array &lhs, const array &rhs) noexcept
Equality operator.
Definition array.hpp:1505
TOML_CONST_INLINE_GETTER toml::value< date_time > * as_date_time() noexcept final
Returns nullptr.
Definition array.hpp:493
TOML_CONST_INLINE_GETTER node_type type() const noexcept final
Returns #toml::node_type::array.
Definition array.hpp:380
TOML_CONST_INLINE_GETTER const table * as_table() const noexcept final
Returns nullptr.
Definition array.hpp:497
array & for_each(Func &&visitor) &noexcept(for_each_is_nothrow< Func &&, array & >::value)
Invokes a visitor on each element in the array.
Definition array.hpp:895
TOML_CONST_INLINE_GETTER bool is_value() const noexcept final
Returns false.
Definition array.hpp:420
TOML_NODISCARD node & operator[](size_t index) noexcept
Gets a reference to the element at a specific index.
Definition array.hpp:612
TOML_NODISCARD bool empty() const noexcept
Returns true if the array is empty.
Definition array.hpp:932
TOML_NODISCARD size_t max_size() const noexcept
Returns the maximum number of elements that can be stored in an array on the current platform.
Definition array.hpp:941
size_t size_type
Definition array.hpp:303
TOML_CONST_INLINE_GETTER const toml::value< double > * as_floating_point() const noexcept final
Returns nullptr.
Definition array.hpp:513
TOML_CONST_INLINE_GETTER const toml::value< int64_t > * as_integer() const noexcept final
Returns nullptr.
Definition array.hpp:509
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype) const noexcept final
TOML_CONST_INLINE_GETTER const toml::value< std::string > * as_string() const noexcept final
Returns nullptr.
Definition array.hpp:505
TOML_CONST_INLINE_GETTER toml::value< time > * as_time() noexcept final
Returns nullptr.
Definition array.hpp:489
ptrdiff_t difference_type
Definition array.hpp:304
TOML_NODISCARD const node & at(size_t index) const
Gets a reference to the element at a specific index, throwing std::out_of_range if none existed.
Definition array.hpp:627
void resize(size_t new_size, ElemType &&default_init_val, value_flags default_init_flags=preserve_source_value_flags)
Resizes the array.
Definition array.hpp:1011
TOML_NODISCARD node & front() noexcept
Returns a reference to the first element in the array.
Definition array.hpp:631
TOML_EXPORTED_MEMBER_FUNCTION array & flatten() &
Flattens this array, recursively hoisting the contents of child arrays up into itself.
iterator replace(const_iterator pos, ElemType &&val, value_flags flags=preserve_source_value_flags)
Replaces the element at a specific position in the array with a different value.
Definition array.hpp:1377
TOML_CONST_INLINE_GETTER const toml::value< date > * as_date() const noexcept final
Returns nullptr.
Definition array.hpp:521
TOML_CONST_INLINE_GETTER toml::value< date > * as_date() noexcept final
Returns nullptr.
Definition array.hpp:485
friend std::ostream & operator<<(std::ostream &lhs, const array &rhs)
Prints the array out to a stream as formatted TOML.
Definition array.hpp:1539
array_iterator iterator
A RandomAccessIterator for iterating over elements in a toml::array.
Definition array.hpp:651
TOML_CONST_INLINE_GETTER bool is_number() const noexcept final
Returns false.
Definition array.hpp:436
TOML_PURE_GETTER TOML_EXPORTED_MEMBER_FUNCTION bool is_homogeneous(node_type ntype, node *&first_nonmatch) noexcept final
const_array_iterator const_iterator
A RandomAccessIterator for iterating over const elements in a toml::array.
Definition array.hpp:654
iterator emplace(const_iterator pos, Args &&... args)
Emplaces a new element at a specific position in the array.
Definition array.hpp:1334
iterator insert(const_iterator pos, Iter first, Iter last, value_flags flags=preserve_source_value_flags)
Inserts a range of elements into the array at a specific position.
Definition array.hpp:1260
TOML_CONST_INLINE_GETTER array * as_array() noexcept final
Returns a pointer to the array.
Definition array.hpp:465
TOML_NODISCARD impl::wrap_node< ElemType > * get_as(size_t index) noexcept
Gets a pointer to the element at a specific index if it is a particular type.
Definition array.hpp:588
TOML_EXPORTED_MEMBER_FUNCTION void shrink_to_fit()
Requests the removal of any unused internal storage capacity.
TOML_NODISCARD_CTOR TOML_EXPORTED_MEMBER_FUNCTION array() noexcept
Default constructor.
TOML_NODISCARD const node & front() const noexcept
Returns a reference to the first element in the array.
Definition array.hpp:635
TOML_NODISCARD const node & back() const noexcept
Returns a reference to the last element in the array.
Definition array.hpp:643
TOML_NODISCARD size_t size() const noexcept
Returns the number of elements in the array.
Definition array.hpp:936
node value_type
Definition array.hpp:302
TOML_CONST_INLINE_GETTER bool is_table() const noexcept final
Returns false.
Definition array.hpp:408
TOML_NODISCARD const impl::wrap_node< ElemType > * get_as(size_t index) const noexcept
Gets a pointer to the element at a specific index if it is a particular type (const overload).
Definition array.hpp:602
TOML_CONST_INLINE_GETTER bool is_date() const noexcept final
Returns false.
Definition array.hpp:444
void push_back(ElemType &&val, value_flags flags=preserve_source_value_flags)
Appends a new element to the end of the array.
Definition array.hpp:1412
A TOML table.
Definition table.hpp:190
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...
bool operator>(const DistancePair &lhs, const DistancePair &rhs)
Definition graph.cpp:47
#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_ASSERT(expr)
Sets the assert function used by the library. \detail Defaults to the standard C assert().
#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
bool operator<(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition json.h:14787
Definition json.h:5363
#define TOML_NODISCARD_CTOR
#define TOML_TRIVIAL_ABI
#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