Commit d57de45a authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH: Accepting/Providing interfaces via variadic templates

parent 7e6b33d4
......@@ -9,6 +9,5 @@ namespace elx
protected:
virtual ~ComponentBase(){};
};
} // end namespace elx
#endif // #define ComponentBase_h
\ No newline at end of file
......@@ -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)
......
......@@ -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();
......
......@@ -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 {
......
......@@ -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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment