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