00001
00002
00003
00004
00005
00006
00007 #include <cstdarg>
00008 #include <algorithm>
00009 #include <map>
00010
00011
00012
00013 #include "GaudiKernel/GaudiException.h"
00014
00015
00016
00017 #include "GaudiAlg/Tuples.h"
00018 #include "GaudiAlg/TupleObj.h"
00019
00020
00021
00022 #include "boost/integer_traits.hpp"
00023 #include "boost/static_assert.hpp"
00024
00032
00033 namespace Tuples
00034 {
00035
00036 BOOST_STATIC_ASSERT( boost::integer_traits<int> :: is_specialized ) ;
00037 BOOST_STATIC_ASSERT( boost::integer_traits<short> :: is_specialized ) ;
00038 BOOST_STATIC_ASSERT( boost::integer_traits<unsigned short> :: is_specialized ) ;
00039 BOOST_STATIC_ASSERT( boost::integer_traits<char> :: is_specialized ) ;
00040 BOOST_STATIC_ASSERT( boost::integer_traits<unsigned char> :: is_specialized ) ;
00041 BOOST_STATIC_ASSERT( sizeof ( int ) <= sizeof ( long ) ) ;
00042 BOOST_STATIC_ASSERT( sizeof ( int ) <= sizeof ( unsigned long ) ) ;
00043 BOOST_STATIC_ASSERT( sizeof ( int ) <= sizeof ( unsigned int ) ) ;
00044 BOOST_STATIC_ASSERT( sizeof ( short ) <= sizeof ( int ) ) ;
00045 BOOST_STATIC_ASSERT( sizeof ( unsigned short ) <= sizeof ( int ) ) ;
00046 BOOST_STATIC_ASSERT( sizeof ( char ) <= sizeof ( int ) ) ;
00047 BOOST_STATIC_ASSERT( sizeof ( signed char ) <= sizeof ( int ) ) ;
00048 BOOST_STATIC_ASSERT( sizeof ( unsigned char ) <= sizeof ( int ) ) ;
00049 BOOST_STATIC_ASSERT( boost::integer_traits<int>::const_max <=
00050 boost::integer_traits<long>::const_max ) ;
00051 BOOST_STATIC_ASSERT( boost::integer_traits<int>::const_min >=
00052 boost::integer_traits<long>::const_min ) ;
00053 BOOST_STATIC_ASSERT( boost::integer_traits<short>::const_max <=
00054 boost::integer_traits<int>::const_max ) ;
00055 BOOST_STATIC_ASSERT( boost::integer_traits<short>::const_min >=
00056 boost::integer_traits<int>::const_min ) ;
00057 BOOST_STATIC_ASSERT( boost::integer_traits<unsigned short>::const_max <=
00058 (unsigned int) boost::integer_traits<int>::const_max ) ;
00059 BOOST_STATIC_ASSERT( boost::integer_traits<char>::const_max <=
00060 boost::integer_traits<int>::const_max ) ;
00061 BOOST_STATIC_ASSERT( boost::integer_traits<char>::const_min >=
00062 boost::integer_traits<int>::const_min ) ;
00063 BOOST_STATIC_ASSERT( boost::integer_traits<unsigned char>::const_max <=
00064 (unsigned int) boost::integer_traits<int>::const_max ) ;
00065 BOOST_STATIC_ASSERT( 31 == boost::integer_traits<int>::digits ) ;
00066 BOOST_STATIC_ASSERT( std::numeric_limits<float>::is_specialized ) ;
00067
00068 namespace Local
00069 {
00070 class Counter
00071 {
00072 public:
00073
00074 Counter ( const std::string& msg = " Misbalance ")
00075 : m_map ()
00076 , m_message ( msg )
00077 {};
00078
00079 ~Counter() { report() ; m_map.clear() ;}
00080
00081 long increment ( const std::string& object ) { return ++m_map[object] ; }
00082
00083 long decrement ( const std::string& object ) { return --m_map[object] ; }
00084
00085 long counts ( const std::string& object ) { return m_map[object] ; }
00086
00087 void report() const
00088 {
00089 for ( Map::const_iterator entry = m_map.begin() ;
00090 m_map.end() != entry ; ++entry )
00091 {
00092 if( 0 == entry->second ) { continue ; }
00093 std::cout << "Tuples::TupleObj WARNING " << m_message
00094 << "'" << entry->first << "' Counts = " << entry->second
00095 << std::endl ;
00096 }
00097 };
00098
00099 private:
00100 typedef std::map<std::string,long> Map;
00101 Map m_map ;
00102 std::string m_message ;
00103 };
00104
00110 static Counter s_InstanceCounter ( " Create/Destroy (mis)balance " ) ;
00111 }
00112 }
00113
00114
00115
00116 Tuples::TupleObj::TupleObj
00117 ( const std::string& name ,
00118 NTuple::Tuple* tuple ,
00119 const CLID& clid ,
00120 const Tuples::Type type )
00121
00122 : m_name ( name )
00123 , m_tuple ( tuple )
00124 , m_clid ( clid )
00125 , m_type ( type )
00126
00127 , m_refCount ( 0 )
00128
00129 , m_ints ()
00130 , m_floats ()
00131 , m_addresses ()
00132 , m_farrays ()
00133 , m_arraysf ()
00134 , m_fmatrices ()
00135 , m_matricesf ()
00136
00137 , m_items ()
00138 {
00139
00140 Tuples::Local::s_InstanceCounter.increment ( m_name ) ;
00141 }
00142
00143
00144
00145 Tuples::TupleObj::~TupleObj()
00146 {
00147 {
00148 for( Ints::iterator it = m_ints.begin() ;
00149 m_ints.end() != it ; ++it )
00150 { if( 0 != it->second ) { delete it->second ; } }
00151 m_ints.clear() ;
00152 }
00153 {
00154 for( Floats::iterator it = m_floats.begin() ;
00155 m_floats.end() != it ; ++it )
00156 { if( 0 != it->second ) { delete it->second ; } }
00157 m_floats.clear() ;
00158 }
00159 {
00160 for( FArrays::iterator it = m_farrays.begin() ;
00161 m_farrays.end() != it ; ++it )
00162 { if( 0 != it->second ) { delete it->second ; } }
00163 m_farrays.clear() ;
00164 }
00165 {
00166 for( FArrays::iterator it = m_arraysf.begin() ;
00167 m_arraysf.end() != it ; ++it )
00168 { if( 0 != it->second ) { delete it->second ; } }
00169 m_arraysf.clear() ;
00170 }
00171 {
00172 for( Addresses::iterator it = m_addresses.begin() ;
00173 m_addresses.end() != it ; ++it )
00174 { if( 0 != it->second ) { delete it->second ; } }
00175 m_addresses.clear();
00176 }
00177 {
00178 for( FMatrices::iterator it = m_fmatrices.begin() ;
00179 m_fmatrices.end() != it ; ++it )
00180 { if( 0 != it->second ) { delete it->second ; } }
00181 m_fmatrices.clear();
00182 }
00183 {
00184 for( FMatrices::iterator it = m_matricesf.begin() ;
00185 m_matricesf.end() != it ; ++it )
00186 { if( 0 != it->second ) { delete it->second ; } }
00187 m_matricesf.clear();
00188 }
00189
00190
00191 Tuples::Local::s_InstanceCounter.decrement ( m_name ) ;
00192 }
00193
00194
00195
00196
00197
00198 void Tuples::TupleObj::release ()
00199 {
00200
00201 if( 0 < refCount() ) { --m_refCount; }
00202
00203 if( 0 != refCount() ) { return; }
00204
00205 delete this ;
00206 }
00207
00208
00209
00210 StatusCode Tuples::TupleObj::write ()
00211 {
00212 if ( invalid() ) { return InvalidTuple ; }
00213 return tuple()->write() ;
00214 }
00215
00216 namespace
00217 {
00219 typedef std::vector<std::string> Tokens;
00224 size_t tokenize( const std::string& value ,
00225 Tokens& tokens ,
00226 const std::string& separators = " " )
00227 {
00228
00229 tokens.clear();
00230 if( value .empty () ) { return tokens.size () ; }
00231 std::string::const_iterator it1 = value.begin() ;
00232 std::string::const_iterator it2 = value.begin() ;
00233 while( value.end() != it1 && value.end() != it2 )
00234 {
00235 it2 = std::find_first_of( it1 ,
00236 value.end () ,
00237 separators.begin () ,
00238 separators.end () ) ;
00239 if( it2 != it1 )
00240 {
00241 std::string aux( value , it1 - value.begin() , it2 - it1 ) ;
00242 tokens.push_back( aux ) ;
00243 it1 = it2 ;
00244 }
00245 else { ++it1 ; }
00246
00247 }
00248 return tokens.size();
00249 };
00250 }
00251
00252 StatusCode Tuples::TupleObj::fill( const char* format ... )
00253 {
00254
00255 if ( invalid() ) { return InvalidTuple ; }
00256
00257 Tokens tokens ;
00258 tokenize( format , tokens , " ,;" );
00259 if ( tokens.empty() ) { return StatusCode::SUCCESS ; }
00261 va_list valist ;
00262 va_start( valist , format ) ;
00263
00264 StatusCode status = StatusCode::SUCCESS ;
00265 for( Tokens::const_iterator token = tokens.begin() ;
00266 tokens.end() != token && status.isSuccess() ; ++token )
00267 {
00268 const double val = va_arg( valist , double );
00269 status = column( *token , val );
00270 if( status.isFailure() )
00271 { Error ( " fill(): Can not add column '" + *token + "' " ) ; }
00272 }
00273
00274 va_end( valist );
00275
00276 return status ;
00277 }
00278
00279
00280
00281 StatusCode Tuples::TupleObj::column
00282 ( const std::string& name ,
00283 IOpaqueAddress* address )
00284 {
00285 if ( invalid () ) { return InvalidTuple ; }
00286 if ( !evtColType () ) { return InvalidOperation ; }
00287 if ( 0 == address )
00288 { return Error ( "column('" + name +
00289 "') IOpaqueAddress* is NULL!" , InvalidObject ) ; }
00290 Address* item = addresses( name );
00291 if ( 0 == item ) { return InvalidItem ; }
00292 *item = address ;
00293 return StatusCode::SUCCESS ;
00294 }
00295
00296
00297
00298 StatusCode Tuples::TupleObj::column
00299 ( IOpaqueAddress* address )
00300 {
00301 return column ("Address" , address ) ;
00302 }
00303
00304 Tuples::TupleObj::Float* Tuples::TupleObj::floats
00305 ( const std::string& name )
00306 {
00307 Floats::iterator found = m_floats.find( name ) ;
00308 if ( m_floats.end() != found ) { return found->second ; }
00309 Float* item = new Float() ;
00310 m_floats[ name ] = item ;
00311 const StatusCode sc = tuple()->addItem( name , *item );
00312 if ( sc.isFailure() )
00313 { Error ( " floats ('" + name + "'): item is not added", sc ) ; }
00314 if ( !addItem ( name , "F" ) )
00315 { Error ( " floats ('" + name + "'): item is not unique" ) ; }
00316 return item ;
00317 }
00318
00319 Tuples::TupleObj::Int* Tuples::TupleObj::ints
00320 ( const std::string& name )
00321 {
00322 Ints::iterator found = m_ints.find( name ) ;
00323 if( m_ints.end() != found ) { return found->second ; }
00324 Int* item = new Int() ;
00325 m_ints[ name ] = item ;
00326 StatusCode sc = tuple()->addItem( name , *item );
00327 if( sc.isFailure() )
00328 { Error ( " ints ('" + name + "'): item is not added", sc ) ; }
00329 if ( !addItem ( name , "L" ) )
00330 { Error ( " ints ('" + name + "'): item is not unique" ) ; }
00331 return item ;
00332 }
00333
00334 Tuples::TupleObj::Int* Tuples::TupleObj::ints
00335 ( const std::string& name ,
00336 const int minv ,
00337 const int maxv )
00338 {
00339 Ints::iterator found = m_ints.find( name ) ;
00340 if( m_ints.end() != found ) { return found->second ; }
00341 Int* item = new Int() ;
00342 m_ints[ name ] = item ;
00343 const StatusCode sc = tuple()->addItem( name , *item , minv , maxv );
00344 if( sc.isFailure() )
00345 { Error ( " ints ('" + name + "'): item is not added", sc ) ; }
00346 if ( !addItem ( name , "L" ) )
00347 { Error ( " ints ('" + name + "'): item is not unique" ) ; }
00348 return item ;
00349 }
00350
00351 Tuples::TupleObj::Address* Tuples::TupleObj::addresses
00352 ( const std::string& name )
00353 {
00354 Addresses::iterator found = m_addresses.find( name ) ;
00355 if( m_addresses.end() != found ) { return found->second ; }
00356 Address* item = new Address() ;
00357 m_addresses[ name ] = item ;
00358 const StatusCode sc = tuple()->addItem( name , *item );
00359 if( sc.isFailure() )
00360 { Error ( " addresses ('" + name + "'): item is not added", sc ) ; }
00361 if ( !addItem ( name , "IOpaqueAddress*" ) )
00362 { Error ( " addresses ('" + name + "'): item is not unique" ) ; }
00363 return item ;
00364 }
00365
00366
00367
00368 Tuples::TupleObj::FArray* Tuples::TupleObj::fArray
00369 ( const std::string& name ,
00370 Tuples::TupleObj::Int* length )
00371 {
00372
00373 FArrays::iterator found = m_farrays.find( name ) ;
00374 if( m_farrays.end() != found ) { return found->second ; }
00375
00376 FArray* array = new FArray () ;
00377 m_farrays[ name] = array ;
00378 const StatusCode sc = tuple() -> addIndexedItem( name , *length , *array) ;
00379 if( sc.isFailure() )
00380 { Error ( " farray ('" + name + "'): item is not added", sc ) ; }
00381 if ( !addItem ( name , "FArray" ) )
00382 { Error ( " farray ('" + name + "'): item is not unique" ) ; }
00383 return array ;
00384 }
00385
00386
00387
00388 Tuples::TupleObj::FArray* Tuples::TupleObj::fArray
00389 ( const std::string& name ,
00390 const Tuples::TupleObj::MIndex& rows )
00391 {
00392
00393 FArrays::iterator found = m_arraysf.find( name ) ;
00394 if( m_arraysf.end() != found ) { return found->second ; }
00395
00396 FArray* array = new FArray () ;
00397 m_arraysf[ name] = array ;
00398 const StatusCode sc = tuple() -> addItem ( name , rows , *array) ;
00399 if( sc.isFailure() )
00400 { Error ( " array ('" + name + "'): item is not added", sc ) ; }
00401 if ( !addItem ( name , "FArray" ) )
00402 { Error ( " array ('" + name + "'): item is not unique" ) ; }
00403 return array ;
00404 }
00405
00406
00407
00408 Tuples::TupleObj::FMatrix*
00409 Tuples::TupleObj::fMatrix
00410 ( const std::string& name ,
00411 Tuples::TupleObj::Int* length ,
00412 const Tuples::TupleObj::MIndex& cols )
00413 {
00414
00415 FMatrices::iterator found = m_fmatrices.find( name ) ;
00416 if( m_fmatrices.end() != found ) { return found->second ; }
00417
00418 FMatrix* matrix = new FMatrix () ;
00419 m_fmatrices[ name] = matrix ;
00420 const StatusCode sc =
00421 tuple() -> addIndexedItem( name , *length , cols , *matrix ) ;
00422 if( sc.isFailure() )
00423 { Error ( " fmatrix ('" + name + "'): item is not added", sc ) ; }
00424 if ( !addItem ( name , "FMatrix" ) )
00425 { Error ( " fmatrix ('" + name + "'): item is not unique" ) ; }
00426 return matrix ;
00427 }
00428
00429
00430
00431 Tuples::TupleObj::FMatrix*
00432 Tuples::TupleObj::fMatrix
00433 ( const std::string& name ,
00434 const Tuples::TupleObj::MIndex& rows ,
00435 const Tuples::TupleObj::MIndex& cols )
00436 {
00437
00438 FMatrices::iterator found = m_matricesf.find( name ) ;
00439 if( m_matricesf.end() != found ) { return found->second ; }
00440
00441 FMatrix* matrix = new FMatrix () ;
00442 m_matricesf[ name] = matrix ;
00443 const StatusCode sc =
00444 tuple() -> addItem( name , rows , cols , *matrix ) ;
00445 if( sc.isFailure() )
00446 { Error ( " matrix ('" + name + "'): item is not added", sc ) ; }
00447 if ( !addItem ( name , "FMatrix" ) )
00448 { Error ( " matrix ('" + name + "'): item is not unique" ) ; }
00449 return matrix ;
00450 }
00451
00452
00453