| Message ID | 20260313-mali-cru-v4-2-c0d9bc8cd8fa@ideasonboard.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
2026. 03. 13. 12:33 keltezéssel, Jacopo Mondi írta: > std::visit() allows quite elegant type-matching implementation of the > visitor pattern. > > The overaloded type helpers allow to define a hierarchy of overloaded '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 types to type > libcamera::utils for easier re-use. > > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > --- > include/libcamera/base/utils.h | 7 ++++++ > src/libcamera/base/utils.cpp | 35 ++++++++++++++++++++++++++++++ > src/libcamera/pipeline/virtual/virtual.cpp | 10 ++------- > 3 files changed, 44 insertions(+), 8 deletions(-) > > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h > index 7083b7ce9ce9..62c7f89c25a1 100644 > --- a/include/libcamera/base/utils.h > +++ b/include/libcamera/base/utils.h > @@ -37,6 +37,13 @@ namespace libcamera { > > namespace utils { > > +template<class... Ts> > +struct overloaded : Ts... { > + using Ts::operator()...; > +}; > +template<class... Ts> > +overloaded(Ts...) -> overloaded<Ts...>; > + > 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..a18ca82e8d07 100644 > --- a/src/libcamera/base/utils.cpp > +++ b/src/libcamera/base/utils.cpp > @@ -23,6 +23,41 @@ 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 > + * implementations of \a operator(). > + */ > + > +/** > + * \var <class... Ts> overloaded(Ts...) -> overloaded<Ts...> This is just a deduction guide. Does doxygen fail if it is not documented? In any case, if documented, I think it should just mention that this is a deduction guide necessary for C++17. And the below text should be moved to the documentation of the type itself. Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > + * \brief Overloaded visitor class for type-matching std::visit implementations > + * \tparam Ts... Template arguments pack of visitor functions > + * > + * std::visit allows quite elegant type-matching implementation of the visitor > + * pattern. An example is provided by the STL 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) >
On Fri, Mar 13, 2026 at 02:57:34PM +0100, Barnabás Pőcze wrote: > 2026. 03. 13. 12:33 keltezéssel, Jacopo Mondi írta: > > std::visit() allows quite elegant type-matching implementation of the > > visitor pattern. > > > > The overaloded type helpers allow to define a hierarchy of overloaded > '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 types to > type > > > > libcamera::utils for easier re-use. > > > > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> > > --- > > include/libcamera/base/utils.h | 7 ++++++ > > src/libcamera/base/utils.cpp | 35 ++++++++++++++++++++++++++++++ > > src/libcamera/pipeline/virtual/virtual.cpp | 10 ++------- > > 3 files changed, 44 insertions(+), 8 deletions(-) > > > > diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h > > index 7083b7ce9ce9..62c7f89c25a1 100644 > > --- a/include/libcamera/base/utils.h > > +++ b/include/libcamera/base/utils.h > > @@ -37,6 +37,13 @@ namespace libcamera { > > namespace utils { > > +template<class... Ts> > > +struct overloaded : Ts... { > > + using Ts::operator()...; > > +}; > > +template<class... Ts> > > +overloaded(Ts...) -> overloaded<Ts...>; > > + > > 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..a18ca82e8d07 100644 > > --- a/src/libcamera/base/utils.cpp > > +++ b/src/libcamera/base/utils.cpp > > @@ -23,6 +23,41 @@ 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 > > + * implementations of \a operator(). > > + */ > > + > > +/** > > + * \var <class... Ts> overloaded(Ts...) -> overloaded<Ts...> > > This is just a deduction guide. Does doxygen fail if it is not documented? In any case, It's pretty easy to test: yes, it does include/libcamera/base/utils.h:45: warning: Member overloaded(Ts...) -> overloaded< Ts... > (function) of namespace libcamera::utils is not documented. > if documented, I think it should just mention that this is a deduction guide necessary > for C++17. And the below text should be moved to the documentation of the type itself. > I'll move the documentation! > Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Thanks j > > > > + * \brief Overloaded visitor class for type-matching std::visit implementations > > + * \tparam Ts... Template arguments pack of visitor functions > > + * > > + * std::visit allows quite elegant type-matching implementation of the visitor > > + * pattern. An example is provided by the STL 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) > > >
diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index 7083b7ce9ce9..62c7f89c25a1 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -37,6 +37,13 @@ namespace libcamera { namespace utils { +template<class... Ts> +struct overloaded : Ts... { + using Ts::operator()...; +}; +template<class... Ts> +overloaded(Ts...) -> overloaded<Ts...>; + 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..a18ca82e8d07 100644 --- a/src/libcamera/base/utils.cpp +++ b/src/libcamera/base/utils.cpp @@ -23,6 +23,41 @@ 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 + * implementations of \a operator(). + */ + +/** + * \var <class... Ts> overloaded(Ts...) -> overloaded<Ts...> + * \brief Overloaded visitor class for type-matching std::visit implementations + * \tparam Ts... Template arguments pack of visitor functions + * + * std::visit allows quite elegant type-matching implementation of the visitor + * pattern. An example is provided by the STL 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)
std::visit() allows quite elegant type-matching implementation of the visitor pattern. The overaloded 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 types to libcamera::utils for easier re-use. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> --- include/libcamera/base/utils.h | 7 ++++++ src/libcamera/base/utils.cpp | 35 ++++++++++++++++++++++++++++++ src/libcamera/pipeline/virtual/virtual.cpp | 10 ++------- 3 files changed, 44 insertions(+), 8 deletions(-)