libcamera: utils: Add overloaded visitor helpers

std::visit() allows quite elegant type-matching implementation of the
visitor pattern.

The 'overloaded' type helpers allow to define a hierarchy of overloaded
operator() implementations which can be used by std::visit().

Currently only the Virtual pipeline handler uses this type-matching
implementation of std::visit(). To prepare to add another user in the
Mali C55 pipeline handler move the 'overloaded' helper type to
libcamera::utils for easier re-use.

Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
Jacopo Mondi
2026-04-24 02:00:23 +03:00
parent 157f03e2df
commit c52e8cde3e
3 changed files with 41 additions and 8 deletions

View File

@@ -37,6 +37,15 @@ namespace libcamera {
namespace utils {
template<class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};
#ifndef __DOXYGEN__
template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
#endif
const char *basename(const char *path);
char *secure_getenv(const char *name);

View File

@@ -23,6 +23,36 @@ namespace libcamera {
namespace utils {
/**
* \struct overloaded
* \brief Helper type for type-matching std::visit() implementations
* \tparam Ts... Template arguments pack of visitors
*
* Expand the template argument pack \a Ts... to provide overloaded \a
* operator() to support type-matching implementations of the visitor design
* pattern using std::visit().
*
* An example is provided by the C++ standard library documentation in the form
* of:
*
* \code{.cpp}
* template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
* template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
*
* using var_t = std::variant<int, long, double, std::string>;
* std::vector<var_t> vec = {10, 15l, 1.5, "hello"};
*
* for (auto& v: vec) {
* std::visit(overloaded {
* [](auto arg) { std::cout << arg << ' '; },
* [](double arg) { std::cout << std::fixed << arg << ' '; },
* [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
* }, v);
* \endcode
*
* Use this helper to implement type-matching visitors using std::visit().
*/
/**
* \brief Strip the directory prefix from the path
* \param[in] path The path to process

View File

@@ -23,6 +23,7 @@
#include <libcamera/base/flags.h>
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
#include <libcamera/control_ids.h>
#include <libcamera/controls.h>
@@ -57,13 +58,6 @@ uint64_t currentTimestamp()
} /* namespace */
template<class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
};
template<class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;
class VirtualCameraConfiguration : public CameraConfiguration
{
public:
@@ -428,7 +422,7 @@ bool PipelineHandlerVirtual::initFrameGenerator(Camera *camera)
{
auto data = cameraData(camera);
auto &frame = data->config_.frame;
std::visit(overloaded{
std::visit(utils::overloaded{
[&](TestPattern &testPattern) {
for (auto &streamConfig : data->streamConfigs_) {
if (testPattern == TestPattern::DiagonalLines)