libcamera: include/libcamera/base/utils.h Source File

libcamera v0.7.2 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
24#include <libcamera/base/class.h>
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>
41 struct overloaded : Ts... {
42 using Ts::operator()...;
43};
44#ifndef __DOXYGEN__
45template<class... Ts>
46 overloaded(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>
64 unsigned 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
82 using clock = std::chrono::steady_clock;
83 using duration = std::chrono::steady_clock::duration;
84 using 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
217 constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
218{
219 return value / alignment * alignment;
220}
221
222 constexpr 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>
325 auto enumerate(T &iterable)
326{
327 return details::enumerate_adapter{ std::begin(iterable), std::end(iterable) };
328}
329
330 class 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>
368 decltype(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>
379 constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept
380{
381 return static_cast<std::underlying_type_t<Enum>>(e);
382}
383
384 class ScopeExitActions
385{
386public:
387 ~ScopeExitActions();
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:
422 LIBCAMERA_DISABLE_COPY_AND_MOVE(scope_exit)
423
424 EF exitFunction_;
425 bool active_ = true;
426};
427
428template<typename EF>
429scope_exit(EF) -> scope_exit<EF>;
430
431#endif /* __DOXYGEN__ */
432
433namespace details {
434
435struct defopt_t {
436 template<typename T>
437 constexpr operator T() const
438 {
439 static_assert(std::is_default_constructible_v<T>);
440 return T{};
441 }
442};
443
444} /* namespace details */
445
446 constexpr details::defopt_t defopt;
447
448#ifndef __DOXYGEN__
449std::ostream &operator<<(std::ostream &os, const Duration &d);
450#endif
451
452} /* namespace utils */
453
454} /* namespace libcamera */
class.h
Utilities to help constructing class interfaces.
LIBCAMERA_DISABLE_COPY_AND_MOVE
#define LIBCAMERA_DISABLE_COPY_AND_MOVE(klass)
Disable copy and move construction and assignment of the klass.
Definition class.h:29
libcamera::utils::Duration
Helper class from std::chrono::duration that represents a time duration in nanoseconds with double pr...
Definition utils.h:331
libcamera::utils::Duration::operator-
constexpr Duration operator-() const
Negation operator to negate a Duration.
Definition utils.h:356
libcamera::utils::Duration::Duration
constexpr Duration(const Rep &r)
Construct a Duration with r ticks.
Definition utils.h:338
libcamera::utils::Duration::get
double get() const
Retrieve the tick count, converted to the timebase provided by the template argument Period of type s...
Definition utils.h:350
libcamera::utils::Duration::Duration
constexpr Duration(const std::chrono::duration< Rep, Period > &d)
Construct a Duration by converting an arbitrary std::chrono::duration.
Definition utils.h:344
libcamera::utils::ScopeExitActions
An object that performs actions upon destruction.
Definition utils.h:385
libcamera::utils::ScopeExitActions::release
void release()
Remove all exit actions.
Definition utils.cpp:683
libcamera::utils::ScopeExitActions::operator+=
void operator+=(std::function< void()> &&action)
Add an exit action.
Definition utils.cpp:671
libcamera
Top-level libcamera namespace.
Definition backtrace.h:17
libcamera::operator<<
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:93
libcamera::operator*
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:133
libcamera::operator==
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition color_space.cpp:506
libcamera::operator!=
bool operator!=(const Vector< T, Rows > &lhs, const Vector< T, Rows > &rhs)
Compare vectors for inequality.
Definition vector.h:347
libcamera::utils::overloaded
Helper type for type-matching std::visit() implementations.
Definition utils.h:41
libcamera::utils::set_overlap
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
libcamera::utils::alignUp
constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)
Align value up to alignment.
Definition utils.h:222
libcamera::utils::duration
std::chrono::steady_clock::duration duration
The libcamera duration related to libcamera::utils::clock.
Definition utils.h:83
libcamera::utils::enumerate
auto enumerate(T &iterable)
Wrap an iterable to enumerate index and value in a range-based loop.
Definition utils.h:325
libcamera::utils::basename
const char * basename(const char *path)
Strip the directory prefix from the path.
Definition utils.cpp:67
libcamera::utils::split
details::StringSplitter split(const std::string &str, const std::string &delim)
Split a string based on a delimiter.
Definition utils.cpp:339
libcamera::utils::time_point_to_string
std::string time_point_to_string(const time_point &time)
Convert a time point to a string representation.
Definition utils.cpp:205
libcamera::utils::time_point
std::chrono::steady_clock::time_point time_point
The libcamera time point related to libcamera::utils::clock.
Definition utils.h:84
libcamera::utils::join
std::string join(const Container &items, const std::string &sep, UnaryOp op=nullptr)
Join elements of a container in a string with a separator.
libcamera::utils::libcameraSourcePath
std::string libcameraSourcePath()
Retrieve the path to the source directory.
Definition source_paths.cpp:114
libcamera::utils::toAscii
std::string toAscii(const std::string &str)
Remove any non-ASCII characters from a string.
Definition utils.cpp:353
libcamera::utils::alignDown
constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
Align value down to alignment.
Definition utils.h:217
libcamera::utils::secure_getenv
char * secure_getenv(const char *name)
Get an environment variable.
Definition utils.cpp:91
libcamera::utils::clock
std::chrono::steady_clock clock
The libcamera clock (monotonic).
Definition utils.h:82
libcamera::utils::reverse
details::reverse_adapter< T > reverse(T &&iterable)
Wrap an iterable to reverse iteration in a range-based loop.
Definition utils.h:249
libcamera::utils::abs_diff
decltype(auto) abs_diff(const T &a, const T &b)
Calculates the absolute value of the difference between two elements.
Definition utils.h:368
libcamera::utils::defopt
constexpr details::defopt_t defopt
Constant used with std::optional::value_or() to create a default-constructed object.
Definition utils.h:446
libcamera::utils::map_keys
std::vector< typename T::key_type > map_keys(const T &map)
Retrieve the keys of a std::map<>.
Definition utils.h:55
libcamera::utils::libcameraBuildPath
std::string libcameraBuildPath()
Retrieve the path to the build directory.
Definition source_paths.cpp:74
libcamera::utils::duration_to_timespec
struct timespec duration_to_timespec(const duration &value)
Convert a duration to a timespec.
Definition utils.cpp:191
libcamera::utils::to_underlying
constexpr std::underlying_type_t< Enum > to_underlying(Enum e) noexcept
Convert an enumeration to its underlygin type.
Definition utils.h:379
libcamera::utils::hex
details::hex hex(T value, unsigned int width=details::hex_width< T >())
Write an hexadecimal value to an output string.
Definition utils.h:108
libcamera::utils::dirname
std::string dirname(const std::string &path)
Identify the dirname portion of a path.
Definition utils.cpp:113