libcamera v0.7.1
Supporting cameras in Linux since 2019
Loading...
Searching...
No Matches
utils.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2018, Google Inc.
4 *
5 * Miscellaneous utility functions
6 */
7
8#pragma once
9
10#include <algorithm>
11#include <chrono>
12#include <functional>
13#include <iterator>
14#include <ostream>
15#include <sstream>
16#include <stdint.h>
17#include <string.h>
18#include <string>
19#include <sys/time.h>
20#include <type_traits>
21#include <utility>
22#include <vector>
23
25#include <libcamera/base/private.h>
26
27#ifndef __DOXYGEN__
28
29/* uClibc and uClibc-ng don't provide O_TMPFILE */
30#ifndef O_TMPFILE
31#define O_TMPFILE (020000000 | O_DIRECTORY)
32#endif
33
34#endif
35
36namespace libcamera {
37
38namespace utils {
39
40template<class... Ts>
41struct overloaded : Ts... {
42 using Ts::operator()...;
43};
44#ifndef __DOXYGEN__
45template<class... Ts>
46overloaded(Ts...) -> overloaded<Ts...>;
47#endif
48
49const char *basename(const char *path);
50
51char *secure_getenv(const char *name);
52std::string dirname(const std::string &path);
53
54template<typename T>
55std::vector<typename T::key_type> map_keys(const T &map)
56{
57 std::vector<typename T::key_type> keys;
58 std::transform(map.begin(), map.end(), std::back_inserter(keys),
59 [](const auto &value) { return value.first; });
60 return keys;
61}
62
63template<class InputIt1, class InputIt2>
64unsigned int set_overlap(InputIt1 first1, InputIt1 last1,
65 InputIt2 first2, InputIt2 last2)
66{
67 unsigned int count = 0;
68
69 while (first1 != last1 && first2 != last2) {
70 if (*first1 < *first2) {
71 ++first1;
72 } else {
73 if (!(*first2 < *first1))
74 count++;
75 ++first2;
76 }
77 }
78
79 return count;
80}
81
82using clock = std::chrono::steady_clock;
83using duration = std::chrono::steady_clock::duration;
84using time_point = std::chrono::steady_clock::time_point;
85
86struct timespec duration_to_timespec(const duration &value);
87std::string time_point_to_string(const time_point &time);
88
89namespace details {
90
91struct hex {
92 uint64_t v;
93 unsigned int w;
94};
95
96template<typename T>
97constexpr unsigned int hex_width()
98{
99 return sizeof(T) * 2;
100}
101
102std::basic_ostream<char, std::char_traits<char>> &
103operator<<(std::basic_ostream<char, std::char_traits<char>> &stream, const hex &h);
104
105} /* namespace details */
106
107template<typename T, std::enable_if_t<std::is_integral_v<T>> * = nullptr>
108details::hex hex(T value, unsigned int width = details::hex_width<T>())
109{
110 return { static_cast<std::make_unsigned_t<T>>(value), width };
111}
112
113size_t strlcpy(char *dst, const char *src, size_t size);
114
115#ifndef __DOXYGEN__
116template<typename Container, typename UnaryOp>
117std::string join(const Container &items, const std::string &sep, UnaryOp op)
118{
119 std::ostringstream ss;
120 bool first = true;
121
122 for (const auto &item : items) {
123 if (!first)
124 ss << sep;
125 else
126 first = false;
127
128 ss << op(item);
129 }
130
131 return ss.str();
132}
133
134template<typename Container>
135std::string join(const Container &items, const std::string &sep)
136{
137 std::ostringstream ss;
138 bool first = true;
139
140 for (const auto &item : items) {
141 if (!first)
142 ss << sep;
143 else
144 first = false;
145
146 ss << item;
147 }
148
149 return ss.str();
150}
151#else
152template<typename Container, typename UnaryOp>
153std::string join(const Container &items, const std::string &sep, UnaryOp op = nullptr);
154#endif
155
156namespace details {
157
158class StringSplitter
159{
160public:
161 StringSplitter(const std::string &str, const std::string &delim);
162
163 class iterator
164 {
165 public:
166 using difference_type = std::size_t;
167 using value_type = std::string;
168 using pointer = value_type *;
169 using reference = value_type &;
170 using iterator_category = std::input_iterator_tag;
171
172 iterator(const StringSplitter *ss, std::string::size_type pos);
173
174 iterator &operator++();
175 std::string operator*() const;
176
177 bool operator==(const iterator &other) const
178 {
179 return pos_ == other.pos_;
180 }
181
182 bool operator!=(const iterator &other) const
183 {
184 return !(*this == other);
185 }
186
187 private:
188 const StringSplitter *ss_;
189 std::string::size_type pos_;
190 std::string::size_type next_;
191 };
192
193 iterator begin() const
194 {
195 return { this, 0 };
196 }
197
198 iterator end() const
199 {
200 return { this, std::string::npos };
201 }
202
203private:
204 std::string str_;
205 std::string delim_;
206};
207
208} /* namespace details */
209
210details::StringSplitter split(const std::string &str, const std::string &delim);
211
212std::string toAscii(const std::string &str);
213
214std::string libcameraBuildPath();
215std::string libcameraSourcePath();
216
217constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
218{
219 return value / alignment * alignment;
220}
221
222constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)
223{
224 return (value + alignment - 1) / alignment * alignment;
225}
226
227namespace details {
228
229template<typename T>
230struct reverse_adapter {
231 T &iterable;
232};
233
234template<typename T>
235auto begin(reverse_adapter<T> r)
236{
237 return std::rbegin(r.iterable);
238}
239
240template<typename T>
241auto end(reverse_adapter<T> r)
242{
243 return std::rend(r.iterable);
244}
245
246} /* namespace details */
247
248template<typename T>
249details::reverse_adapter<T> reverse(T &&iterable)
250{
251 return { iterable };
252}
253
254namespace details {
255
256template<typename Base>
257class enumerate_iterator
258{
259private:
260 using base_reference = typename std::iterator_traits<Base>::reference;
261
262public:
263 using difference_type = typename std::iterator_traits<Base>::difference_type;
264 using value_type = std::pair<const std::size_t, base_reference>;
265 using pointer = value_type *;
266 using reference = value_type &;
267 using iterator_category = std::input_iterator_tag;
268
269 explicit enumerate_iterator(Base iter)
270 : current_(iter), pos_(0)
271 {
272 }
273
274 enumerate_iterator &operator++()
275 {
276 ++current_;
277 ++pos_;
278 return *this;
279 }
280
281 bool operator!=(const enumerate_iterator &other) const
282 {
283 return current_ != other.current_;
284 }
285
286 value_type operator*() const
287 {
288 return { pos_, *current_ };
289 }
290
291private:
292 Base current_;
293 std::size_t pos_;
294};
295
296template<typename Base>
297class enumerate_adapter
298{
299public:
300 using iterator = enumerate_iterator<Base>;
301
302 enumerate_adapter(Base begin, Base end)
303 : begin_(begin), end_(end)
304 {
305 }
306
307 iterator begin() const
308 {
309 return iterator{ begin_ };
310 }
311
312 iterator end() const
313 {
314 return iterator{ end_ };
315 }
316
317private:
318 const Base begin_;
319 const Base end_;
320};
321
322} /* namespace details */
323
324template<typename T>
325auto enumerate(T &iterable)
326{
327 return details::enumerate_adapter{ std::begin(iterable), std::end(iterable) };
328}
329
330class Duration : public std::chrono::duration<double, std::nano>
331{
332 using BaseDuration = std::chrono::duration<double, std::nano>;
333
334public:
335 Duration() = default;
336
337 template<typename Rep>
338 constexpr explicit Duration(const Rep &r)
339 : BaseDuration(r)
340 {
341 }
342
343 template<typename Rep, typename Period>
344 constexpr Duration(const std::chrono::duration<Rep, Period> &d)
345 : BaseDuration(d)
346 {
347 }
348
349 template<typename Period>
350 double get() const
351 {
352 const auto c = std::chrono::duration_cast<std::chrono::duration<double, Period>>(*this);
353 return c.count();
354 }
355
356 constexpr Duration operator-() const
357 {
358 return BaseDuration::operator-();
359 }
360
361 explicit constexpr operator bool() const
362 {
363 return *this != BaseDuration::zero();
364 }
365};
366
367template<typename T>
368decltype(auto) abs_diff(const T &a, const T &b)
369{
370 if (a < b)
371 return b - a;
372 else
373 return a - b;
374}
375
376double strtod(const char *__restrict nptr, char **__restrict endptr);
377
378template<class Enum>
379constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept
380{
381 return static_cast<std::underlying_type_t<Enum>>(e);
382}
383
385{
386public:
388
389 void operator+=(std::function<void()> &&action);
390 void release();
391
392private:
393 std::vector<std::function<void()>> actions_;
394};
395
396#ifndef __DOXYGEN__
397template<typename EF>
398class scope_exit
399{
400public:
401 template<typename Fn,
402 std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Fn>>, scope_exit> &&
403 std::is_constructible_v<EF, Fn>> * = nullptr>
404 explicit scope_exit(Fn &&fn)
405 : exitFunction_(std::forward<Fn>(fn))
406 {
407 static_assert(std::is_nothrow_constructible_v<EF, Fn>);
408 }
409
410 ~scope_exit()
411 {
412 if (active_)
413 exitFunction_();
414 }
415
416 void release()
417 {
418 active_ = false;
419 }
420
421private:
423
424 EF exitFunction_;
425 bool active_ = true;
426};
427
428template<typename EF>
429scope_exit(EF) -> scope_exit<EF>;
430
431#endif /* __DOXYGEN__ */
432
433#ifndef __DOXYGEN__
434std::ostream &operator<<(std::ostream &os, const Duration &d);
435#endif
436
437} /* namespace utils */
438
439} /* 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
Helper class from std::chrono::duration that represents a time duration in nanoseconds with double pr...
Definition utils.h:331
constexpr Duration operator-() const
Negation operator to negate a Duration.
Definition utils.h:356
constexpr Duration(const Rep &r)
Construct a Duration with r ticks.
Definition utils.h:338
double get() const
Retrieve the tick count, converted to the timebase provided by the template argument Period of type s...
Definition utils.h:350
constexpr Duration(const std::chrono::duration< Rep, Period > &d)
Construct a Duration by converting an arbitrary std::chrono::duration.
Definition utils.h:344
An object that performs actions upon destruction.
Definition utils.h:385
void release()
Remove all exit actions.
Definition utils.cpp:683
void operator+=(std::function< void()> &&action)
Add an exit action.
Definition utils.cpp:671
Top-level libcamera namespace.
Definition backtrace.h:17
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:93
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:133
Helper type for type-matching std::visit() implementations.
Definition utils.h:41
unsigned int set_overlap(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
Count the number of elements in the intersection of two ranges.
Definition utils.h:64
constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)
Align value up to alignment.
Definition utils.h:222
std::chrono::steady_clock::duration duration
The libcamera duration related to libcamera::utils::clock.
Definition utils.h:83
auto enumerate(T &iterable)
Wrap an iterable to enumerate index and value in a range-based loop.
Definition utils.h:325
const char * basename(const char *path)
Strip the directory prefix from the path.
Definition utils.cpp:67
details::StringSplitter split(const std::string &str, const std::string &delim)
Split a string based on a delimiter.
Definition utils.cpp:339
std::string time_point_to_string(const time_point &time)
Convert a time point to a string representation.
Definition utils.cpp:205
std::chrono::steady_clock::time_point time_point
The libcamera time point related to libcamera::utils::clock.
Definition utils.h:84
std::string join(const Container &items, const std::string &sep, UnaryOp op=nullptr)
Join elements of a container in a string with a separator.
std::string libcameraSourcePath()
Retrieve the path to the source directory.
Definition source_paths.cpp:114
std::string toAscii(const std::string &str)
Remove any non-ASCII characters from a string.
Definition utils.cpp:353
constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
Align value down to alignment.
Definition utils.h:217
char * secure_getenv(const char *name)
Get an environment variable.
Definition utils.cpp:91
std::chrono::steady_clock clock
The libcamera clock (monotonic).
Definition utils.h:82
details::reverse_adapter< T > reverse(T &&iterable)
Wrap an iterable to reverse iteration in a range-based loop.
Definition utils.h:249
decltype(auto) abs_diff(const T &a, const T &b)
Calculates the absolute value of the difference between two elements.
Definition utils.h:368
std::vector< typename T::key_type > map_keys(const T &map)
Retrieve the keys of a std::map<>.
Definition utils.h:55
std::string libcameraBuildPath()
Retrieve the path to the build directory.
Definition source_paths.cpp:74
struct timespec duration_to_timespec(const duration &value)
Convert a duration to a timespec.
Definition utils.cpp:191
constexpr std::underlying_type_t< Enum > to_underlying(Enum e) noexcept
Convert an enumeration to its underlygin type.
Definition utils.h:379
details::hex hex(T value, unsigned int width=details::hex_width< T >())
Write an hexadecimal value to an output string.
Definition utils.h:108
std::string dirname(const std::string &path)
Identify the dirname portion of a path.
Definition utils.cpp:113