From 7968590fb8ac30a93be3bfb1b7d3424c7a3f6c77 Mon Sep 17 00:00:00 2001
From: Martin Killenberg <martin.killenberg@desy.de>
Date: Tue, 5 Sep 2017 10:20:51 +0200
Subject: [PATCH] simplified DoocsProcessScalar by getting rid of the
 DOOCS_VALUE_TYPE template parameter

---
 include/DoocsPVFactory.h             |  6 +++---
 include/DoocsProcessScalar.h         | 10 +++-------
 src/DoocsPVFactory.cc                | 30 ++++++++++++++--------------
 tests/src/testDoocsPVFactory.cpp     | 30 ++++++++++++++--------------
 tests/src/testDoocsProcessScalar.cpp | 12 +++++------
 5 files changed, 42 insertions(+), 46 deletions(-)

diff --git a/include/DoocsPVFactory.h b/include/DoocsPVFactory.h
index 2fa9652..1b42422 100644
--- a/include/DoocsPVFactory.h
+++ b/include/DoocsPVFactory.h
@@ -31,8 +31,8 @@ namespace ChimeraTK {
     boost::shared_ptr<ControlSystemSynchronizationUtility> _syncUtility; //< The syncUtility is needed to register listeners
     boost::shared_ptr<ControlSystemPVManager> _controlSystemPVManager; //< The pv manager, needed to get the instances @todo Do we need it in a proper design?
 
-    // create the DOOCS property. Note: DOOCS_T and DOOCS_VALUE_T are only used for scalar properties, not for arrays!
-    template<class T, class DOOCS_T, class DOOCS_VALUE_T>
+    // create the DOOCS property. Note: DOOCS_T is only used for scalar properties, not for arrays!
+    template<class T, class DOOCS_T>
     typename boost::shared_ptr<D_fct> createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable);
  
   };
@@ -40,7 +40,7 @@ namespace ChimeraTK {
 
   // specialisation for strings
   template<>
-  typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string, std::string>(typename ProcessVariable::SharedPtr & processVariable);
+  typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string>(typename ProcessVariable::SharedPtr & processVariable);
   
   
 }//namespace ChimeraTK
diff --git a/include/DoocsProcessScalar.h b/include/DoocsProcessScalar.h
index e961051..8579f59 100644
--- a/include/DoocsProcessScalar.h
+++ b/include/DoocsProcessScalar.h
@@ -16,12 +16,8 @@ namespace ChimeraTK {
   /** The DoocsProcessScalar has three template parameters:
   *  \li \c T, The primitive value type of the ChimeraTK process variable
   *  \li \c DOOCS_T, The Doocs type which is used
-  *  \li \c DOOCS_VALUE_T, The primitive type of the Doocs type, which is not necessarily the same as T
-  * 
-  *  The last type is necessary for the set_value overloading to work. If for instance T is short, then
-  *  D_int is used and the signature is set_value(int), not set_value(short).
   */
-  template <typename T, typename DOOCS_T, typename DOOCS_VALUE_T>
+  template <typename T, typename DOOCS_T>
   class DoocsProcessScalar :  public DOOCS_T {
 
     protected:
@@ -67,8 +63,8 @@ namespace ChimeraTK {
     private:
 
       // This class is neither assignable nor copy-constructible
-      DoocsProcessScalar< T, DOOCS_T, DOOCS_VALUE_T > & operator= (DoocsProcessScalar< T, DOOCS_T, DOOCS_VALUE_T> const &other);
-      DoocsProcessScalar(DoocsProcessScalar< T, DOOCS_T, DOOCS_VALUE_T> const &other);
+      DoocsProcessScalar< T, DOOCS_T> & operator= (DoocsProcessScalar< T, DOOCS_T> const &other);
+      DoocsProcessScalar(DoocsProcessScalar< T, DOOCS_T> const &other);
       
     public:
 
diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc
index 8087320..847cee6 100644
--- a/src/DoocsPVFactory.cc
+++ b/src/DoocsPVFactory.cc
@@ -17,7 +17,7 @@ namespace ChimeraTK {
       assert(eqFct != nullptr);
   }
 
-  template<class T, class DOOCS_T, class DOOCS_VALUE_T>
+  template<class T, class DOOCS_T>
   typename boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable) {
     // the DoocsProcessArray needs the real ProcessScalar type, not just ProcessVariable
     typename ProcessArray<T>::SharedPtr processArray
@@ -41,15 +41,15 @@ namespace ChimeraTK {
       // The DOOCS property name is the variable name without the location name and the separating slash between location and property name.
       if(propertyDescription->name.length() > 64) {
         std::cerr << "WARNING: Disabling history for " << processArray->getName() << ". Name is too long." << std::endl;
-        doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T, DOOCS_VALUE_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
+        doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
       }
       else{
         if (autoPropertyDescription && autoPropertyDescription->hasHistory){
           // version with history: EqFtc first
-          doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T, DOOCS_VALUE_T>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
+          doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
         }else{
           // version without history: name first
-          doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T, DOOCS_VALUE_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
+          doocsPV.reset( new DoocsProcessScalar<T, DOOCS_T>(propertyDescription->name.c_str(), _eqFct, processArray, *_syncUtility) );
         }
       }// if name too long
     }// if scalar
@@ -68,7 +68,7 @@ namespace ChimeraTK {
   }
 
   template<>
-  boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string, std::string>(
+  boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsProperty<std::string, D_string>(
             boost::shared_ptr<ProcessVariable> & processVariable) {
     // the DoocsProcessArray needs the real ProcessScalar type, not just ProcessVariable
     boost::shared_ptr<ProcessArray<std::string>> processArray
@@ -82,7 +82,7 @@ namespace ChimeraTK {
 
     assert(processArray->getNumberOfChannels() == 1);
     assert(processArray->getNumberOfSamples() == 1);    // array of strings is not supported
-    return boost::shared_ptr<D_fct>( new DoocsProcessScalar<std::string, D_string, std::string>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
+    return boost::shared_ptr<D_fct>( new DoocsProcessScalar<std::string, D_string>(_eqFct, propertyDescription->name.c_str(), processArray, *_syncUtility) );
   }
 
  boost::shared_ptr<D_fct> DoocsPVFactory::create( ProcessVariable::SharedPtr & processVariable ){
@@ -92,23 +92,23 @@ namespace ChimeraTK {
     // parameter. The value type in only known at run time,
     // but the template parameter has to be known at compile time.
     if (valueType == typeid(int8_t)) {
-      return createDoocsProperty<int8_t, D_int, int>(processVariable);
+      return createDoocsProperty<int8_t, D_int>(processVariable);
     } else if (valueType == typeid(uint8_t)) {
-      return createDoocsProperty<uint8_t, D_int, int>(processVariable);
+      return createDoocsProperty<uint8_t, D_int>(processVariable);
     } else if (valueType == typeid(int16_t)) {
-      return createDoocsProperty<int16_t, D_int, int>(processVariable);
+      return createDoocsProperty<int16_t, D_int>(processVariable);
     } else if (valueType == typeid(uint16_t)) {
-      return createDoocsProperty<uint16_t, D_int, int>(processVariable);
+      return createDoocsProperty<uint16_t, D_int>(processVariable);
     } else if (valueType == typeid(int32_t)) {
-      return createDoocsProperty<int32_t, D_int, int>(processVariable);
+      return createDoocsProperty<int32_t, D_int>(processVariable);
     } else if (valueType == typeid(uint32_t)) {
-      return createDoocsProperty<uint32_t, D_int, int>(processVariable);
+      return createDoocsProperty<uint32_t, D_int>(processVariable);
     } else if (valueType == typeid(float)) {
-      return createDoocsProperty<float, D_float, float>(processVariable);
+      return createDoocsProperty<float, D_float>(processVariable);
     } else if (valueType == typeid(double)) {
-      return createDoocsProperty<double, D_double, double>(processVariable);
+      return createDoocsProperty<double, D_double>(processVariable);
     } else if (valueType == typeid(std::string)) {
-      return createDoocsProperty<std::string, D_string, std::string>(processVariable);
+      return createDoocsProperty<std::string, D_string>(processVariable);
     } else {
       throw std::invalid_argument("unsupported value type");
     }
diff --git a/tests/src/testDoocsPVFactory.cpp b/tests/src/testDoocsPVFactory.cpp
index 3fceadf..147ec56 100644
--- a/tests/src/testDoocsPVFactory.cpp
+++ b/tests/src/testDoocsPVFactory.cpp
@@ -42,20 +42,20 @@ public:
     : DoocsPVFactory(eqFct, syncUtility, csPVManager){
   }
 
-  template<class T, class DOOCS_T, class DOOCS_VALUE_T>
+  template<class T, class DOOCS_T>
   typename boost::shared_ptr<D_fct> createDoocsProperty(typename ProcessVariable::SharedPtr & processVariable){
-    return DoocsPVFactory::createDoocsProperty<T, DOOCS_T, DOOCS_VALUE_T>(processVariable);
+    return DoocsPVFactory::createDoocsProperty<T, DOOCS_T>(processVariable);
   }
 };
 
-template<class T, class DOOCS_T, class DOOCS_VALUE_T>
+template<class T, class DOOCS_T>
 static void testCreateProcessScalar(typename ProcessVariable::SharedPtr processVariable,
 				    DoocsPVFactory & factory, std::string const & expectedPropertyName){
   // have the variable created and check that it is the right type
   boost::shared_ptr<D_fct> doocsVariableAsDFct = factory.create( processVariable );
   // get the raw pointer and dynamic cast it to the expected type
-  DoocsProcessScalar<T, DOOCS_T, DOOCS_VALUE_T> * doocsScalarType = 
-    dynamic_cast< DoocsProcessScalar<T, DOOCS_T, DOOCS_VALUE_T> * > (doocsVariableAsDFct.get());
+  DoocsProcessScalar<T, DOOCS_T> * doocsScalarType = 
+    dynamic_cast< DoocsProcessScalar<T, DOOCS_T> * > (doocsVariableAsDFct.get());
   // if the cast succeeds the factory works as expected we are done
   std::string errorMessage = std::string("testCreateProcessScalar failed for type ") + typeid(T).name();
   BOOST_CHECK_MESSAGE(doocsScalarType, errorMessage);
@@ -92,35 +92,35 @@ BOOST_AUTO_TEST_CASE( testCreateScalars ) {
 
   // We insert check points with integers so we know where the algorithm kicks out in case of an error.
   // These checkpoints are always true.
-  testCreateProcessScalar<int32_t, D_int, int>(
+  testCreateProcessScalar<int32_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<int32_t>("I/int32")),
     factory, "int32 ");// DOOCS property names always have a space (and potentially some description)"
   BOOST_CHECK(-32);
-  testCreateProcessScalar<uint32_t, D_int, int>(
+  testCreateProcessScalar<uint32_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<uint32_t>("U/uint32")),
     factory, "uint32 ");
   BOOST_CHECK(32);
-  testCreateProcessScalar<int16_t, D_int, int>(
+  testCreateProcessScalar<int16_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<int16_t>("I/int16")),
     factory, "int16 ");
   BOOST_CHECK(-16);
-  testCreateProcessScalar<uint16_t, D_int, int>(
+  testCreateProcessScalar<uint16_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<uint16_t>("U/uint16")),
     factory, "uint16 ");
   BOOST_CHECK(16);
-  testCreateProcessScalar<int8_t, D_int, int>(
+  testCreateProcessScalar<int8_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<int8_t>("I/int8")),
     factory, "int8 ");
   BOOST_CHECK(-8);
-  testCreateProcessScalar<uint8_t, D_int, int>(
+  testCreateProcessScalar<uint8_t, D_int>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<uint8_t>("U/uint8")),
     factory, "uint8 ");
   BOOST_CHECK(8);
-  testCreateProcessScalar<float, D_float, float>(
+  testCreateProcessScalar<float, D_float>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<float>("FP/float")),
     factory, "float ");
   BOOST_CHECK(0.5);
-  testCreateProcessScalar<double, D_double, double>(
+  testCreateProcessScalar<double, D_double>(
     boost::dynamic_pointer_cast<ProcessVariable>(csManager->getProcessArray<double>("FP/double")),
     factory, "double ");
   
@@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE( testErrorHandling ){
   // Unfortunately BOOST_CHECK cannot deal with multiple template parameters,
   // so we have to trick it
   try{
-    testableFactory.createDoocsProperty<int32_t, D_int, int>( processScalar );
+    testableFactory.createDoocsProperty<int32_t, D_int>( processScalar );
     // In a working unit test this line should not be hit, so er exclude it
     // from the coverage report.
     BOOST_FAIL( "createDoocsScalar did not throw as expected");//LCOV_EXCL_LINE
@@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE( testErrorHandling ){
 
   // now the same with arrays
   ProcessVariable::SharedPtr processArray = csManager->getProcessArray<int64_t>("A/toDeviceArray");
-  BOOST_CHECK_THROW( ( testableFactory.createDoocsProperty<int32_t, D_int, int>(processArray) ),
+  BOOST_CHECK_THROW( ( testableFactory.createDoocsProperty<int32_t, D_int>(processArray) ),
 		      std::invalid_argument );
 
    // finally we check that the create method catches the not-supported type.
diff --git a/tests/src/testDoocsProcessScalar.cpp b/tests/src/testDoocsProcessScalar.cpp
index 4aa4b87..1afe6f5 100644
--- a/tests/src/testDoocsProcessScalar.cpp
+++ b/tests/src/testDoocsProcessScalar.cpp
@@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( toDeviceIntegerTypeTest, T, integer_test_types ){
   controlSystemVariable->accessData(0)=0;
 
   // just write to the doocs scalar, it is automatically sending
-  DoocsProcessScalar<T, D_int, int> doocsScalar( NULL, "TO_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
+  DoocsProcessScalar<T, D_int> doocsScalar( NULL, "TO_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
 
   BOOST_CHECK(set_doocs_value(doocsScalar,42) == 0);
   BOOST_CHECK( controlSystemVariable->accessData(0) == 42 );
@@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(toDeviceFloatTest){
   controlSystemFloat->accessData(0)=0;
 
   // just write to the doocs scalar, it is automatically sending
-  DoocsProcessScalar<float, D_float, float> doocsScalar( NULL, "TO_DEVICE_FLOAT", controlSystemFloat, syncUtil );
+  DoocsProcessScalar<float, D_float> doocsScalar( NULL, "TO_DEVICE_FLOAT", controlSystemFloat, syncUtil );
 
   BOOST_CHECK(set_doocs_value(doocsScalar,12.125) == 0);
   BOOST_CHECK( controlSystemFloat->accessData(0) == 12.125 );
@@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(toDeviceDoubleTest){
   controlSystemDouble->accessData(0)=0;
 
   // just write to the doocs scalar, it is automatically sending
-  DoocsProcessScalar<double, D_double, double> doocsScalar( NULL, "TO_DEVICE_DOUBLE", controlSystemDouble, syncUtil );
+  DoocsProcessScalar<double, D_double> doocsScalar( NULL, "TO_DEVICE_DOUBLE", controlSystemDouble, syncUtil );
 
   BOOST_CHECK(set_doocs_value(doocsScalar,12.125) == 0);
   BOOST_CHECK( controlSystemDouble->accessData(0) == 12.125 );
@@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( fromDeviceIntegerTypeTest, T, integer_test_types
   controlSystemVariable->accessData(0)=0;
 
   // initialise the doocs scalar
-  DoocsProcessScalar<T, D_int, int> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
+  DoocsProcessScalar<T, D_int> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
   BOOST_CHECK(set_doocs_value(doocsScalar,0) == 0);
 
   deviceVariable->accessData(0)=42;
@@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE( fromDeviceFloatTest ){
   controlSystemVariable->accessData(0)=0;
 
   // initialise the doocs scalar
-  DoocsProcessScalar<float, D_float, float> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
+  DoocsProcessScalar<float, D_float> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
   BOOST_CHECK(set_doocs_value(doocsScalar,0) == 0);
 
   deviceVariable->accessData(0)=12.125;
@@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE( fromDeviceDoubleTest ){
   controlSystemVariable->accessData(0)=0;
 
   // initialise the doocs scalar
-  DoocsProcessScalar<double, D_double, double> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
+  DoocsProcessScalar<double, D_double> doocsScalar( NULL, "FROM_DEVICE_VARIABLE", controlSystemVariable, syncUtil );
   BOOST_CHECK(set_doocs_value(doocsScalar,0) == 0);
 
   deviceVariable->accessData(0)=12.125;
-- 
GitLab