diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-12-15 11:44:32 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-12-18 18:31:37 +0000 |
commit | 4844c096a8ab6a9a620c410a0949d4499f12a504 (patch) | |
tree | 38967ed6ef03f90ae6cef48c313e77b7ba93b139 /include/comphelper/servicehelper.hxx | |
parent | 9a0b523e0a84d403b9092176ccec4b3e3efe42d0 (diff) |
loplugin:unocast (cairocanvas::SurfaceProvider)
(See the upcoming commit introducing that loplugin:unocast on why such
dynamic_casts from UNO types are dangerous.)
There are implementation classes whose getSomething already delegates to
RepaintTarget, so they can't also delegate to SurfaceProvider. So introduce the
concept of comphelper::getSomethingImpl additionally delegating to a sequence of
mixin classes before delegating to the base.
Change-Id: I9230f3dc06abbdd1ad92514a11473dae2624f7c1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144404
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'include/comphelper/servicehelper.hxx')
-rw-r--r-- | include/comphelper/servicehelper.hxx | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/include/comphelper/servicehelper.hxx b/include/comphelper/servicehelper.hxx index c225494ccf1b..1d157cbf1482 100644 --- a/include/comphelper/servicehelper.hxx +++ b/include/comphelper/servicehelper.hxx @@ -82,6 +82,16 @@ namespace comphelper { && memcmp(T::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16) == 0; } + template<typename T> struct MixinToGetSomethingOf { + static bool get(css::uno::Sequence<sal_Int8> const & id, T * p, sal_Int64 * result) { + if (!isUnoTunnelId<T>(id)) { + return false; + } + *result = getSomething_cast(p); + return true; + } + }; + template <class Base> struct FallbackToGetSomethingOf { static sal_Int64 get(const css::uno::Sequence<sal_Int8>& rId, Base* p) @@ -95,12 +105,65 @@ namespace comphelper { static sal_Int64 get(const css::uno::Sequence<sal_Int8>&, void*) { return 0; } }; + // There are five cases how to implement T::getSomething: + // (1) Delegate to Base: + // Either, if Base has only getUnoTunnelId but no getSomething: + // return getSomethingImpl<Base>(aIdentifier, this); + // Or, if Base has getSomething: + // return Base::getSomething(aIdentifier) + // (2) Check against T::getUnoTunnelId, else return 0: + // return getSomethingImpl(aIdentifier, this); + // (3) Check against T::getUnoTunnelId, else delegate to Base: + // return getSomethingImpl(aIdentifier, this, FallbackToGetSomethingOf<Base>{}); + // (4) Check against T::getUnoTunnelId, else check against each Mixins::getUnoTunnelId, else + // delegate to Base: + // return getSomethingImpl( + // aIdentifier, this, MixinToGetSomethingOf<Mixin1>{}, ..., + // MixinToGetSomethingOf<MixinN>{}, FallbackToGetSomethingOf<Base>{}); + // (5) Check against each Mixins::getUnoTunnelId, else delegate to Base: + // return getSomethingImpl_skipDerived( + // aIdentifier, this, MixinToGetSomethingOf<Mixin1>{}, ..., + // MixinToGetSomethingOf<MixinN>{}, FallbackToGetSomethingOf<Base>{}); + template <class T, class Base = void> sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis, FallbackToGetSomethingOf<Base> = {}) { - if (isUnoTunnelId<T>(rId)) - return getSomething_cast(pThis); + sal_Int64 res; + if (MixinToGetSomethingOf<T>::get(rId, pThis, &res)) { + return res; + } + + return FallbackToGetSomethingOf<Base>::get(rId, pThis); + } + + template <class T, class Mixin, class... Mixins, class Base> + sal_Int64 getSomethingImpl(const css::uno::Sequence<sal_Int8>& rId, T* pThis, + MixinToGetSomethingOf<Mixin>, MixinToGetSomethingOf<Mixins>..., + FallbackToGetSomethingOf<Base>) + { + sal_Int64 res; + if (((MixinToGetSomethingOf<T>::get(rId, pThis, &res) + || MixinToGetSomethingOf<Mixin>::get(rId, pThis, &res)) || ... + || MixinToGetSomethingOf<Mixins>::get(rId, pThis, &res))) + { + return res; + } + + return FallbackToGetSomethingOf<Base>::get(rId, pThis); + } + + template <class T, class Mixin, class... Mixins, class Base> + sal_Int64 getSomethingImpl_skipDerived(const css::uno::Sequence<sal_Int8>& rId, T* pThis, + MixinToGetSomethingOf<Mixin>, MixinToGetSomethingOf<Mixins>..., + FallbackToGetSomethingOf<Base>) + { + sal_Int64 res; + if ((MixinToGetSomethingOf<Mixin>::get(rId, pThis, &res) || ... + || MixinToGetSomethingOf<Mixins>::get(rId, pThis, &res))) + { + return res; + } return FallbackToGetSomethingOf<Base>::get(rId, pThis); } |