libcamera v0.7.1
Supporting cameras in Linux since 2019
Loading...
Searching...
No Matches
value_node.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2022, Google Inc.
4 * Copyright (C) 2026, Ideas on Board
5 *
6 * Data structure to manage tree of values
7 */
8
9#pragma once
10
11#include <initializer_list>
12#include <iterator>
13#include <map>
14#include <memory>
15#include <optional>
16#include <string>
17#include <string_view>
18#include <type_traits>
19#include <utility>
20#include <vector>
21
23
24namespace libcamera {
25
26class ValueNode
27{
28private:
29 struct Value {
30 Value(std::string k, std::unique_ptr<ValueNode> &&v)
31 : key(std::move(k)), value(std::move(v))
32 {
33 }
34 std::string key;
35 std::unique_ptr<ValueNode> value;
36 };
37
38 using ValueContainer = std::vector<Value>;
39
40public:
41#ifndef __DOXYGEN__
42 template<typename Derived, typename ContainerIterator>
43 class Iterator
44 {
45 public:
46 using difference_type = std::ptrdiff_t;
47 using iterator_category = std::forward_iterator_tag;
48
49 Iterator(ContainerIterator it)
50 : it_(it)
51 {
52 }
53
54 Derived &operator++()
55 {
56 ++it_;
57 return *static_cast<Derived *>(this);
58 }
59
60 Derived operator++(int)
61 {
62 Derived it = *static_cast<Derived *>(this);
63 it_++;
64 return it;
65 }
66
67 friend bool operator==(const Iterator &a, const Iterator &b)
68 {
69 return a.it_ == b.it_;
70 }
71
72 friend bool operator!=(const Iterator &a, const Iterator &b)
73 {
74 return a.it_ != b.it_;
75 }
76
77 protected:
78 ContainerIterator it_;
79 };
80
81 template<typename Iterator, typename Container>
82 class Adapter
83 {
84 public:
85 Adapter(Container &container)
86 : container_(container)
87 {
88 }
89
90 Iterator begin() const
91 {
92 return Iterator{ container_.begin() };
93 }
94
95 Iterator end() const
96 {
97 return Iterator{ container_.end() };
98 }
99
100 protected:
101 Container &container_;
102 };
103
104 template<typename Value, typename ContainerIterator>
105 class ListIterator : public Iterator<ListIterator<Value, ContainerIterator>,
106 ContainerIterator>
107 {
108 private:
109 using Base = Iterator<ListIterator<Value, ContainerIterator>,
110 ContainerIterator>;
111
112 public:
113 using value_type = Value;
114 using pointer = value_type *;
115 using reference = value_type &;
116
117 reference operator*() const
118 {
119 return *Base::it_->value.get();
120 }
121
122 pointer operator->() const
123 {
124 return Base::it_->value.get();
125 }
126 };
127
128 template<typename Value, typename ContainerIterator>
129 class DictIterator : public Iterator<DictIterator<Value, ContainerIterator>,
130 ContainerIterator>
131 {
132 private:
133 using Base = Iterator<DictIterator<Value, ContainerIterator>,
134 ContainerIterator>;
135
136 public:
137 using value_type = std::pair<const std::string &, Value &>;
138 using pointer = value_type *;
139 using reference = value_type &;
140
141 value_type operator*() const
142 {
143 return { Base::it_->key, *Base::it_->value.get() };
144 }
145 };
146
147 class DictAdapter : public Adapter<DictIterator<ValueNode,
148 ValueContainer::iterator>,
149 ValueContainer>
150 {
151 public:
152 using key_type = std::string;
153 };
154
155 class ListAdapter : public Adapter<ListIterator<ValueNode,
156 ValueContainer::iterator>,
157 ValueContainer>
158 {
159 };
160
161 class ConstDictAdapter : public Adapter<DictIterator<const ValueNode,
162 ValueContainer::const_iterator>,
163 const ValueContainer>
164 {
165 public:
166 using key_type = std::string;
167 };
168
169 class ConstListAdapter : public Adapter<ListIterator<const ValueNode,
170 ValueContainer::const_iterator>,
171 const ValueContainer>
172 {
173 };
174#endif /* __DOXYGEN__ */
175
176 ValueNode();
177
178 template<typename T>
179 ValueNode(T &&value)
180 : type_(Type::Empty)
181 {
182 set(std::forward<T>(value));
183 }
184
185 ~ValueNode();
186
187 bool isValue() const
188 {
189 return type_ == Type::Value;
190 }
191 bool isList() const
192 {
193 return type_ == Type::List;
194 }
195 bool isDictionary() const
196 {
197 return type_ == Type::Dictionary;
198 }
199 bool isEmpty() const
200 {
201 return type_ == Type::Empty;
202 }
203 explicit operator bool() const
204 {
205 return type_ != Type::Empty;
206 }
207
208 std::size_t size() const;
209
210 template<typename T>
211 std::optional<T> get() const
212 {
213 return Accessor<T>{}.get(*this);
214 }
215
216 template<typename T, typename U>
217 T get(U &&defaultValue) const
218 {
219 return get<T>().value_or(std::forward<U>(defaultValue));
220 }
221
222 template<typename T>
223 void set(T &&value)
224 {
225 return Accessor<std::remove_cv_t<std::remove_reference_t<T>>>{}
226 .set(*this, std::forward<T>(value));
227 }
228
229 DictAdapter asDict() { return DictAdapter{ list_ }; }
230 ListAdapter asList() { return ListAdapter{ list_ }; }
231 ConstDictAdapter asDict() const { return ConstDictAdapter{ list_ }; }
232 ConstListAdapter asList() const { return ConstListAdapter{ list_ }; }
233
234 ValueNode *at(std::size_t index);
235 const ValueNode &operator[](std::size_t index) const;
236
237 bool contains(std::string_view key) const;
238 ValueNode *at(std::string_view key);
239 const ValueNode &operator[](std::string_view key) const;
240 const ValueNode &operator[](std::initializer_list<std::string_view> path) const;
241
242 ValueNode *add(std::unique_ptr<ValueNode> &&child);
243 ValueNode *add(std::string key, std::unique_ptr<ValueNode> &&child);
244 ValueNode *add(std::initializer_list<std::string_view> path,
245 std::unique_ptr<ValueNode> &&child);
246
247 void erase(std::string_view key);
248 void erase(std::initializer_list<std::string_view> path);
249
250private:
252
253 template<typename T>
254 friend struct Accessor;
255
256 enum class Type {
257 Dictionary,
258 List,
259 Value,
260 Empty,
261 };
262
263 template<typename T, typename Enable = void>
264 struct Accessor {
265 std::optional<T> get(const ValueNode &obj) const;
266 void set(ValueNode &obj, T value);
267 };
268
269 Type type_;
270
271 std::string value_;
272 ValueContainer list_;
273 std::map<std::string, ValueNode *, std::less<>> dictionary_;
274};
275
276} /* namespace libcamera */
Utilities to help constructing class interfaces.
#define LIBCAMERA_DISABLE_COPY_AND_MOVE(klass)
Disable copy and move construction and assignment of the klass.
Definition class.h:29
A class representing a tree structure of values.
Definition value_node.h:27
bool isValue() const
Return whether the ValueNode is a value.
Definition value_node.h:187
ValueNode * at(std::size_t index)
Retrieve the element from list ValueNode by index.
Definition value_node.cpp:404
const ValueNode & operator[](std::size_t index) const
Retrieve the element from list ValueNode by index.
Definition value_node.cpp:423
ValueNode * add(std::unique_ptr< ValueNode > &&child)
Add a child node to a list.
Definition value_node.cpp:528
T get(U &&defaultValue) const
Parse the ValueNode as a T value.
Definition value_node.h:217
void set(T &&value)
Set the value of a ValueNode.
Definition value_node.h:223
bool isEmpty() const
Return whether the ValueNode is an empty.
Definition value_node.h:199
ListAdapter asList()
Wrap a list ValueNode in an adapter that exposes iterators.
Definition value_node.h:230
bool isDictionary() const
Return whether the ValueNode is a dictionary.
Definition value_node.h:195
ConstDictAdapter asDict() const
Wrap a dictionary ValueNode in an adapter that exposes iterators.
Definition value_node.h:231
void erase(std::string_view key)
Erase a child node in a dictionary.
Definition value_node.cpp:633
bool isList() const
Return whether the ValueNode is a list.
Definition value_node.h:191
ValueNode(T &&value)
Construct a ValueNode instance with a value.
Definition value_node.h:179
bool contains(std::string_view key) const
Check if an element of a dictionary exists.
Definition value_node.cpp:442
std::size_t size() const
Retrieve the number of elements in a dictionary or list ValueNode.
Definition value_node.cpp:106
std::optional< T > get() const
Parse the ValueNode as a T value.
Definition value_node.h:211
ConstListAdapter asList() const
Wrap a list ValueNode in an adapter that exposes iterators.
Definition value_node.h:232
DictAdapter asDict()
Wrap a dictionary ValueNode in an adapter that exposes iterators.
Definition value_node.h:229
Top-level libcamera namespace.
Definition backtrace.h:17
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:133