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