[libcamera-devel] [PATCH v1 3/6] libcamera: base: bound_method: Remove BoundMethodArgs specialization
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Aug 31 11:28:37 CEST 2021
Hi Umang,
On Tue, Aug 31, 2021 at 11:13:12AM +0530, Umang Jain wrote:
> On 8/27/21 8:08 AM, Laurent Pinchart wrote:
> > The BoundMethodArgs specialization for the void return type is only
> > needed to avoid accessing the ret_ member variable that is lacking from
> > the corresponding BoundMethodPack specialization. As the member variable
> > is only accessed in a single function, instead of specializing the whole
> > class we can use SFINAE to select between two different implementations
> > of the function.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> > include/libcamera/base/bound_method.h | 34 +++++++--------------------
> > 1 file changed, 8 insertions(+), 26 deletions(-)
> >
> > diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h
> > index 9c212f1ecc3a..76ce8017e721 100644
> > --- a/include/libcamera/base/bound_method.h
> > +++ b/include/libcamera/base/bound_method.h
> > @@ -98,35 +98,17 @@ public:
> > using PackType = BoundMethodPack<R, Args...>;
> >
> > private:
> > - template<std::size_t... I>
> > - void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
> > + template<std::size_t... I, typename T = R>
> > + std::enable_if_t<!std::is_void<T>::value, void>
> > + invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
> > {
> > PackType *args = static_cast<PackType *>(pack);
> > args->ret_ = invoke(std::get<I>(args->args_)...);
> > }
> >
> > -public:
> > - BoundMethodArgs(void *obj, Object *object, ConnectionType type)
> > - : BoundMethodBase(obj, object, type) {}
> > -
> > - void invokePack(BoundMethodPackBase *pack) override
> > - {
> > - invokePack(pack, std::make_index_sequence<sizeof...(Args)>{});
> > - }
> > -
> > - virtual R activate(Args... args, bool deleteMethod = false) = 0;
> > - virtual R invoke(Args... args) = 0;
> > -};
> > -
> > -template<typename... Args>
> > -class BoundMethodArgs<void, Args...> : public BoundMethodBase
> > -{
> > -public:
> > - using PackType = BoundMethodPack<void, Args...>;
> > -
> > -private:
> > - template<std::size_t... I>
> > - void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
> > + template<std::size_t... I, typename T = R>
>
>
> As you have explained to me the workaround of T= R on IRC, that
> std::enable_if works on function template argument typename rather on
> class template argument, do you mind capturing this as a comment here or
> in the commit message while pushing?
I'll add this to the commit messge:
SFINAE can only depend on the function template parameters, not the
parameters of the class template in which the function is defined:
"Only the failures in the types and expressions in the immediate context
of the function type or its template parameter types are SFINAE errors."
We thus can't use the type R in an std::enable_if expression for the
invokePack() function. To work around this, we have to add a type T to
the function template definition, which defaults to R, and use T with
std::enable_if.
> > + std::enable_if_t<std::is_void<T>::value, void>
> > + invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
> > {
> > /* args is effectively unused when the sequence I is empty. */
> > PackType *args [[gnu::unused]] = static_cast<PackType *>(pack);
> > @@ -142,8 +124,8 @@ public:
> > invokePack(pack, std::make_index_sequence<sizeof...(Args)>{});
> > }
> >
> > - virtual void activate(Args... args, bool deleteMethod = false) = 0;
> > - virtual void invoke(Args... args) = 0;
> > + virtual R activate(Args... args, bool deleteMethod = false) = 0;
> > + virtual R invoke(Args... args) = 0;
> > };
> >
> > template<typename T, typename R, typename... Args>
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list