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

ENH: reorganize Interface files for templated classes

parent 74ef1f2c
#ifndef InterfaceTraits_h
#define InterfaceTraits_h
#include "Interfaces.h"
namespace elx
{
// Traits to get printable interface name
// default implementation
template <typename T>
struct InterfaceName
{
static const char* Get()
{
return typeid(T).name();
}
};
// a specialization for each type of those you want to support
// and don't like the string returned by typeid
template <>
struct InterfaceName < MetricValueInterface >
{
static const char* Get()
{
return "MetricValueInterface";
}
};
template <>
struct InterfaceName < MetricDerivativeInterface >
{
static const char* Get()
{
return "MetricDerivativeInterface";
}
};
template <>
struct InterfaceName < OptimizerUpdateInterface >
{
static const char* Get()
{
return "OptimizerUpdateInterface";
}
};
// partial specialization of InterfaceName
template<template<typename> class TT, typename T1>
struct InterfaceName < TT<T1> > {
static const char* Get()
{
return InterfaceName<T1>::Get();
}
};
template <typename T>
struct AcceptorInterfaceName
{
static const char* Get()
{
return InterfaceName<T>::Get();
}
};
} // end namespace elx
#endif // #define InterfaceTraits_h
\ No newline at end of file
#ifndef Interfaces_h
#define Interfaces_h
#include "ComponentBase.h"
#include "InterfaceTraits.h"
#include <typeinfo>
namespace elx
{
// Define the providing interfaces abstractly
class MetricDerivativeInterface {
public:
virtual int GetDerivative() = 0;
};
class MetricValueInterface {
public:
virtual int GetValue() = 0;
};
class OptimizerUpdateInterface {
public:
virtual int Update() = 0;
};
// Define the accepting interfaces as templated by the providing interface
template<class InterfaceT>
class InterfaceAcceptor {
public:
// Set() is called by a succesfull Connect()
// The implementation of Set() must be provided by component developers.
virtual int Set(InterfaceT*) = 0;
// Connect tries to connect this accepting interface with all interfaces of the provider component.
int Connect(ComponentBase*);
private:
bool isSet;
};
template<typename ... RestInterfaces>
class Accepting
{
public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ;
int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ;
};
template<typename FirstInterface, typename ... RestInterfaces>
class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... >
{
public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
int ConnectFromImpl(ComponentBase*);
};
template<typename... Interfaces>
class Providing : public Interfaces...
{
};
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase
{
public:
virtual interfaceStatus ConnectFrom(const char *, ComponentBase*);
virtual int ConnectFrom(ComponentBase*);
};
} // end namespace elx
#ifndef ITK_MANUAL_INSTANTIATION
#include "Interfaces.hxx"
#endif
#endif // #define Interfaces_h
\ No newline at end of file
#ifndef Interfaces_hxx #ifndef Interfaces_hxx
#define Interfaces_hxx #define Interfaces_hxx
#include "ComponentBase.h" #include "InterfaceTraits.h"
#include <typeinfo>
namespace elx namespace elx
{ {
// Define the providing interfaces abstractly
class MetricDerivativeInterface {
public:
virtual int GetDerivative() = 0;
};
class MetricValueInterface {
public:
virtual int GetValue() = 0;
};
class OptimizerUpdateInterface {
public:
virtual int Update() = 0;
};
// Define the accepting interfaces as templated by the providing interface
template<class InterfaceT>
class InterfaceAcceptor {
public:
// Set() is called by a succesfull Connect()
// The implementation of Set() must be provided by component developers.
virtual int Set(InterfaceT*) = 0;
// Connect tries to connect this accepting interface with all interfaces of the provider component.
int Connect(ComponentBase*);
private:
bool isSet;
};
template<typename ... RestInterfaces>
class Accepting
{
public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*) { return interfaceStatus::noaccepter; }; //no interface called interfacename ;
int ConnectFromImpl(ComponentBase*) { return 0; }; //Empty RestInterfaces does 0 successful connects ;
};
template<typename FirstInterface, typename ... RestInterfaces>
class Accepting<FirstInterface, RestInterfaces... > : public InterfaceAcceptor<FirstInterface>, public Accepting< RestInterfaces ... >
{
public:
interfaceStatus ConnectFromImpl(const char *, ComponentBase*);
int ConnectFromImpl(ComponentBase*);
};
template<typename... Interfaces>
class Providing : public Interfaces...
{
};
template<typename AcceptingInterfaces, typename ProvidingInterfaces>
class Implements : public AcceptingInterfaces, public ProvidingInterfaces, public ComponentBase
{
public:
virtual interfaceStatus ConnectFrom(const char *, ComponentBase*);
virtual int ConnectFrom(ComponentBase*);
};
// TEST
template<class InterfaceT>
class InterfaceProvider {
public:
virtual int Set(InterfaceT*) {};
private:
};
// Traits to get printable interface name
// default implementation
template <typename T>
struct InterfaceName
{
static const char* Get()
{
return typeid(T).name();
}
};
// a specialization for each type of those you want to support
// and don't like the string returned by typeid
template <>
struct InterfaceName < MetricValueInterface >
{
static const char* Get()
{
return "MetricValueInterface";
}
};
template <>
struct InterfaceName < MetricDerivativeInterface >
{
static const char* Get()
{
return "MetricDerivativeInterface";
}
};
template <>
struct InterfaceName < OptimizerUpdateInterface >
{
static const char* Get()
{
return "OptimizerUpdateInterface";
}
};
// partial specialization of InterfaceName
template<template<typename> class TT, typename T1>
struct InterfaceName < TT<T1> > {
static const char* Get()
{
return InterfaceName<T1>::Get();
}
};
template <typename T>
struct AcceptorInterfaceName
{
static const char* Get()
{
return InterfaceName<T>::Get();
}
};
template<class InterfaceT> template<class InterfaceT>
int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
...@@ -150,12 +18,6 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){ ...@@ -150,12 +18,6 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
return 1; return 1;
} }
//template<template<typename... RestInterfacesT> class AcceptingT, typename ProvidingT>
//interfaceStatus Implements<AcceptingT<RestInterfacesT... >, ProvidingT>::ConnectFrom(const char * interfacename, ComponentBase* other)
//{
// :ConnectFrom(const char * interfacename, ComponentBase* other)
//}
template<typename AcceptingInterfaces, typename ProvidingInterfaces> template<typename AcceptingInterfaces, typename ProvidingInterfaces>
interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other) interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other)
{ {
...@@ -204,4 +66,6 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase ...@@ -204,4 +66,6 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase
} }
} // end namespace elx } // end namespace elx
#endif // #define Interfaces_hxx #endif // #define Interfaces_hxx
\ No newline at end of file
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