Loading...
Searching...
No Matches
utils.h
Go to the documentation of this file.
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2018, Google Inc.
*
* Miscellaneous utility functions
*/
#pragma once
#include <algorithm>
#include <chrono>
#include <functional>
#include <iterator>
#include <ostream>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>
#include <sys/time.h>
#include <type_traits>
#include <utility>
#include <vector>
#include <libcamera/base/class.h>
#include <libcamera/base/private.h>
#ifndef __DOXYGEN__
/* uClibc and uClibc-ng don't provide O_TMPFILE */
#ifndef O_TMPFILE
#define O_TMPFILE (020000000 | O_DIRECTORY)
#endif
#endif
namespace libcamera {
namespace utils {
const char *basename(const char *path);
char *secure_getenv(const char *name);
std::string dirname(const std::string &path);
template<typename T>
std::vector<typename T::key_type> map_keys(const T &map)
{
std::vector<typename T::key_type> keys;
std::transform(map.begin(), map.end(), std::back_inserter(keys),
[](const auto &value) { return value.first; });
return keys;
}
template<class InputIt1, class InputIt2>
unsigned int set_overlap(InputIt1 first1, InputIt1 last1,
InputIt2 first2, InputIt2 last2)
{
unsigned int count = 0;
while (first1 != last1 && first2 != last2) {
if (*first1 < *first2) {
++first1;
} else {
if (!(*first2 < *first1))
count++;
++first2;
}
}
return count;
}
using clock = std::chrono::steady_clock;
using duration = std::chrono::steady_clock::duration;
using time_point = std::chrono::steady_clock::time_point;
struct timespec duration_to_timespec(const duration &value);
std::string time_point_to_string(const time_point &time);
namespace details {
struct hex {
uint64_t v;
unsigned int w;
};
template<typename T>
constexpr unsigned int hex_width()
{
return sizeof(T) * 2;
}
std::basic_ostream<char, std::char_traits<char>> &
operator<<(std::basic_ostream<char, std::char_traits<char>> &stream, const hex &h);
} /* namespace details */
template<typename T, std::enable_if_t<std::is_integral_v<T>> * = nullptr>
details::hex hex(T value, unsigned int width = details::hex_width<T>())
{
return { static_cast<std::make_unsigned_t<T>>(value), width };
}
size_t strlcpy(char *dst, const char *src, size_t size);
#ifndef __DOXYGEN__
template<typename Container, typename UnaryOp>
std::string join(const Container &items, const std::string &sep, UnaryOp op)
{
std::ostringstream ss;
bool first = true;
for (auto it = std::begin(items); it != std::end(items); ++it) {
if (!first)
ss << sep;
else
first = false;
ss << op(*it);
}
return ss.str();
}
template<typename Container>
std::string join(const Container &items, const std::string &sep)
{
std::ostringstream ss;
bool first = true;
for (auto it = std::begin(items); it != std::end(items); ++it) {
if (!first)
ss << sep;
else
first = false;
ss << *it;
}
return ss.str();
}
#else
template<typename Container, typename UnaryOp>
std::string join(const Container &items, const std::string &sep, UnaryOp op = nullptr);
#endif
namespace details {
class StringSplitter
{
public:
StringSplitter(const std::string &str, const std::string &delim);
class iterator
{
public:
using difference_type = std::size_t;
using value_type = std::string;
using pointer = value_type *;
using reference = value_type &;
using iterator_category = std::input_iterator_tag;
iterator(const StringSplitter *ss, std::string::size_type pos);
iterator &operator++();
std::string operator*() const;
bool operator==(const iterator &other) const
{
return pos_ == other.pos_;
}
bool operator!=(const iterator &other) const
{
return !(*this == other);
}
private:
const StringSplitter *ss_;
std::string::size_type pos_;
std::string::size_type next_;
};
iterator begin() const
{
return { this, 0 };
}
iterator end() const
{
return { this, std::string::npos };
}
private:
std::string str_;
std::string delim_;
};
} /* namespace details */
details::StringSplitter split(const std::string &str, const std::string &delim);
std::string toAscii(const std::string &str);
std::string libcameraBuildPath();
std::string libcameraSourcePath();
constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
{
return value / alignment * alignment;
}
constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)
{
return (value + alignment - 1) / alignment * alignment;
}
namespace details {
template<typename T>
struct reverse_adapter {
T &iterable;
};
template<typename T>
auto begin(reverse_adapter<T> r)
{
return std::rbegin(r.iterable);
}
template<typename T>
auto end(reverse_adapter<T> r)
{
return std::rend(r.iterable);
}
} /* namespace details */
template<typename T>
details::reverse_adapter<T> reverse(T &&iterable)
{
return { iterable };
}
namespace details {
template<typename Base>
class enumerate_iterator
{
private:
using base_reference = typename std::iterator_traits<Base>::reference;
public:
using difference_type = typename std::iterator_traits<Base>::difference_type;
using value_type = std::pair<const std::size_t, base_reference>;
using pointer = value_type *;
using reference = value_type &;
using iterator_category = std::input_iterator_tag;
explicit enumerate_iterator(Base iter)
: current_(iter), pos_(0)
{
}
enumerate_iterator &operator++()
{
++current_;
++pos_;
return *this;
}
bool operator!=(const enumerate_iterator &other) const
{
return current_ != other.current_;
}
value_type operator*() const
{
return { pos_, *current_ };
}
private:
Base current_;
std::size_t pos_;
};
template<typename Base>
class enumerate_adapter
{
public:
using iterator = enumerate_iterator<Base>;
enumerate_adapter(Base begin, Base end)
: begin_(begin), end_(end)
{
}
iterator begin() const
{
return iterator{ begin_ };
}
iterator end() const
{
return iterator{ end_ };
}
private:
const Base begin_;
const Base end_;
};
} /* namespace details */
template<typename T>
auto enumerate(T &iterable)
{
return details::enumerate_adapter{ std::begin(iterable), std::end(iterable) };
}
class Duration : public std::chrono::duration<double, std::nano>
{
using BaseDuration = std::chrono::duration<double, std::nano>;
public:
Duration() = default;
template<typename Rep>
constexpr explicit Duration(const Rep &r)
: BaseDuration(r)
{
}
template<typename Rep, typename Period>
constexpr Duration(const std::chrono::duration<Rep, Period> &d)
: BaseDuration(d)
{
}
template<typename Period>
double get() const
{
auto const c = std::chrono::duration_cast<std::chrono::duration<double, Period>>(*this);
return c.count();
}
constexpr Duration operator-() const
{
return BaseDuration::operator-();
}
explicit constexpr operator bool() const
{
return *this != BaseDuration::zero();
}
};
template<typename T>
decltype(auto) abs_diff(const T &a, const T &b)
{
if (a < b)
return b - a;
else
return a - b;
}
double strtod(const char *__restrict nptr, char **__restrict endptr);
template<class Enum>
constexpr std::underlying_type_t<Enum> to_underlying(Enum e) noexcept
{
return static_cast<std::underlying_type_t<Enum>>(e);
}
class ScopeExitActions
{
public:
~ScopeExitActions();
void operator+=(std::function<void()> &&action);
void release();
private:
std::vector<std::function<void()>> actions_;
};
#ifndef __DOXYGEN__
template<typename EF>
class scope_exit
{
public:
template<typename Fn,
std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Fn>>, scope_exit> &&
std::is_constructible_v<EF, Fn>> * = nullptr>
explicit scope_exit(Fn &&fn)
: exitFunction_(std::forward<Fn>(fn))
{
static_assert(std::is_nothrow_constructible_v<EF, Fn>);
}
~scope_exit()
{
if (active_)
exitFunction_();
}
void release()
{
active_ = false;
}
private:
LIBCAMERA_DISABLE_COPY_AND_MOVE(scope_exit)
EF exitFunction_;
bool active_ = true;
};
template<typename EF>
scope_exit(EF) -> scope_exit<EF>;
#endif /* __DOXYGEN__ */
#ifndef __DOXYGEN__
std::ostream &operator<<(std::ostream &os, const Duration &d);
#endif
} /* namespace utils */
} /* 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:322
libcamera::utils::Duration::operator-
constexpr Duration operator-() const
Negation operator to negate a Duration.
Definition utils.h:347
libcamera::utils::Duration::Duration
constexpr Duration(const Rep &r)
Construct a Duration with r ticks.
Definition utils.h:329
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:341
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:335
libcamera::utils::ScopeExitActions
An object that performs actions upon destruction.
Definition utils.h:376
libcamera::utils::ScopeExitActions::release
void release()
Remove all exit actions.
Definition utils.cpp:653
libcamera::utils::ScopeExitActions::operator+=
void operator+=(std::function< void()> &&action)
Add an exit action.
Definition utils.cpp:641
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:91
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::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:55
libcamera::utils::alignUp
constexpr unsigned int alignUp(unsigned int value, unsigned int alignment)
Align value up to alignment.
Definition utils.h:213
libcamera::utils::duration
std::chrono::steady_clock::duration duration
The libcamera duration related to libcamera::utils::clock.
Definition utils.h:74
libcamera::utils::enumerate
auto enumerate(T &iterable)
Wrap an iterable to enumerate index and value in a range-based loop.
Definition utils.h:316
libcamera::utils::basename
const char * basename(const char *path)
Strip the directory prefix from the path.
Definition utils.cpp:37
libcamera::utils::split
details::StringSplitter split(const std::string &str, const std::string &delim)
Split a string based on a delimiter.
Definition utils.cpp:309
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:175
libcamera::utils::time_point
std::chrono::steady_clock::time_point time_point
The libcamera time point related to libcamera::utils::clock.
Definition utils.h:75
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:323
libcamera::utils::alignDown
constexpr unsigned int alignDown(unsigned int value, unsigned int alignment)
Align value down to alignment.
Definition utils.h:208
libcamera::utils::secure_getenv
char * secure_getenv(const char *name)
Get an environment variable.
Definition utils.cpp:61
libcamera::utils::clock
std::chrono::steady_clock clock
The libcamera clock (monotonic).
Definition utils.h:73
libcamera::utils::reverse
details::reverse_adapter< T > reverse(T &&iterable)
Wrap an iterable to reverse iteration in a range-based loop.
Definition utils.h:240
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:359
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:46
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:161
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:370
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:99
libcamera::utils::dirname
std::string dirname(const std::string &path)
Identify the dirname portion of a path.
Definition utils.cpp:83