From d57de45a30953d7884d6b3fe4a82d11ef537d078 Mon Sep 17 00:00:00 2001 From: Floris Berendsen <floris.berendsen@gmail.com> Date: Mon, 16 Nov 2015 17:26:18 +0100 Subject: [PATCH] ENH: Accepting/Providing interfaces via variadic templates --- .../Core/ComponentInterface/ComponentBase.h | 1 - .../GDOptimizer3rdPartyComponent.cxx | 32 ++++----- .../GDOptimizer3rdPartyComponent.h | 8 ++- .../Core/ComponentInterface/Interfaces.hxx | 67 ++++++++++++++++++- .../ComponentInterface/componenthandshake.cxx | 2 + 5 files changed, 92 insertions(+), 18 deletions(-) diff --git a/Modules/Core/ComponentInterface/ComponentBase.h b/Modules/Core/ComponentInterface/ComponentBase.h index 78da4c6a..06857cfd 100644 --- a/Modules/Core/ComponentInterface/ComponentBase.h +++ b/Modules/Core/ComponentInterface/ComponentBase.h @@ -9,6 +9,5 @@ namespace elx protected: virtual ~ComponentBase(){}; }; - } // end namespace elx #endif // #define ComponentBase_h \ No newline at end of file diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx index 0b8fac5c..87146c75 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.cxx @@ -20,26 +20,28 @@ int GDOptimizer3rdPartyComponent::ConnectFrom(const char * interfacename, Compon if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get(), interfacename) == 0) { InterfaceAcceptor<MetricValueInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricValueInterface>*> (this); - if (!acceptIF) + // static_cast always succeeds since we know via the template arguments of the component what InterfaceAcceptors are base classes. + // connect value interfaces + if (1 == acceptIF->Connect(other)) { - std::cout << InterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl; + return 1; //success, assume only one interface listens interfacename } - // connect value interfaces - acceptIF->Connect(other); - return 1; //success, assume only one interface listens interfacename - } - if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get(), interfacename) == 0) - { - InterfaceAcceptor<MetricDerivativeInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (this); - if (!acceptIF) + else { - std::cout << InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl; + if (std::strcmp(InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get(), interfacename) == 0) + { + InterfaceAcceptor<MetricDerivativeInterface>* acceptIF = static_cast<InterfaceAcceptor<MetricDerivativeInterface>*> (this); + if (!acceptIF) + { + std::cout << InterfaceName<InterfaceAcceptor<MetricDerivativeInterface>>::Get() << " optimizer has no OptimizerValueInterface" << std::endl; + } + // connect value interfaces + acceptIF->Connect(other); + return 1; //success, assume only one interface listens interfacename + } + return 0; } - // connect value interfaces - acceptIF->Connect(other); - return 1; //success, assume only one interface listens interfacename } - return 0; } int GDOptimizer3rdPartyComponent::Set(MetricValueInterface* component) diff --git a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h index 7addba7b..8a8cd819 100644 --- a/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h +++ b/Modules/Core/ComponentInterface/GDOptimizer3rdPartyComponent.h @@ -9,7 +9,13 @@ namespace elx { - class GDOptimizer3rdPartyComponent : public ComponentBase, public InterfaceAcceptor<MetricValueInterface>, public InterfaceAcceptor<MetricDerivativeInterface>, public OptimizerUpdateInterface + + class GDOptimizer3rdPartyComponent : + public Implements< + Accepting< MetricValueInterface, MetricDerivativeInterface >, + //Accepting< InterfaceAcceptor<MetricValueInterface>, InterfaceAcceptor<MetricDerivativeInterface> >, + Providing< OptimizerUpdateInterface> + > { public: GDOptimizer3rdPartyComponent(); diff --git a/Modules/Core/ComponentInterface/Interfaces.hxx b/Modules/Core/ComponentInterface/Interfaces.hxx index c74468bb..f5071a0b 100644 --- a/Modules/Core/ComponentInterface/Interfaces.hxx +++ b/Modules/Core/ComponentInterface/Interfaces.hxx @@ -38,7 +38,7 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ InterfaceT* providerInterface = dynamic_cast<InterfaceT*> (providerComponent); if (!providerInterface) { - std::cout << "providerComponent does not have required interface" << std::endl; + std::cout << "providerComponent does not have required " << InterfaceName < InterfaceT >::Get() << std::endl; return 0; } // connect value interfaces @@ -47,6 +47,71 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ } +//template<typename... Interfaces> +//class Accepting : public Interfaces... +//{ +//}; + +//template<> +//class Accepting<> +//{ +//}; + + +//template<typename FirstInterface> +//class Accepting : public InterfaceAcceptor < FirstInterface > +//{ +//}; + +template<typename ... RestInterfaces> +class Accepting +{ +}; + + +//template<typename FirstInterface, typename ... RestInterfaces> +//class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... > +//{ +//}; + +template<typename FirstInterface, typename ... RestInterfaces> +class Accepting<FirstInterface, RestInterfaces... > : public Accepting< RestInterfaces ... >, public InterfaceAcceptor<FirstInterface> +{ + //FirstInterface firstIF; +}; + + + +template<typename... Interfaces> +class Providing : public Interfaces... +{ +}; + +template<typename AcceptingInterfaces, typename ProvidingInterfaces> +class Implements : public ComponentBase, public AcceptingInterfaces, public ProvidingInterfaces +{ + typedef typename AcceptingInterfaces AcceptingInterfacesType; + typedef typename ProvidingInterfaces ProvidingInterfacesType; +}; + +/* +// + +template <typename First, typename ... Rest> +int ConnectFromBaseQueryInterface(GUID const & id) noexcept +{ + if (id == __uuidof(First) || id == __uuidof(::IUnknown)) + { + return static_cast<First *>(this); + } + if (IsInspectable<Interfaces ...>() && + id == __uuidof(::IInspectable)) + { + return FindInspectable<Interfaces ...>(); + } + return FindInterface<Rest ...>(id); +} +*/ // TEST template<class InterfaceT> class InterfaceProvider { diff --git a/Modules/Core/ComponentInterface/componenthandshake.cxx b/Modules/Core/ComponentInterface/componenthandshake.cxx index 930b2028..78149b0c 100644 --- a/Modules/Core/ComponentInterface/componenthandshake.cxx +++ b/Modules/Core/ComponentInterface/componenthandshake.cxx @@ -13,6 +13,8 @@ using namespace elx; int main() { { + tuple<double, long long, const char*> t1(12.2, 42, "big"); + std::cout << InterfaceName<MetricValueInterface>::Get() << std::endl; std::cout << AcceptorInterfaceName<InterfaceAcceptor<MetricValueInterface>>::Get() << std::endl; -- GitLab