| Message ID | 20260423230059.3180987-2-laurent.pinchart@ideasonboard.com |
|---|---|
| State | Superseded |
| Headers | show |
| Series |
|
| Related | show |
Hi Laurent On Fri, Apr 24, 2026 at 02:00:23AM +0300, Laurent Pinchart wrote: > From: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > > 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> > --- > Changes since v8 of "[PATCH v8 0/8] libcamera: mali-c55: Add support for memory-to-memory": > > - Small improvements to documentation > - Drop documentation of deduction guide > --- Fine with me Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > include/libcamera/base/utils.h | 9 +++++++ > src/libcamera/base/utils.cpp | 30 ++++++++++++++++++++++ > src/libcamera/pipeline/virtual/virtual.cpp | 10 ++------ > 3 files changed, 41 insertions(+), 8 deletions(-) > > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h > index 7083b7ce9ce9..b33a4c644a87 100644 > --- a/include/libcamera/base/utils.h > +++ b/include/libcamera/base/utils.h > @@ -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); > diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp > index 42a516097be2..4ab2bd863e11 100644 > --- a/src/libcamera/base/utils.cpp > +++ b/src/libcamera/base/utils.cpp > @@ -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 > diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp > index efd800ebe3d6..e8ef7e524ccf 100644 > --- a/src/libcamera/pipeline/virtual/virtual.cpp > +++ b/src/libcamera/pipeline/virtual/virtual.cpp > @@ -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) > -- > Regards, > > Laurent Pinchart >
diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index 7083b7ce9ce9..b33a4c644a87 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -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); diff --git a/src/libcamera/base/utils.cpp b/src/libcamera/base/utils.cpp index 42a516097be2..4ab2bd863e11 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -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 diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index efd800ebe3d6..e8ef7e524ccf 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -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)