diff --git a/include/DoocsProcessArray.h b/include/DoocsProcessArray.h index ad07ab0debe706e902d5d71114005e6aca22504d..97d57a7814840bb2465d380aeedd3cadb3ff7bb3 100644 --- a/include/DoocsProcessArray.h +++ b/include/DoocsProcessArray.h @@ -122,14 +122,28 @@ namespace ChimeraTK { // DoocsUpdater auto& processVector = _processArray->accessChannel(0); - // We have to cast the pointer to the correct underlying DOOCS type. This - // cast never does anything, the only reason is to "convert" from int64_t to - // long long int (which are different types!) + // We have to cast the pointer to the correct underlying DOOCS type. No real conversion is done, since only + // equivalent types are casted here. typedef typename std::result_of<decltype (&DOOCS_T::value)(DOOCS_T, int)>::type THE_DOOCS_TYPE; - static_assert(std::is_same<THE_DOOCS_TYPE, DOOCS_PRIMITIVE_T>::value || - (std::is_same<DOOCS_PRIMITIVE_T, int64_t>::value && std::is_same<THE_DOOCS_TYPE, long long int>::value), - "Bad type casting."); - auto dataPtr = reinterpret_cast<THE_DOOCS_TYPE*>(processVector.data()); + THE_DOOCS_TYPE* dataPtr; + if constexpr(std::is_same<THE_DOOCS_TYPE, DOOCS_PRIMITIVE_T>::value) { + // No cast necessary if types are identical. + dataPtr = processVector.data(); + } + else if constexpr(std::is_same<DOOCS_PRIMITIVE_T, int64_t>::value && + std::is_same<THE_DOOCS_TYPE, long long int>::value) { + // Cast from int64_t to long long int (which are different types!) + dataPtr = reinterpret_cast<long long int*>(processVector.data()); + } + else if constexpr(std::is_same<DOOCS_PRIMITIVE_T, ChimeraTK::Boolean>::value && + std::is_same<THE_DOOCS_TYPE, bool>::value) { + // FIXME: Is it really ok to use reinterpret_cast here? + static_assert(sizeof(ChimeraTK::Boolean) == sizeof(bool)); + dataPtr = reinterpret_cast<bool*>(processVector.data()); + } + else { + static_assert(std::is_same<THE_DOOCS_TYPE, DOOCS_PRIMITIVE_T>::value, "Bad type casting."); + } if(_processArray->dataValidity() != ChimeraTK::DataValidity::ok) { this->d_error(stale_data); diff --git a/include/PropertyDescription.h b/include/PropertyDescription.h index b10790a6e8f912d197cb2a88cafb9b61485ac0b2..ddc07f20de9faaf8336b4fbfebe076319190ee9d 100644 --- a/include/PropertyDescription.h +++ b/include/PropertyDescription.h @@ -85,7 +85,7 @@ namespace ChimeraTK { // Combines property attributes and the base description // FIXME: should sort by name to put it into a set? struct AutoPropertyDescription : public PropertyDescription, public PropertyAttributes { - enum class DataType { Byte, Short, Int, Long, Float, Double, Auto }; + enum class DataType { Byte, Short, Int, Long, Float, Double, Bool, Void, Auto }; ChimeraTK::RegisterPath source; AutoPropertyDescription(ChimeraTK::RegisterPath const& source_ = "", std::string location_ = "", std::string name_ = "", DataType dataType_ = DataType::Auto, bool hasHistory_ = true, bool isWriteable_ = true) @@ -113,6 +113,8 @@ namespace ChimeraTK { if(info == typeid(uint64_t) || info == typeid(int64_t)) dataType = DataType::Long; if(info == typeid(float)) dataType = DataType::Float; if(info == typeid(double)) dataType = DataType::Double; + if(info == typeid(ChimeraTK::Boolean)) dataType = DataType::Bool; + if(info == typeid(ChimeraTK::Void)) dataType = DataType::Void; } DataType dataType; diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc index aec76e47a74fac61f48f5dfe4b1dabae86142847..89daaf101af99c2ac83321a256afef1eda3092b2 100644 --- a/src/DoocsPVFactory.cc +++ b/src/DoocsPVFactory.cc @@ -377,6 +377,13 @@ namespace ChimeraTK { case AutoPropertyDescription::DataType::Double: return typedCreateScalarOrArray<D_double, double, D_doublearray, double>( valueType, *processVariable, *autoPropertyDescription, DecoratorType::C_style_conversion); + case AutoPropertyDescription::DataType::Bool: + return typedCreateScalarOrArray<doocs::D_value<bool>, ChimeraTK::Boolean, doocs::D_array<int32_t>, int32_t>( + valueType, *processVariable, *autoPropertyDescription, DecoratorType::C_style_conversion); + case AutoPropertyDescription::DataType::Void: + // TODO: Map this to something more appropriate, e.g. D_fwd + return typedCreateScalarOrArray<D_int, int32_t, D_intarray, int32_t>( + valueType, *processVariable, *autoPropertyDescription, DecoratorType::C_style_conversion); case AutoPropertyDescription::DataType::Auto: if(valueType == typeid(std::string)) { return typedCreateScalarOrArray<D_textUnifier, std::string, std::nullptr_t, std::nullptr_t>( @@ -478,6 +485,9 @@ namespace ChimeraTK { else if(propertyDescription->dataType == AutoPropertyDescription::DataType::Double) { return typedCreateDoocsArray<double, D_doublearray>(*propertyDescription); } + else if(propertyDescription->dataType == AutoPropertyDescription::DataType::Bool) { + return typedCreateDoocsArray<int32_t, doocs::D_array<int32_t>>(*propertyDescription); + } else { throw std::logic_error("DoocsPVFactory does not implement a data type it should!"); } diff --git a/src/VariableMapper.cc b/src/VariableMapper.cc index b0c6d56f5666ad157aa6a5954a5ff5773e68678c..7121a57078cb865e04e97ebac29d19645a89aa96 100644 --- a/src/VariableMapper.cc +++ b/src/VariableMapper.cc @@ -212,7 +212,7 @@ namespace ChimeraTK { {{"auto", AutoPropertyDescription::DataType::Auto}, {"byte", AutoPropertyDescription::DataType::Byte}, {"short", AutoPropertyDescription::DataType::Short}, {"int", AutoPropertyDescription::DataType::Int}, {"long", AutoPropertyDescription::DataType::Long}, {"float", AutoPropertyDescription::DataType::Float}, - {"double", AutoPropertyDescription::DataType::Double}}); + {"double", AutoPropertyDescription::DataType::Double}, {"bool", AutoPropertyDescription::DataType::Bool}}); auto type = AutoPropertyDescription::DataType::Auto;