//---------------------------------------------------------------------------// #ifndef IMCDATATYPE #define IMCDATATYPE //---------------------------------------------------------------------------// namespace imc { // map datatype to machine's datatypes typedef unsigned char imc_Ubyte; typedef signed char imc_Sbyte; // typedef unsigned short imc_Ushort; typedef signed short imc_Sshort; // // e.g. ARM Cortex-A72 armv7l gcc version 10.2.0 (Ubuntu 10.2.0-13ubuntu1) // #ifdef __arm__ // typedef unsigned long int imc_Ulongint; // typedef signed long int imc_Slongint; // e.g. Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz x86_64 gcc version 10.2.0 (Ubuntu 10.2.0-13ubuntu1) // #ifdef i386 __i386 __i386__ typedef unsigned int imc_Ulongint; typedef signed int imc_Slongint; // typedef float imc_float; typedef double imc_double; // // TODO not all remaining types are supported yet // typedef ... > "imc Devices Transitional Recording" // typedf "Timestamp Ascii" typedef char16_t imc_digital; // typedef struct { unsigned char bytes[6]; } imc_sixbyte; class datatype { protected: imc_Ubyte ubyte_; // 0 imc_Sbyte sbyte_; // 1 imc_Ushort ushort_; // 2 imc_Sshort sshort_; // 3 imc_Ulongint ulint_; // 4 imc_Slongint slint_; // 5 imc_float sfloat_; // 6 imc_double sdouble_; // 7 imc_digital sdigital_; // 10 imc_sixbyte sixbyte_; // 13 short int dtidx_; // \in \{0,...,7,10,13\} public: datatype(): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0), ulint_(0), slint_(0), sfloat_(0.0), sdouble_(0.0), sdigital_(0), sixbyte_({0}), dtidx_(0) { }; // every supported datatype gets its own constructor datatype(imc_Ubyte num): ubyte_(num), dtidx_(0) {}; datatype(imc_Sbyte num): sbyte_(num), dtidx_(1) {}; datatype(imc_Ushort num): ushort_(num), dtidx_(2) {}; datatype(imc_Sshort num): sshort_(num), dtidx_(3) {}; datatype(imc_Ulongint num): ulint_(num), dtidx_(4) {}; datatype(imc_Slongint num): slint_(num), dtidx_(5) {}; datatype(imc_float num): sfloat_(num), dtidx_(6) {}; datatype(imc_double num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0), ulint_(0), slint_(0), sfloat_(0.0), sdouble_(num), sdigital_(0), sixbyte_({0}), dtidx_(7) {}; datatype(imc_digital num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0), ulint_(0), slint_(0), sfloat_(0.0), sdouble_(0.0), sdigital_(num), sixbyte_({0}), dtidx_(10) {}; datatype(imc_sixbyte num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0), ulint_(0), slint_(0), sfloat_(0.0), sdouble_(0.0), sdigital_(0), sixbyte_(num), dtidx_(13) {}; // identify type short int& dtype() { return dtidx_; } // copy constructor datatype(const datatype &num) { this->ubyte_ = num.ubyte_; this->sbyte_ = num.sbyte_; this->ushort_ = num.ushort_; this->sshort_ = num.sshort_; this->ulint_ = num.ulint_; this->slint_ = num.slint_; this->sfloat_ = num.sfloat_; this->sdouble_ = num.sdouble_; this->sdigital_ = num.sdigital_; this->sixbyte_ = num.sixbyte_; this->dtidx_ = num.dtidx_; } // overall assignment operator datatype& operator=(const datatype &num) { if ( this != &num ) { this->ubyte_ = num.ubyte_; this->sbyte_ = num.sbyte_; this->ushort_ = num.ushort_; this->sshort_ = num.sshort_; this->ulint_ = num.ulint_; this->slint_ = num.slint_; this->sfloat_ = num.sfloat_; this->sdouble_ = num.sdouble_; this->sdigital_ = num.sdigital_; this->sixbyte_ = num.sixbyte_; this->dtidx_ = num.dtidx_; } return *this; } // implement assignment operator for individual datatypes datatype& operator=(const imc_Ubyte &num) { this->ubyte_ = num; this->dtidx_ = 0; return *this; } datatype& operator=(const imc_Sbyte &num) { this->sbyte_ = num; this->dtidx_ = 1; return *this; } datatype& operator=(const imc_Ushort &num) { this->ushort_ = num; this->dtidx_ = 2; return *this; } datatype& operator=(const imc_Sshort &num) { this->sshort_ = num; this->dtidx_ = 3; return *this; } datatype& operator=(const imc_Ulongint &num) { this->ulint_ = num; this->dtidx_ = 4; return *this; } datatype& operator=(const imc_Slongint &num) { this->slint_ = num; this->dtidx_ = 5; return *this; } datatype& operator=(const imc_float &num) { this->sfloat_ = num; this->dtidx_ = 6; return *this; } datatype& operator=(const imc_double &num) { this->sdouble_ = num; this->dtidx_ = 7; return *this; } datatype& operator=(const imc_digital &num) { this->sdigital_ = num; this->dtidx_ = 10; return *this; } datatype& operator=(const imc_sixbyte &num) { this->sixbyte_ = num; this->dtidx_ = 13; return *this; } // obtain number as double double as_double() { double num = 0.0; if ( dtidx_ == 0 ) num = (double)ubyte_; else if ( dtidx_ == 1 ) num = (double)sbyte_; else if ( dtidx_ == 2 ) num = (double)ushort_; else if ( dtidx_ == 3 ) num = (double)sshort_; else if ( dtidx_ == 4 ) num = (double)ulint_; else if ( dtidx_ == 5 ) num = (double)slint_; else if ( dtidx_ == 6 ) num = (double)sfloat_; else if ( dtidx_ == 7 ) num = (double)sdouble_; else if ( dtidx_ == 10 ) num = static_cast(sdigital_); else if ( dtidx_ == 13 ) { unsigned long long value = 0; for (int i = 0; i < 6; ++i) { value |= static_cast(sixbyte_.bytes[i]) << (8 * i); } num = static_cast(value); } return num; } // define custom stream operator to print the correct type friend std::ostream& operator<<(std::ostream& out, const datatype& num) { if ( num.dtidx_ == 0 ) out<(num.sdigital_); else if ( num.dtidx_ == 13 ) { unsigned long long value = 0; for (int i = 0; i < 6; ++i) { value |= static_cast(num.sixbyte_.bytes[i]) << (8 * i); } out<(value); } return out; } }; } #endif //---------------------------------------------------------------------------//