// ---------------------------------------------------------------------- // // ColumnT - implementation of the template class ColumnT // // // Note: the constructor of a columnT use the getColumnData_t() // function family to correctly set ColumnAttribs.type #include "HepTuple/Column.h" #include "HepTuple/ColumnT.h" #include "ColumnType.h" #include "HepTuple/HBookNameTag.h" #include USING( std::string ) ZM_BEGIN_NAMESPACE( zmht ) /* namespace zmht { */ // *************************** // // // // Constructors and copier // // // // *************************** // template ColumnT::ColumnT(Block* block, ColumnAttribs attrib) : Column(block,attrib), value(T()), valuesArray(0) { _attributes.type = getColumnData_t( T() ); } template ColumnT::ColumnT( Block* block, const string& tag) : Column( block, tag, getColumnData_t(T())), value(T()), valuesArray(0) { } template ColumnT::~ColumnT() { if (valuesArray!= NULL) { delete valuesArray; } } template Column* ColumnT::duplicate(Block* newBlock) { ColumnAttribs ca ( _attributes ); ca.variable = 0; ca.function = 0; ca.getMethod = 0; ca.destination = 0; ca.destFunction = 0; ca.setMethod = 0; return (new ColumnT(newBlock,ca)); } // *************************** // // // // check the type // // // // *************************** // //template //bool ColumnT::checkType(T) { // return true; //} //template //ColumnData_t ColumnT::Type() // *************************** // // // // set values // // // // *************************** // template bool ColumnT::setDefaultValue(T defVal) { return _attributes.setDefaultValue(defVal); } template bool ColumnT::setDesignatedVariable(T* variable) { _attributes.function = 0; _attributes.getMethod = 0; _attributes.variable = (void*) variable; return true; } template bool ColumnT::setDesignatedFunction(inputFunction function) { _attributes.variable = 0; _attributes.getMethod = 0; _attributes.function = (genericFunction)function; return true; } template bool ColumnT::setDesignatedMethod(ZMuseMethod* method) { _attributes.variable = 0; _attributes.function = 0; _attributes.getMethod = (void*) method; return true; } template bool ColumnT::setDestinationVariable(T* variable) { _attributes.destFunction = 0; _attributes.setMethod = 0; _attributes.destination = (void*) variable; return true; } template bool ColumnT::setDestinationFunction(outputFunction function) { _attributes.destination = 0; _attributes.setMethod = 0; _attributes.destFunction = (genericFunction)function; return true; } template bool ColumnT::setDestinationMethod(ZMsetMethod* method) { _attributes.destination = 0; _attributes.destFunction = 0; _attributes.setMethod = (void*) method; return true; } // *************************** // // // // Capture // // // // *************************** // template bool ColumnT::captureDesignatedValues() { if ( !captureCheck() ) { ZMthrow(ZMxHepAlreadyDone(string("Column ")+name()+ " has already been captured")); return false; } setIsCaptured(true); if ( _attributes.ndim == 0 ) { // Case of a single variable if( _attributes.isIndex && (_attributes.indexHi <= _attributes.indexLo)) ZMthrow(ZMxHepIllFormedItem(string("Index column ")+name()+ string(" has no span"))); if ( _attributes.variable != NULL ) { value = * ((T*) _attributes.variable); } else if ( _attributes.function != NULL) { value = (reinterpret_cast(_attributes.function) ) (); } else if ( _attributes.getMethod != NULL ) { value = ((ZMuseMethod*)(_attributes.getMethod))->evaluate(); } // If none of the two is true then the value is // kept. } else { // Case where the column actually contain an array! int sumDim = _attributes.sumDim(); if ( valuesArray == NULL ) { setToDefault(); } if ( _attributes.variable != NULL ) { memcpy(valuesArray,_attributes.variable,sizeof(T)*sumDim); } // here should go else if statement if we provide a way // to set array of column through methods/functions. } return true; } template < class T > static int forceInt( T newVal ) { return -1; } template < > int forceInt( Int4 newVal ) { return newVal; } template bool ColumnT::captureValue(T newVal) { if ( !captureCheck() ) { ZMthrow(ZMxHepAlreadyDone(string("Column ")+name()+ " has already been captured")); return false; } setIsCaptured(true); if ( _attributes.ndim == 0 ) { // Case of a single variable if( _attributes.isIndex && (_attributes.indexHi <= _attributes.indexLo)) { ZMthrow(ZMxHepIllFormedItem(string("Index column ")+name()+ string(" has no span"))); return false; } if( _attributes.isIndex ) { // Won't compile under OSF1! Replace with following line. JMM 15 Oct. 2001 // int indexVal = (int)newVal; int indexVal = forceInt( newVal ); if( indexVal < 0 ) { ZMthrow(ZMxHepTypeMismatch (string("Index column must be of type int: ") +_attributes.tag)); return false; } if( (indexVal > _attributes.indexHi || indexVal < _attributes.indexLo) ) { ZMthrow(ZMxHepOutOfRangeValue (string("Attempted capture with out-of-range value for index column: ") +_attributes.tag)); return false; } } value = newVal; return true; } else { // Case where the column actually contain an array! ZMthrow(ZMxHepImproperUse( "Can not use captureValue with an Array Column")); return false; } } template bool ColumnT::captureValues(const T newVal[],int indexVal) { if ( !captureCheck() ) { ZMthrow(ZMxHepAlreadyDone(string("Column ")+name()+ " has already been captured")); return false; } setIsCaptured(true); if ( _attributes.ndim == 0 ) { // Case of a single variable ZMthrow(ZMxHepImproperUse( "captureValues can only be used with an Array Column")); return false; } else { // Case where the column actually contain an array! if ( indexVal == 0 ) { indexVal = _attributes.sumDim(); } if ( valuesArray == NULL ) { setToDefault(); } memcpy(valuesArray,newVal,sizeof(T)*indexVal); return true; } } // *************************** // // // // reset default. // // // // *************************** // template void ColumnT::setToDefault() { if ( _attributes.ndim == 0 ) { // Case of a single variable if ( _attributes.defaultVal != NULL ) { value = * ((T*) _attributes.defaultVal); } else { value = 0; } } else { // Case where the column actually contain an array! int sumDim = _attributes.sumDim(); if ( valuesArray == NULL ) { valuesArray = new T[sumDim]; } if ( _attributes.defaultVal != NULL ) { for (int i=0; i void* ColumnT::getValueAddr() { if ( _attributes.ndim != 0 ) { if ( valuesArray == NULL ) { setToDefault(); } return valuesArray; } return &value; } // return the size of the base type of the column element template std::string::size_type ColumnT::sizeofSingleElem() const { return sizeof(T); } // return the size of the content of the column template std::string::size_type ColumnT::sizeofElem() const { if ( _attributes.ndim == 0 ) { return sizeof(T); } else { return _attributes.sumDim()* sizeof(T); } } // *************************** // // // // Memory copy functions // // // // *************************** // // this copy the content of the column at the location indicated by // addr and return (addr + sizeofElem()) template void* ColumnT::copyToMem(void* addr) { if ( _attributes.ndim == 0 ) { // *(T*)addr = value; // to avoid alignment errors memcpy(addr,&value,sizeof(T)); } else { if ( valuesArray == NULL ) { setToDefault(); } memcpy(addr,valuesArray,sizeof(T)*_attributes.sumDim()); } return ((char*)addr+sizeofElem()); } // this copy the content of the column FROM the location indicated by // addr and return (addr + sizeofElem()) template void* ColumnT::copyFromMem(const void* addr) { if ( _attributes.ndim == 0 ) { // *(T*)addr = value; // to avoid alignment errors memcpy(&value,addr,sizeof(T)); } else { if ( valuesArray == NULL ) { setToDefault(); } memcpy(valuesArray,addr,sizeof(T)*_attributes.sumDim()); } return (void*)((char*)addr+sizeofElem()); } template bool ColumnT::copyToMem(void* addr, const string& indices) { if ( _attributes.ndim == 0 ) { ZMthrow(ZMxHepImproperUse("Non-array column used as a array")); return false; } // Parse the string; we expect the indices string to be // a comma delimited list of indices. // the slowest varying indices is the last one. int offset = 0; int dimension = 0; int accumulateDim = 1; for (std::string::size_type i = 0; (i < indices.length()) && (dimension < _attributes.ndim); i++) { int loopStart = i; if ( !isdigit(indices[i]) ) { ZMthrow(ZMxHepBadFormat("Bad indices format in ColumnT::copyToMem")); return false; } while ( i < indices.length() && isdigit(indices[i]) ) { i++; }; int val = atoi(indices.substr(loopStart,i-loopStart).c_str()); if ( (val < 0) || (val >= _attributes.extents[dimension] )) { ZMthrow(ZMxHepOutOfRangeValue(string("for ")+name()+indices)); return false; } offset += val*accumulateDim; accumulateDim *= _attributes.extents[dimension]; dimension++; if ( i < indices.length() ) { if ( indices[i] != HBookNameTag::IndicesDelimiter[0] ) { ZMthrow(ZMxHepBadFormat("Bad indices format in ColumnT::copyToMem")); return false; } } } if ( dimension != _attributes.ndim ) { ZMthrow(ZMxHepBadFormat("Too many indices in format in ColumnT::copyToMem")); return false; } *(T*) addr = valuesArray[offset]; return true; } // ******************************************************************** // // // // Reading functions // // // // virtual bool read(void * addr); // // copy the value pointed to by addr to the designated variable // // function/method. WARNING This CAN NOT check if the value is of // // the proper type. The addr MUST point to an array of the proper size // // if the column is an array. // // // // ******************************************************************** // template bool ColumnT::read(const void* addr) { T* value_ptr = (T*)addr; if ( _attributes.ndim == 0 ) { // case of single value column if ( _attributes.destination != NULL ) { *(T*) _attributes.destination = *value_ptr; return true; } else if ( _attributes.destFunction != NULL ) { (reinterpret_cast( _attributes.destFunction )) ( *value_ptr ); return true; } else if ( _attributes.setMethod != NULL ) { ((ZMsetMethod*) _attributes.setMethod)->set(*value_ptr); return true; } } else { if ( _attributes.destination != NULL ) { memcpy(_attributes.destination,addr,sizeof(T)*_attributes.sumDim()); return true; } } return false; } // ******************************************************** // // // // virtual bool read(); // // copy the value of the column to the designated variable // // function/method. // // // // ******************************************************** // template bool ColumnT::read() { if ( _attributes.ndim == 0 ) { // case of single value column if ( _attributes.destination != NULL ) { *(T*) _attributes.destination = value; return true; } else if ( _attributes.destFunction != NULL ) { (reinterpret_cast( _attributes.destFunction )) ( value ); return true; } else if ( _attributes.setMethod != NULL ) { ((ZMsetMethod*) _attributes.setMethod)->set(value); return true; } } else { if ( _attributes.destination != NULL ) { memcpy(_attributes.destination,valuesArray,sizeof(T)*_attributes.sumDim()); return true; } } return false; } // *************************** // // // // Explicit instantiation // // // // *************************** // template class ColumnT; template class ColumnT; template class ColumnT; #ifdef Int8 template class ColumnT; #endif template class ColumnT; template class ColumnT; template class ColumnT; #ifdef Uint8 template class ColumnT; #endif template class ColumnT; template class ColumnT; #ifdef Float16 template class ColumnT; #endif template class ColumnT; template class ColumnT; ZM_END_NAMESPACE( zmht ) /* } // namespace zmht */