Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
node.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
8#include "header_start.hpp"
9#include "source_region.hpp"
10#include "std_utility.hpp"
11
18 private:
20
21 friend class TOML_PARSER_TYPENAME;
22 source_region source_{};
23
24 template <typename T>
25 TOML_NODISCARD decltype(auto) get_value_exact() const
26 noexcept(impl::value_retrieval_is_nothrow<T>);
27
28 template <typename T, typename N>
29 using ref_type_ = std::conditional_t< //
30 std::is_reference_v<T>, //
31 impl::copy_ref<impl::copy_cv<impl::unwrap_node<T>, std::remove_reference_t<N>>, T>, //
32 impl::copy_cvref<impl::unwrap_node<T>, N> //
33 >;
34
35 template <typename T, typename N>
36 using ref_type = std::conditional_t< //
37 std::is_reference_v<N>, //
38 ref_type_<T, N>, //
39 ref_type_<T, std::add_lvalue_reference_t<N>> //
40 >;
41
42 template <typename T, typename N>
43 TOML_PURE_GETTER static ref_type<T, N&&> do_ref(N&& n) noexcept {
44 using unwrapped_type = impl::unwrap_node<T>;
45 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
46 "The template type argument of node::ref() must be one "
47 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
48
49 TOML_ASSERT_ASSUME(n.template is<unwrapped_type>() &&
50 "template type argument provided to toml::node::ref() didn't match the "
51 "node's actual type");
52
53 using node_ref = std::remove_volatile_t<std::remove_reference_t<N>>&;
54 using val_type = std::remove_volatile_t<unwrapped_type>;
55 using out_ref = ref_type<T, N&&>;
56 static_assert(std::is_reference_v<out_ref>);
57
58 if constexpr (toml::is_value<unwrapped_type>)
59 return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>().get());
60 else
61 return static_cast<out_ref>(const_cast<node_ref>(n).template ref_cast<val_type>());
62 }
63
64 protected:
66 node() noexcept;
67
69 node(const node&) noexcept;
70
72 node(node&&) noexcept;
73
75 node& operator=(const node&) noexcept;
76
78 node& operator=(node&&) noexcept;
79
80 template <typename T, typename N>
81 using ref_cast_type_ = std::conditional_t< //
82 std::is_reference_v<T>, //
83 impl::copy_ref<impl::copy_cv<impl::wrap_node<T>, std::remove_reference_t<N>>, T>, //
84 impl::copy_cvref<impl::wrap_node<T>, N> //
85 >;
86
87 template <typename T, typename N>
88 using ref_cast_type = std::conditional_t< //
89 std::is_reference_v<N>, //
90 ref_cast_type_<T, N>, //
91 ref_cast_type_<T, std::add_lvalue_reference_t<N>> //
92 >;
93
94 template <typename T>
95 TOML_PURE_INLINE_GETTER ref_cast_type<T, node&> ref_cast() & noexcept {
96 using out_ref = ref_cast_type<T, node&>;
97 using out_type = std::remove_reference_t<out_ref>;
98 return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
99 }
100
101 template <typename T>
102 TOML_PURE_INLINE_GETTER ref_cast_type<T, node&&> ref_cast() && noexcept {
103 using out_ref = ref_cast_type<T, node&&>;
104 using out_type = std::remove_reference_t<out_ref>;
105 return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
106 }
107
108 template <typename T>
109 TOML_PURE_INLINE_GETTER ref_cast_type<T, const node&> ref_cast() const& noexcept {
110 using out_ref = ref_cast_type<T, const node&>;
111 using out_type = std::remove_reference_t<out_ref>;
112 return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
113 }
114
115 template <typename T>
116 TOML_PURE_INLINE_GETTER ref_cast_type<T, const node&&> ref_cast() const&& noexcept {
117 using out_ref = ref_cast_type<T, const node&&>;
118 using out_type = std::remove_reference_t<out_ref>;
119 return static_cast<out_ref>(*reinterpret_cast<out_type*>(this));
120 }
121
123
124 public:
126 virtual ~node() noexcept;
127
130
163 virtual bool is_homogeneous(node_type ntype, node*& first_nonmatch) noexcept = 0;
164
167 virtual bool is_homogeneous(node_type ntype, const node*& first_nonmatch) const noexcept = 0;
168
196 virtual bool is_homogeneous(node_type ntype) const noexcept = 0;
197
224 template <typename ElemType = void>
225 TOML_PURE_GETTER bool is_homogeneous() const noexcept {
226 using type = impl::remove_cvref<impl::unwrap_node<ElemType>>;
227 static_assert(std::is_void_v<type> || toml::is_value<type> || toml::is_container<type>,
228 "The template type argument of node::is_homogeneous() must be void or one "
229 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
230
231 return is_homogeneous(impl::node_type_of<type>);
232 }
233
236 virtual node_type type() const noexcept = 0;
237
240 virtual bool is_table() const noexcept = 0;
241
244 virtual bool is_array() const noexcept = 0;
245
248 virtual bool is_array_of_tables() const noexcept = 0;
249
252 virtual bool is_value() const noexcept = 0;
253
256 virtual bool is_string() const noexcept = 0;
257
260 virtual bool is_integer() const noexcept = 0;
261
264 virtual bool is_floating_point() const noexcept = 0;
265
268 virtual bool is_number() const noexcept = 0;
269
272 virtual bool is_boolean() const noexcept = 0;
273
276 virtual bool is_date() const noexcept = 0;
277
280 virtual bool is_time() const noexcept = 0;
281
284 virtual bool is_date_time() const noexcept = 0;
285
291 template <typename T>
292 TOML_PURE_INLINE_GETTER bool is() const noexcept {
293 using type = impl::remove_cvref<impl::unwrap_node<T>>;
294 static_assert(toml::is_value<type> || toml::is_container<type>,
295 "The template type argument of node::is() must be one "
296 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
297
298 if constexpr (std::is_same_v<type, table>)
299 return is_table();
300 else if constexpr (std::is_same_v<type, array>)
301 return is_array();
302 else if constexpr (std::is_same_v<type, std::string>)
303 return is_string();
304 else if constexpr (std::is_same_v<type, int64_t>)
305 return is_integer();
306 else if constexpr (std::is_same_v<type, double>)
307 return is_floating_point();
308 else if constexpr (std::is_same_v<type, bool>)
309 return is_boolean();
310 else if constexpr (std::is_same_v<type, date>)
311 return is_date();
312 else if constexpr (std::is_same_v<type, time>)
313 return is_time();
314 else if constexpr (std::is_same_v<type, date_time>)
315 return is_date_time();
316 }
317
319
322
325 virtual table* as_table() noexcept = 0;
326
329 virtual array* as_array() noexcept = 0;
330
333 virtual toml::value<std::string>* as_string() noexcept = 0;
334
337 virtual toml::value<int64_t>* as_integer() noexcept = 0;
338
341 virtual toml::value<double>* as_floating_point() noexcept = 0;
342
345 virtual toml::value<bool>* as_boolean() noexcept = 0;
346
349 virtual toml::value<date>* as_date() noexcept = 0;
350
353 virtual toml::value<time>* as_time() noexcept = 0;
354
357 virtual toml::value<date_time>* as_date_time() noexcept = 0;
358
361 virtual const table* as_table() const noexcept = 0;
362
365 virtual const array* as_array() const noexcept = 0;
366
370 virtual const toml::value<std::string>* as_string() const noexcept = 0;
371
375 virtual const toml::value<int64_t>* as_integer() const noexcept = 0;
376
380 virtual const toml::value<double>* as_floating_point() const noexcept = 0;
381
384 virtual const toml::value<bool>* as_boolean() const noexcept = 0;
385
389 virtual const toml::value<date>* as_date() const noexcept = 0;
390
394 virtual const toml::value<time>* as_time() const noexcept = 0;
395
399 virtual const toml::value<date_time>* as_date_time() const noexcept = 0;
400
421 template <typename T>
422 TOML_PURE_INLINE_GETTER impl::wrap_node<T>* as() noexcept {
423 using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
424 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
425 "The template type argument of node::as() must be one "
426 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
427
428 if constexpr (std::is_same_v<unwrapped_type, table>)
429 return as_table();
430 else if constexpr (std::is_same_v<unwrapped_type, array>)
431 return as_array();
432 else if constexpr (std::is_same_v<unwrapped_type, std::string>)
433 return as_string();
434 else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
435 return as_integer();
436 else if constexpr (std::is_same_v<unwrapped_type, double>)
437 return as_floating_point();
438 else if constexpr (std::is_same_v<unwrapped_type, bool>)
439 return as_boolean();
440 else if constexpr (std::is_same_v<unwrapped_type, date>)
441 return as_date();
442 else if constexpr (std::is_same_v<unwrapped_type, time>)
443 return as_time();
444 else if constexpr (std::is_same_v<unwrapped_type, date_time>)
445 return as_date_time();
446 }
447
449 template <typename T>
450 TOML_PURE_INLINE_GETTER const impl::wrap_node<T>* as() const noexcept {
451 using unwrapped_type = impl::unwrap_node<impl::remove_cvref<T>>;
452 static_assert(toml::is_value<unwrapped_type> || toml::is_container<unwrapped_type>,
453 "The template type argument of node::as() must be one "
454 "of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
455
456 if constexpr (std::is_same_v<unwrapped_type, table>)
457 return as_table();
458 else if constexpr (std::is_same_v<unwrapped_type, array>)
459 return as_array();
460 else if constexpr (std::is_same_v<unwrapped_type, std::string>)
461 return as_string();
462 else if constexpr (std::is_same_v<unwrapped_type, int64_t>)
463 return as_integer();
464 else if constexpr (std::is_same_v<unwrapped_type, double>)
465 return as_floating_point();
466 else if constexpr (std::is_same_v<unwrapped_type, bool>)
467 return as_boolean();
468 else if constexpr (std::is_same_v<unwrapped_type, date>)
469 return as_date();
470 else if constexpr (std::is_same_v<unwrapped_type, time>)
471 return as_time();
472 else if constexpr (std::is_same_v<unwrapped_type, date_time>)
473 return as_date_time();
474 }
475
477
480
494 template <typename T>
495 TOML_NODISCARD optional<T> value_exact() const noexcept(impl::value_retrieval_is_nothrow<T>);
496
623 template <typename T>
624 TOML_NODISCARD optional<T> value() const noexcept(impl::value_retrieval_is_nothrow<T>);
625
643 template <typename T>
644 TOML_NODISCARD auto value_or(T&& default_value) const
645 noexcept(impl::value_retrieval_is_nothrow<T>);
646
675 template <typename T>
676 TOML_PURE_GETTER decltype(auto) ref() & noexcept {
677 return do_ref<T>(*this);
678 }
679
681 template <typename T>
682 TOML_PURE_GETTER decltype(auto) ref() && noexcept {
683 return do_ref<T>(std::move(*this));
684 }
685
687 template <typename T>
688 TOML_PURE_GETTER decltype(auto) ref() const& noexcept {
689 return do_ref<T>(*this);
690 }
691
693 template <typename T>
694 TOML_PURE_GETTER decltype(auto) ref() const&& noexcept {
695 return do_ref<T>(std::move(*this));
696 }
697
699
702
705 const source_region& source() const noexcept { return source_; }
706
708
709 private:
711
712 template <typename Func, typename Node, typename T>
713 static constexpr bool can_visit = std::is_invocable_v<Func, ref_cast_type<T, Node>>;
714
715 template <typename Func, typename Node, typename T>
716 static constexpr bool can_visit_nothrow =
717 std::is_nothrow_invocable_v<Func, ref_cast_type<T, Node>>;
718
719 template <typename Func, typename Node>
720 static constexpr bool can_visit_any = can_visit<Func, Node, table> //
721 || can_visit<Func, Node, array> //
722 || can_visit<Func, Node, std::string> //
723 || can_visit<Func, Node, int64_t> //
724 || can_visit<Func, Node, double> //
725 || can_visit<Func, Node, bool> //
726 || can_visit<Func, Node, date> //
727 || can_visit<Func, Node, time> //
728 || can_visit<Func, Node, date_time>;
729
730 // clang-format off
731
732 template <typename Func, typename Node>
733 static constexpr bool can_visit_all = can_visit<Func, Node, table> //
734 && can_visit<Func, Node, array> //
735 && can_visit<Func, Node, std::string> //
736 && can_visit<Func, Node, int64_t> //
737 && can_visit<Func, Node, double> //
738 && can_visit<Func, Node, bool> //
739 && can_visit<Func, Node, date> //
740 && can_visit<Func, Node, time> //
741 && can_visit<Func, Node, date_time>;
742
743 template <typename Func, typename Node, typename T>
744 static constexpr bool visit_is_nothrow_one = !can_visit<Func, Node, T> || can_visit_nothrow<Func, Node, T>;
745
746 template <typename Func, typename Node>
747 static constexpr bool visit_is_nothrow = visit_is_nothrow_one<Func, Node, table> //
748 && visit_is_nothrow_one<Func, Node, array> //
749 && visit_is_nothrow_one<Func, Node, std::string> //
750 && visit_is_nothrow_one<Func, Node, int64_t> //
751 && visit_is_nothrow_one<Func, Node, double> //
752 && visit_is_nothrow_one<Func, Node, bool> //
753 && visit_is_nothrow_one<Func, Node, date> //
754 && visit_is_nothrow_one<Func, Node, time> //
755 && visit_is_nothrow_one<Func, Node, date_time>;
756
757 // clang-format on
758
759 template <typename Func, typename Node, typename T, bool = can_visit<Func, Node, T>>
760 struct visit_return_type_ {
761 using type = decltype(std::declval<Func>()(std::declval<ref_cast_type<T, Node>>()));
762 };
763 template <typename Func, typename Node, typename T>
764 struct visit_return_type_<Func, Node, T, false> {
765 using type = void;
766 };
767
768 template <typename Func, typename Node, typename T>
769 using visit_return_type = typename visit_return_type_<Func, Node, T>::type;
770
771 template <typename A, typename B>
772 using nonvoid = std::conditional_t<std::is_void_v<A>, B, A>;
773
774 template <typename Func, typename Node>
775 static decltype(auto) do_visit(Func&& visitor,
776 Node&& n) noexcept(visit_is_nothrow<Func&&, Node&&>) {
777 static_assert(can_visit_any<Func&&, Node&&>,
778 "TOML node visitors must be invocable for at least one of the toml::node "
779 "specializations:" TOML_SA_NODE_TYPE_LIST);
780
781 switch (n.type()) {
782 case node_type::table:
783 if constexpr (can_visit<Func&&, Node&&, table>)
784 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<table>());
785 break;
786
787 case node_type::array:
788 if constexpr (can_visit<Func&&, Node&&, array>)
789 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<array>());
790 break;
791
792 case node_type::string:
793 if constexpr (can_visit<Func&&, Node&&, std::string>)
794 return static_cast<Func&&>(visitor)(
795 static_cast<Node&&>(n).template ref_cast<std::string>());
796 break;
797
798 case node_type::integer:
799 if constexpr (can_visit<Func&&, Node&&, int64_t>)
800 return static_cast<Func&&>(visitor)(
801 static_cast<Node&&>(n).template ref_cast<int64_t>());
802 break;
803
804 case node_type::floating_point:
805 if constexpr (can_visit<Func&&, Node&&, double>)
806 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<double>());
807 break;
808
809 case node_type::boolean:
810 if constexpr (can_visit<Func&&, Node&&, bool>)
811 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<bool>());
812 break;
813
814 case node_type::date:
815 if constexpr (can_visit<Func&&, Node&&, date>)
816 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<date>());
817 break;
818
819 case node_type::time:
820 if constexpr (can_visit<Func&&, Node&&, time>)
821 return static_cast<Func&&>(visitor)(static_cast<Node&&>(n).template ref_cast<time>());
822 break;
823
824 case node_type::date_time:
825 if constexpr (can_visit<Func&&, Node&&, date_time>)
826 return static_cast<Func&&>(visitor)(
827 static_cast<Node&&>(n).template ref_cast<date_time>());
828 break;
829
830 case node_type::none:
832 default:
834 }
835
836 if constexpr (!can_visit_all<Func&&, Node&&>) {
837 // clang-format off
838
839 using return_type =
840 nonvoid<visit_return_type<Func&&, Node&&, table>,
841 nonvoid<visit_return_type<Func&&, Node&&, array>,
842 nonvoid<visit_return_type<Func&&, Node&&, std::string>,
843 nonvoid<visit_return_type<Func&&, Node&&, int64_t>,
844 nonvoid<visit_return_type<Func&&, Node&&, double>,
845 nonvoid<visit_return_type<Func&&, Node&&, bool>,
846 nonvoid<visit_return_type<Func&&, Node&&, date>,
847 nonvoid<visit_return_type<Func&&, Node&&, time>,
848 visit_return_type<Func&&, Node&&, date_time>
849 >>>>>>>>;
850
851 // clang-format on
852
853 if constexpr (!std::is_void_v<return_type>) {
854 static_assert(
855 std::is_default_constructible_v<return_type>,
856 "Non-exhaustive visitors must return a default-constructible type, or void");
857 return return_type{};
858 }
859 }
860 }
861
863
864 public:
867
899 template <typename Func>
900 decltype(auto) visit(Func&& visitor) & noexcept(visit_is_nothrow<Func&&, node&>) {
901 return do_visit(static_cast<Func&&>(visitor), *this);
902 }
903
905 template <typename Func>
906 decltype(auto) visit(Func&& visitor) && noexcept(visit_is_nothrow<Func&&, node&&>) {
907 return do_visit(static_cast<Func&&>(visitor), static_cast<node&&>(*this));
908 }
909
912 template <typename Func>
913 decltype(auto) visit(Func&& visitor) const& noexcept(visit_is_nothrow<Func&&, const node&>) {
914 return do_visit(static_cast<Func&&>(visitor), *this);
915 }
916
919 template <typename Func>
920 decltype(auto) visit(Func&& visitor) const&& noexcept(visit_is_nothrow<Func&&, const node&&>) {
921 return do_visit(static_cast<Func&&>(visitor), static_cast<const node&&>(*this));
922 }
923
925
928
931 explicit operator node_view<node>() noexcept;
932
935 explicit operator node_view<const node>() const noexcept;
936
976 node_view<node> at_path(std::string_view path) noexcept;
977
983 node_view<const node> at_path(std::string_view path) const noexcept;
984
1026 node_view<node> at_path(const toml::path& path) noexcept;
1027
1033 node_view<const node> at_path(const toml::path& path) const noexcept;
1034
1035#if TOML_ENABLE_WINDOWS_COMPAT
1036
1044 node_view<node> at_path(std::wstring_view path);
1045
1053 node_view<const node> at_path(std::wstring_view path) const;
1054
1055#endif // TOML_ENABLE_WINDOWS_COMPAT
1056
1066 node_view<node> operator[](const toml::path& path) noexcept;
1067
1077 node_view<const node> operator[](const toml::path& path) const noexcept;
1078
1080 };
1081}
1083
1088 bool TOML_CALLCONV node_deep_equality(const node*, const node*) noexcept;
1089}
1092
1093#include "header_end.hpp"
#define N
Definition 17.names.cpp:157
#define T
Definition 17.names.cpp:163
#define B
Definition 17.names.cpp:145
#define n
Definition 17.names.cpp:130
T value(const T &val)
TOML_NODISCARD TOML_EXPORTED_FREE_FUNCTION node_view< const node > TOML_CALLCONV at_path(const node &root, std::string_view path) noexcept
Returns a const view of the node matching a fully-qualified "TOML path".
A TOML array.
Definition array.hpp:258
A TOML path.
Definition path.hpp:209
A TOML table.
Definition table.hpp:190
constexpr bool is_number
Metafunction for determining if a type satisfies either toml::is_integer or toml::is_floating_point.
constexpr bool is_boolean
Metafunction for determining if a type is, or is a reference to, a bool or toml::value<bool>.
constexpr bool is_floating_point
Metafunction for determining if a type is, or is a reference to, a double or toml::value<double>.
constexpr bool is_date
Metafunction for determining if a type is, or is a reference to, a toml::date or toml::value<date>.
constexpr bool is_string
Metafunction for determining if a type is, or is a reference to, a std::string or toml::value<std::st...
constexpr bool is_array
Metafunction for determining if a type is, or is a reference to, a toml::array.
constexpr bool is_date_time
Metafunction for determining if a type is, or is a reference to, a toml::date_time or toml::value<dat...
constexpr bool is_integer
Metafunction for determining if a type is, or is a reference to, a int64_t or toml::value<int64_t>.
constexpr bool is_time
Metafunction for determining if a type is, or is a reference to, a toml::time or toml::value<time>.
constexpr bool is_value
Metafunction for determining if a type is, or is a reference to, any of the toml value types....
#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_ASSERT_ASSUME(expr)
#define TOML_EXPORTED_FREE_FUNCTION
An 'export' annotation to add to free functions. \detail Not defined by default.
#define TOML_EXPORTED_MEMBER_FUNCTION
An 'export' annotation to add to non-static class member functions. \detail Not defined by default.
TOML_NAMESPACE_START
Definition node.hpp:12
TOML_NAMESPACE_END
Definition node.hpp:1082
#define TOML_UNREACHABLE
#define TOML_NODISCARD
#define TOML_PURE_GETTER
#define TOML_PURE_INLINE_GETTER
#define TOML_IMPL_NAMESPACE_END
#define TOML_IMPL_NAMESPACE_START
#define TOML_ABSTRACT_INTERFACE
#define false
Definition stdbool.h:26
A source document region.