Branch data Line data Source code
1 : : /*
2 : : ** Copyright (C) 2021 CERN
3 : : **
4 : : ** This software is provided 'as-is', without any express or implied
5 : : ** warranty. In no event will the authors be held liable for any damages
6 : : ** arising from the use of this software.
7 : : **
8 : : ** Permission is granted to anyone to use this software for any purpose,
9 : : ** including commercial applications, and to alter it and redistribute it
10 : : ** freely, subject to the following restrictions:
11 : : **
12 : : ** 1. The origin of this software must not be misrepresented; you must not
13 : : ** claim that you wrote the original software. If you use this software
14 : : ** in a product, an acknowledgment in the product documentation would be
15 : : ** appreciated but is not required.
16 : : ** 2. Altered source versions must be plainly marked as such, and must not be
17 : : ** misrepresented as being the original software.
18 : : ** 3. This notice may not be removed or altered from any source distribution.
19 : : **
20 : : ** Created on: 2022-02-25T11:07:41+01:00
21 : : ** Author: Sylvain Fargier <sfargier> <sylvain.fargier@cern.ch>
22 : : **
23 : : */
24 : :
25 : : #ifndef CCUT_YML_HPP__
26 : : #define CCUT_YML_HPP__
27 : :
28 : : #include <type_traits>
29 : :
30 : : #include "Exception.hpp"
31 : : #include "ryml_internals.hpp"
32 : :
33 : : namespace ccut {
34 : : namespace yml {
35 : :
36 : : using namespace ryml;
37 : : using ryml::NodeRef;
38 : :
39 : : inline Tree parse(const std::string &str)
40 : : {
41 : : return yml::parse_in_arena(to_csubstr(str));
42 : : }
43 : :
44 : : /**
45 : : * @brief initialize rapidyaml library
46 : : * @details sets proper callbacks
47 : : */
48 : : void init();
49 : :
50 : : namespace {
51 : : template<class T, class V>
52 : : struct default_to_
53 : : {
54 : : T &val;
55 : : const V def;
56 : : };
57 : : } // namespace
58 : : template<class T, class V>
59 : 2 : inline default_to_<T, V> default_to(T &val, V v)
60 : : {
61 : 2 : return default_to_<T, V>{val, v};
62 : : }
63 : :
64 : : template<class T, class V>
65 : : struct default_to_key_
66 : : {
67 : : yml::Key<T> val;
68 : : const V def;
69 : : };
70 : : template<class T, class V>
71 : 3 : inline default_to_key_<T, V> default_to(yml::Key<T> val, V v)
72 : : {
73 : 3 : return default_to_key_<T, V>{val, v};
74 : : }
75 : :
76 : : template<typename V>
77 : 3 : typename std::enable_if<std::is_integral<V>::value, NodeRef>::type get(
78 : : const NodeRef &n,
79 : : V c)
80 : : {
81 : 6 : return (n.valid() && !n.is_seed() && n.is_seq()) ? n.child(c) : NodeRef();
82 : : }
83 : :
84 : : template<typename V>
85 : 16 : typename std::enable_if<!std::is_integral<V>::value, NodeRef>::type get(
86 : : const NodeRef &n,
87 : : V c)
88 : : {
89 : 29 : return (n.valid() && !n.is_seed() && n.is_map()) ?
90 : 13 : n.find_child(to_csubstr(c)) :
91 : 16 : NodeRef();
92 : : }
93 : :
94 : : template<typename V, typename... T>
95 : 13 : NodeRef get(const NodeRef &n, V arg, T... args)
96 : : {
97 : 13 : if (!n.valid())
98 : 1 : return NodeRef();
99 : 12 : return get(get(n, arg), args...);
100 : : }
101 : :
102 : : Exception make_error(const Parser &parser,
103 : : const NodeRef &ref,
104 : : const std::string &message);
105 : :
106 : : } // namespace yml
107 : : } // namespace ccut
108 : :
109 : : template<class T, class V>
110 : 2 : const ccut::yml::NodeRef &operator>>(const ccut::yml::NodeRef &ref,
111 : : const ccut::yml::default_to_<T, V> &wrapper)
112 : : {
113 : 2 : if (ref.is_seed() || !ref.valid() || ref.get() == nullptr)
114 : 1 : wrapper.val = wrapper.def;
115 : 1 : else if (!read(ref, &wrapper.val))
116 : 0 : wrapper.val = wrapper.def;
117 : 2 : return ref;
118 : : }
119 : :
120 : : template<class T, class V>
121 : 3 : const ccut::yml::NodeRef &operator>>(
122 : : const ccut::yml::NodeRef &ref,
123 : : const ccut::yml::default_to_key_<T, V> &wrapper)
124 : : {
125 : 3 : if (ref.is_seed() || !ref.valid() || ref.get() == nullptr)
126 : 1 : wrapper.val.k = wrapper.def;
127 : 2 : else if (!from_chars(ref.key(), &wrapper.val.k))
128 : 0 : wrapper.val.k = wrapper.def;
129 : 3 : return ref;
130 : : }
131 : :
132 : : #endif
|