GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 21, 0 excluded
0.0%
Functions:
0 of 16, 0 excluded
0.0%
Branches:
0 of 18, 0 excluded
0.0%

libs/kdl/src/eu/kdl/kdl.h
Line Branch Exec Source
1 #pragma once
2
3 #include <functional>
4 #include <map>
5 #include <optional>
6 #include <stdexcept>
7 #include <string>
8 #include <string_view>
9 #include <type_traits>
10 #include <variant>
11 #include <vector>
12
13 // forward-declare the types used from the C headers as not to pollute the global namespace
14 typedef struct kdl_str kdl_str;
15 typedef struct kdl_number kdl_number;
16 typedef struct kdl_value kdl_value;
17 typedef struct _kdl_parser kdl_parser;
18
19 namespace eu::kdl
20 {
21
22 enum class Version
23 {
24 kdl_1,
25 kdl_2,
26 any
27 };
28
29 template <typename T> concept arithmetic_concept = std::is_arithmetic_v<T>;
30
31 // Ways in which a KDL number may be represented in C/C++
32 enum class NumberType
33 {
34 integer_type = 0,
35 float_type,
36 string_type
37 };
38
39 using integer_type = long long;
40 using float_type = double;
41 using string_type = std::string;
42
43 struct Number
44 {
45 std::variant<integer_type, float_type, std::string> m_value;
46
47 Number();
48 Number(long long n);
49 Number(long n);
50 Number(int n);
51 Number(short n);
52 Number(double n);
53 Number(float n);
54 Number(const kdl_number& n);
55
56 ✗ Number(Number const&) = default;
57 ✗ Number(Number&&) = default;
58 ✗ Number& operator=(Number const&) = default;
59 ✗ Number& operator=(Number&&) = default;
60
61 bool operator==(const Number&) const = default;
62 bool operator!=(const Number&) const = default;
63
64 NumberType type() const noexcept;
65
66 // Cast the number to a fundamental arithmetic type (no bounds checking,
67 // no support for strings)
68 template <arithmetic_concept T>
69 ✗ std::optional<T> as() const
70 {
71 ✗ if (std::holds_alternative<integer_type>(m_value)) {
72 ✗ return static_cast<T>(std::get<integer_type>(m_value));
73 ✗ } else if (std::holds_alternative<float_type>(m_value)) {
74 ✗ return static_cast<T>(std::get<float_type>(m_value));
75 } else {
76 // string
77 ✗ return std::nullopt;
78 }
79 }
80
81 // Cast this C++ object to a libkdl C struct
82 // Note this object may hold a pointer to our string representation
83 explicit operator kdl_number() const;
84 };
85
86 template <typename T> concept into_number_concept = requires(T t) { Number{t}; };
87
88 // Mixin
89 struct HasTypeAnnotation
90 {
91 std::optional<std::string> type_annotation;
92
93 ✗ HasTypeAnnotation() = default;
94 HasTypeAnnotation(std::string_view t);
95
96
97 void remove_type_annotation();
98
99 bool operator==(const HasTypeAnnotation&) const = default;
100 bool operator!=(const HasTypeAnnotation&) const = default;
101 };
102
103 // KDL data types
104 enum class Type
105 {
106 null,
107 boolean,
108 number,
109 string
110 };
111
112 // A KDL value, possibly including a type annotation
113 // Analogous to kdl_value
114 struct Value : HasTypeAnnotation
115 {
116 std::variant<std::monostate, bool, Number, std::string> m_value;
117
118 ✗ Value() = default;
119
120 Value(bool b);
121 Value(std::string_view s);
122 Value(std::string s);
123 Value(char const* s);
124 Value(Number n);
125 Value(into_number_concept auto n) : m_value{Number{n}} {}
126
127 Value(std::string_view ta, bool b);
128 Value(std::string_view ta, std::string_view s);
129 Value(std::string_view ta, std::string s);
130 Value(std::string_view ta, Number n);
131 Value(std::string_view type_annotation, into_number_concept auto n);
132
133 Value(kdl_value const& val);
134
135 ✗ Value(Value const&) = default;
136 ✗ Value(Value&&) = default;
137 Value& operator=(Value const&) = default;
138 ✗ Value& operator=(Value&&) = default;
139
140 Value& operator=(bool b);
141 Value& operator=(std::string_view s);
142 Value& operator=(std::string s);
143 Value& operator=(Number const& n);
144 Value& operator=(Number&& n);
145 Value& operator=(into_number_concept auto n)
146 {
147 m_value = Number{n};
148 return *this;
149 }
150
151 bool operator==(const Value&) const = default;
152 bool operator!=(const Value&) const = default;
153
154 void set_to_null();
155
156 Type type() const noexcept;
157
158 const Number& as_number() const;
159 const std::string& as_string() const;
160 bool as_bool() const;
161
162 bool is_null() const;
163
164 explicit operator kdl_value() const;
165 };
166
167 // A node with all its contents
168 struct Node : HasTypeAnnotation
169 {
170 std::string name;
171 std::vector<Value> args;
172 std::map<std::string, Value, std::less<>> properties;
173 std::vector<Node> children;
174
175 Node() = default;
176 ✗ Node(Node const&) = default;
177 ✗ Node(Node&&) = default;
178
179 Node(std::string_view name);
180 Node(std::string_view ta, std::string_view name);
181 Node(std::string_view name, std::vector<Value> args, std::map<std::string, Value, std::less<>> properties, std::vector<Node> children);
182 Node(std::string_view ta, std::string_view name, std::vector<Value> args, std::map<std::string, Value, std::less<>> properties, std::vector<Node> children);
183
184 Node& operator=(Node const&) = default;
185 Node& operator=(Node&&) = default;
186 };
187
188 // A KDL document - consisting of several nodes.
189 struct Document
190 {
191 std::vector<Node> nodes;
192
193 Document() = default;
194 ✗ Document(Document const&) = default;
195 ✗ Document(Document&&) = default;
196
197 Document(std::vector<Node> nodes);
198 Document(std::initializer_list<Node> nodes);
199
200 Document& operator=(Document const&) = default;
201 Document& operator=(Document&&) = default;
202
203 ✗ [[nodiscard]] inline auto begin() const { return nodes.begin(); }
204 [[nodiscard]] inline auto begin() { return nodes.begin(); }
205 ✗ [[nodiscard]] inline auto end() const { return nodes.end(); }
206 [[nodiscard]] inline auto end() { return nodes.end(); }
207
208 std::optional<std::string> to_string() const;
209 std::optional<std::string> to_string(Version version) const;
210 };
211
212 // Exception thrown on regular KDL parsing errors
213 struct DocumentResult
214 {
215 std::optional<Document> document;
216 std::string error;
217
218 explicit DocumentResult(Document doc);
219 explicit DocumentResult(std::string error);
220 };
221
222 // Load a KDL document from string
223 DocumentResult parse(std::string_view kdl_text);
224 DocumentResult parse(std::string_view kdl_text, Version version);
225
226 } // namespace kdl
227