Euphoria
kdl.h
Go to the documentation of this file.
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
14typedef struct kdl_str kdl_str;
15typedef struct kdl_number kdl_number;
16typedef struct kdl_value kdl_value;
17typedef struct _kdl_parser kdl_parser;
18
19namespace eu::kdl
20{
21
22enum class Version
23{
27};
28
29template <typename T> concept arithmetic_concept = std::is_arithmetic_v<T>;
30
31// Ways in which a KDL number may be represented in C/C++
38
39using integer_type = long long;
40using float_type = double;
41using string_type = std::string;
42
43struct Number
44{
45 std::variant<integer_type, float_type, std::string> m_value;
46
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
86template <typename T> concept into_number_concept = requires(T t) { Number{t}; };
87
88// Mixin
90{
91 std::optional<std::string> type_annotation;
92
93 HasTypeAnnotation() = default;
94 HasTypeAnnotation(std::string_view t);
95
96
98
99 bool operator==(const HasTypeAnnotation&) const = default;
100 bool operator!=(const HasTypeAnnotation&) const = default;
101};
102
103// KDL data types
104enum class Type
105{
109 string
110};
111
112// A KDL value, possibly including a type annotation
113// Analogous to kdl_value
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);
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);
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
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
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.
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;
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
214{
215 std::optional<Document> document;
216 std::string error;
217
219 explicit DocumentResult(std::string error);
220};
221
222// Load a KDL document from string
223DocumentResult parse(std::string_view kdl_text);
224DocumentResult parse(std::string_view kdl_text, Version version);
225
226} // namespace kdl
struct kdl_str kdl_str
Definition kdl.h:14
struct kdl_number kdl_number
Definition kdl.h:15
struct _kdl_parser kdl_parser
Definition kdl.h:17
struct kdl_value kdl_value
Definition kdl.h:16
Definition kdl.h:20
DocumentResult parse(std::string_view kdl_text)
NumberType
Definition kdl.h:33
double float_type
Definition kdl.h:40
long long integer_type
Definition kdl.h:39
Type
Definition kdl.h:105
std::string string_type
Definition kdl.h:41
Version
Definition kdl.h:23
DocumentResult(std::string error)
std::string error
Definition kdl.h:216
DocumentResult(Document doc)
std::optional< Document > document
Definition kdl.h:215
std::optional< std::string > to_string() const
auto end()
Definition kdl.h:206
Document(Document &&)=default
auto begin()
Definition kdl.h:204
Document()=default
auto end() const
Definition kdl.h:205
std::optional< std::string > to_string(Version version) const
Document & operator=(Document &&)=default
Document(Document const &)=default
Document & operator=(Document const &)=default
Document(std::vector< Node > nodes)
auto begin() const
Definition kdl.h:203
std::vector< Node > nodes
Definition kdl.h:191
Document(std::initializer_list< Node > nodes)
HasTypeAnnotation(std::string_view t)
bool operator!=(const HasTypeAnnotation &) const =default
std::optional< std::string > type_annotation
Definition kdl.h:91
bool operator==(const HasTypeAnnotation &) const =default
std::map< std::string, Value, std::less<> > properties
Definition kdl.h:172
Node & operator=(Node &&)=default
Node(std::string_view ta, std::string_view name)
Node & operator=(Node const &)=default
Node(Node const &)=default
std::string name
Definition kdl.h:170
std::vector< Node > children
Definition kdl.h:173
Node(std::string_view name, std::vector< Value > args, std::map< std::string, Value, std::less<> > properties, std::vector< Node > children)
Node()=default
Node(Node &&)=default
std::vector< Value > args
Definition kdl.h:171
Node(std::string_view name)
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)
Number(const kdl_number &n)
std::optional< T > as() const
Definition kdl.h:69
std::variant< integer_type, float_type, std::string > m_value
Definition kdl.h:45
NumberType type() const noexcept
Number & operator=(Number &&)=default
Number(Number &&)=default
Number(long long n)
Number(Number const &)=default
bool operator!=(const Number &) const =default
Number(double n)
Number & operator=(Number const &)=default
bool operator==(const Number &) const =default
Value(Value &&)=default
Value & operator=(bool b)
Value(into_number_concept auto n)
Definition kdl.h:125
Value & operator=(Value &&)=default
Value & operator=(Number const &n)
bool operator==(const Value &) const =default
Value & operator=(Value const &)=default
Value(Value const &)=default
Value(std::string_view ta, Number n)
Value(std::string_view ta, bool b)
void set_to_null()
Value(std::string_view ta, std::string_view s)
Value(kdl_value const &val)
bool operator!=(const Value &) const =default
Value(char const *s)
const Number & as_number() const
Type type() const noexcept
Value & operator=(Number &&n)
Value(std::string_view ta, std::string s)
bool is_null() const
Value(std::string s)
Value(std::string_view s)
const std::string & as_string() const
bool as_bool() const
Value & operator=(std::string_view s)
Value & operator=(std::string s)
Value()=default
Value(Number n)
Value & operator=(into_number_concept auto n)
Definition kdl.h:145
Value(std::string_view type_annotation, into_number_concept auto n)
std::variant< std::monostate, bool, Number, std::string > m_value
Definition kdl.h:116