From a961c0424e21bdfc103830b2fe6e7b6593c8d69d Mon Sep 17 00:00:00 2001
From: Floris Berendsen <floris.berendsen@gmail.com>
Date: Wed, 18 Nov 2015 14:17:52 +0100
Subject: [PATCH] ENH: reorganize Interface files for templated classes

---
 .../include/InterfaceTraits.h                 |  69 +++++++++
 .../ComponentInterface/include/Interfaces.h   |  78 ++++++++++
 .../ComponentInterface/include/Interfaces.hxx | 142 +-----------------
 3 files changed, 150 insertions(+), 139 deletions(-)
 create mode 100644 Modules/Core/ComponentInterface/include/InterfaceTraits.h
 create mode 100644 Modules/Core/ComponentInterface/include/Interfaces.h

diff --git a/Modules/Core/ComponentInterface/include/InterfaceTraits.h b/Modules/Core/ComponentInterface/include/InterfaceTraits.h
new file mode 100644
index 00000000..5dd03ec3
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/InterfaceTraits.h
@@ -0,0 +1,69 @@
+#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
diff --git a/Modules/Core/ComponentInterface/include/Interfaces.h b/Modules/Core/ComponentInterface/include/Interfaces.h
new file mode 100644
index 00000000..281d763d
--- /dev/null
+++ b/Modules/Core/ComponentInterface/include/Interfaces.h
@@ -0,0 +1,78 @@
+#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
diff --git a/Modules/Core/ComponentInterface/include/Interfaces.hxx b/Modules/Core/ComponentInterface/include/Interfaces.hxx
index 7b309ca0..cade1ce1 100644
--- a/Modules/Core/ComponentInterface/include/Interfaces.hxx
+++ b/Modules/Core/ComponentInterface/include/Interfaces.hxx
@@ -1,141 +1,9 @@
 #ifndef Interfaces_hxx
 #define Interfaces_hxx
 
-#include "ComponentBase.h"
-#include <typeinfo>
-
+#include "InterfaceTraits.h"
 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>
 int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
 
@@ -150,12 +18,6 @@ int InterfaceAcceptor<InterfaceT>::Connect(ComponentBase* providerComponent){
   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>
 interfaceStatus Implements<AcceptingInterfaces, ProvidingInterfaces>::ConnectFrom(const char * interfacename, ComponentBase* other)
 {
@@ -204,4 +66,6 @@ int Accepting<FirstInterface, RestInterfaces... >::ConnectFromImpl(ComponentBase
 }
 
 } // end namespace elx
+
+
 #endif // #define Interfaces_hxx
\ No newline at end of file
-- 
GitLab