Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

NTuple.h

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiKernel/GaudiKernel/NTuple.h,v 1.1.1.1 2001/04/18 18:14:18 tlindner Exp $
00002 #ifndef GAUDIKERNEL_NTUPLE_H
00003 #define GAUDIKERNEL_NTUPLE_H
00004 
00005 // STL include files
00006 #include <string>
00007 #include <climits>
00008 #include <cfloat>
00009 
00010 // Framework include files
00011 #include "GaudiKernel/DataTypeInfo.h"
00012 #include "GaudiKernel/DataObject.h"
00013 #include "GaudiKernel/INTuple.h"
00014 
00015 // Forward declarations
00016 class IOpaqueAddress;
00017 class NTupleFile;
00018 class NTupleDirectory;
00019 template <class TYPE> class SmartDataPtr;
00020 
00021 // Definition of the CLIDs for this classes  
00022 static const CLID CLID_NTupleFile       = 40;
00023 static const CLID CLID_NTupleDirectory  = 41;
00024 static const CLID CLID_RowWiseTuple     = 42;
00025 static const CLID CLID_ColumnWiseTuple  = 43;
00026 
00027 
00028 
00035 namespace NTuple   {
00036   // local forward declarations
00037   template <class TYP> class Range;
00038   template <class TYP> class _Data;
00039   template <class TYP> class _Item;
00040   template <class TYP> class _Array;
00041   template <class TYP> class _Matrix;
00042   template <class TYP> class _Accessor;
00043   template <class TYP> class Item;
00044   template <class TYP> class Array;
00045   template <class TYP> class Matrix;
00046 
00048   template <class TYP> class Range  {
00050     /*const*/ TYP    m_lower;
00052     /*const*/ TYP    m_upper;
00053   public:
00055     Range(const TYP low, const TYP upper) : m_lower(low), m_upper(upper)   {
00056     }
00058     Range(const Range<TYP>& copy) : m_lower(copy.m_lower), m_upper(copy.m_upper) {
00059     }
00061     Range& operator=(const Range<TYP>& copy)    {
00062       m_lower = copy.m_lower;
00063       m_upper = copy.m_upper;
00064       return *this;
00065     }
00067     virtual ~Range()             {                               }
00069     const TYP lower()    const   { return m_lower;               }
00071     const TYP upper()    const   { return m_upper;               }
00073     const TYP distance() const   { return m_upper-m_lower;       }
00075     static const TYP min();
00077     static const TYP max();
00078   };
00079   template <> class Range<bool>  {
00080   public:
00082     Range(const bool /* low */ , const bool /* upper */ )    {
00083     }
00085     Range(const Range<bool>& /* copy */ )  {
00086     }
00088     virtual ~Range()              {                               }
00090     const bool lower()    const   { return false;                 }
00092     const bool upper()    const   { return true;                  }
00094     const bool distance() const   { return true;                  }
00096     static const bool min()       { return false;                 }
00098     static const bool max()       { return true;                  }
00099   };
00101   #define DECL_MINMAX(true_typ,minimum,maximum)                  \
00102   template <> inline const true_typ Range<true_typ>::min()     { \
00103     return minimum;                                              \
00104   }                                                              \
00105   template <> inline const true_typ Range<true_typ>::max()     { \
00106     return maximum;                                              \
00107   }
00108   template <> inline const float Range<float>::min()     { 
00109     return -FLT_MAX;                                              
00110   }
00111   template <> inline const float Range<float>::max()     { 
00112     return FLT_MAX;                                              
00113   }
00114   template <> inline const double Range<double>::min()     { 
00115     return -DBL_MAX;
00116   }
00117   template <> inline const double Range<double>::max()     { 
00118     return DBL_MAX;
00119   }
00120   template <> inline const unsigned char Range<unsigned char>::min()     { 
00121     return 0;                                              
00122   }
00123   template <> inline const unsigned char Range<unsigned char>::max()     { 
00124     return UCHAR_MAX;
00125   }
00126   template <> inline const char Range<char>::min()     { 
00127     return CHAR_MIN;
00128   }
00129   template <> inline const char Range<char>::max()     { 
00130     return CHAR_MAX;
00131   }
00132   template <> inline const unsigned short Range<unsigned short>::min()     { 
00133     return 0;                                              
00134   }
00135   template <> inline const unsigned short Range<unsigned short>::max()     { 
00136     return USHRT_MAX;                                              
00137   }
00138   template <> inline const short Range<short>::min()     { 
00139     return SHRT_MIN;                                              
00140   }
00141   template <> inline const short Range<short>::max()     { 
00142     return SHRT_MAX;                                              
00143   }
00144   template <> inline const unsigned int Range<unsigned int>::min()     { 
00145     return 0;                                              
00146   }
00147   template <> inline const unsigned int Range<unsigned int>::max()     { 
00148     return UINT_MAX;                                              
00149   }
00150   template <> inline const int Range<int>::min()     { 
00151     return INT_MIN;                                              
00152   }
00153   template <> inline const int Range<int>::max()     { 
00154     return USHRT_MAX;                                              
00155   }
00156   template <> inline const unsigned long Range<unsigned long>::min()     { 
00157     return 0;                                              
00158   }
00159   template <> inline const unsigned long Range<unsigned long>::max()     { 
00160     return ULONG_MAX;                                              
00161   }
00162   template <> inline const long Range<long>::min()     { 
00163     return LONG_MIN;            
00164   }
00165   template <> inline const long Range<long>::max()     { 
00166     return LONG_MAX;
00167   }
00168   template <> inline IOpaqueAddress* const Range<IOpaqueAddress* >::min()     {
00169     return (IOpaqueAddress*)0x0;
00170   }
00171   template <> inline IOpaqueAddress* const Range<IOpaqueAddress* >::max()     {
00172     return (IOpaqueAddress*)0xffffffff;
00173   }
00174   /*
00175   template <> inline SmartRef<DataObject> const Range<SmartRef<DataObject> >::min()     { 
00176     return (DataObject*)0x0;            
00177   }
00178   template <> inline SmartRef<DataObject> const Range<SmartRef<DataObject> >::max()     { 
00179     return (DataObject*)0xffffffff;
00180   }
00181   template <> inline SmartRef<ContainedObject> const Range<SmartRef<ContainedObject> >::min()     { 
00182     return (ContainedObject*)0x0;            
00183   }
00184   template <> inline SmartRef<ContainedObject> const Range<SmartRef<ContainedObject> >::max()     { 
00185     return (ContainedObject*)0xffffffff;
00186   }
00187   */
00188 
00191   template <class TYP> class _Data : virtual public INTupleItem  {
00192   protected:
00194     TYP* m_buffer;
00195   public:
00197     typedef Range<TYP>  ItemRange;
00199     virtual void setDefault(const TYP d)          = 0;
00201     virtual const ItemRange& range() const        = 0;
00202   };
00203 
00206   template <class TYP> class _Item : virtual public _Data<TYP>  {
00207   public:
00209     static _Item* create(INTuple* tup, const std::string& name, TYP min, TYP max, TYP def);
00211     void       set(const TYP& item) { *m_buffer = item;             }
00213     virtual const TYP get() const   { return *m_buffer;             }
00214   };
00215 
00218   template <class TYP> class _Array : virtual public _Data<TYP>  {
00219   public:
00221     static _Array* create(INTuple* tup, const std::string& name, const std::string& index, long len, TYP min, TYP max, TYP def);
00223     const TYP& data(long i)  const  { return *(m_buffer + i);        }
00225     TYP&       data(long i)         { return *(m_buffer + i);        }
00226   };
00227 
00230   template <class TYP> class _Matrix : virtual public _Data<TYP>    {
00231   protected:
00233     long  m_rows;
00234   public:
00236     static _Matrix* create(INTuple* tup, const std::string& name, const std::string& index, long ncol, long nrow, TYP min, TYP max, TYP def);
00238     TYP*       column(long i)       { return (m_buffer + i*m_rows);  }
00240     const TYP* column(long i) const { return (m_buffer + i*m_rows);  }
00241   };
00242 
00245   template <class TYP> class _Accessor  {
00246     friend class Tuple;
00247   protected:
00249     mutable TYP*  m_ptr;
00250   public:
00252     _Accessor() : m_ptr(0)           {                                }
00254     virtual ~_Accessor()             {                                }
00256     bool          operator !() const { return m_ptr != 0;             }
00258     operator const void*()     const { return m_ptr;                  }
00260     TYP*         operator->()        { return m_ptr;                  }
00262     const TYP*   operator->() const  { return m_ptr;                  }
00264     const Range<TYP>& range()  const { return m_ptr->range();         }
00265   };
00266 
00269   template <class TYP> class Item : virtual public _Accessor< _Item<TYP> > {
00270     typedef Item<TYP> _My;
00271   public:
00273     Item()                          {    }
00275     operator const TYP () const     { return m_ptr->get();             }
00276     // Arithmetic operators defined on NTuple column entries
00277     Item& operator ++ ()            { return *this += TYP(1);          }
00278     Item& operator ++ (int)         { return *this += TYP(1);          }
00279     Item& operator -- ()            { return *this -= TYP(1);          }
00280     Item& operator -- (int)         { return *this -= TYP(1);          }
00282     Item& operator=(const TYP data) { 
00283       m_ptr->set( data ); 
00284       return *this;
00285     }
00286     Item<TYP>& operator += (const TYP data)    {                       
00287       m_ptr->set ( m_ptr->get() + data );                     
00288       return *this;                                                     
00289     }
00290     Item<TYP>& operator -= (const TYP data)    {                       
00291       m_ptr->set ( m_ptr->get() - data );                     
00292       return *this;                                                     
00293     }
00294     Item<TYP>& operator *= (const TYP data)    {                       
00295       m_ptr->set ( m_ptr->get() * data );                     
00296       return *this;                                                     
00297     }
00298     Item<TYP>& operator /= (const TYP data)    {                       
00299       m_ptr->set ( m_ptr->get() / data );                     
00300       return *this;                                                     
00301     }
00302   };
00303 
00306   template <class TYP> class Array  : virtual public _Accessor < _Array<TYP> > {
00307   public:
00309     Array()                                  {    }
00311     template <class T>
00312     TYP&       operator[] (const T i)        { return m_ptr->data(i);  }
00314     template <class T>
00315     const TYP& operator[] (const T i) const  { return m_ptr->data(i);  }
00316   };
00317 
00320   template <class TYP> class Matrix : virtual public _Accessor< _Matrix<TYP> >  {
00321   public:
00323     Matrix()                                  {    }
00325     template <class T>
00326     TYP*       operator[] (const T i)         { return m_ptr->column(i); }
00328     template <class T>
00329     const TYP* operator[] (const T i)  const  { return m_ptr->column(i); }
00330   };
00331 
00338   class Tuple : public DataObject, virtual public INTuple  {
00339 
00340   protected:
00342     template <class TYPE> StatusCode i_item(const std::string& name, _Item<TYPE>*& result)  const   {
00343       try   {
00344         result = dynamic_cast< _Item<TYPE>* > (i_find(name));
00345       }
00346       catch (...)   {
00347         result = 0;
00348       }
00349       return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00350     }
00352     template <class TYPE> StatusCode i_item(const std::string& name, _Array<TYPE>*& result)  const   {
00353       try   {
00354         if ( clID() == CLID_ColumnWiseTuple )   {
00355           result = dynamic_cast< _Array<TYPE>* > (i_find(name));
00356         }
00357       }
00358       catch (...)   {
00359         result = 0;
00360       }
00361       return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00362     }
00364     template <class TYPE> StatusCode i_item(const std::string& name, _Matrix<TYPE>*& result)  const   {
00365       try   {
00366         if ( clID() == CLID_ColumnWiseTuple )   {
00367           result = dynamic_cast< _Matrix<TYPE>* > (i_find(name));
00368         }
00369       }
00370       catch (...)   {
00371         result = 0;
00372       }
00373       return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00374     }
00376     template <class TYPE>
00377     StatusCode i_addItem(const std::string& name, long, const std::string&, TYPE low, TYPE high, _Item<TYPE>*& result)   {
00378       if ( !i_find(name) )    {
00379         TYPE nil;
00380         nil = 0;
00381         return add( result = _Item<TYPE>::create(this, name, low, high, nil) );
00382       }
00383       return StatusCode::FAILURE;
00384     }
00386     template <class TYPE>
00387     StatusCode i_addItem(const std::string& name, long dim, const std::string& index, TYPE low, TYPE high, _Array<TYPE>*& result)   {
00388       if ( !i_find(name) && clID() == CLID_ColumnWiseTuple )    {
00389         return add( result = _Array<TYPE>::create(this, name, index, dim, low, high, TYPE(0)) );
00390       }
00391       return StatusCode::FAILURE;
00392     }
00394     template <class TYPE>
00395     StatusCode i_addItem(const std::string& name, long dim1, long dim2, const std::string& index, TYPE low, TYPE high, _Matrix<TYPE>*& result)   {
00396       if ( !i_find(name) && clID() == CLID_ColumnWiseTuple )    {
00397         return add( result = _Matrix<TYPE>::create(this, name, index, dim1, dim2, low, high, TYPE(0)) );
00398       }
00399       return StatusCode::FAILURE;
00400     }
00401   public:
00403     virtual ~Tuple()   {
00404     }
00406     template <class TYPE> StatusCode item(const std::string& name, Item<TYPE>& result)    {
00407       return i_item(name, result.m_ptr);
00408     }
00410     template <class TYPE> StatusCode item(const std::string& name, const Item<TYPE>& result)  const   {
00411       return i_item(name, result.m_ptr);
00412     }
00414     template <class TYPE> StatusCode item(const std::string& name, Array<TYPE>& result)    {
00415       return i_item(name, result.m_ptr);
00416     }
00418     template <class TYPE> StatusCode item(const std::string& name, const Array<TYPE>& result)  const   {
00419       return i_item(name, result.m_ptr);
00420     }
00422     template <class TYPE> StatusCode item(const std::string& name, Matrix<TYPE>& result)    {
00423       return i_item(name, result.m_ptr);
00424     }
00426     template <class TYPE> StatusCode item(const std::string& name, const Matrix<TYPE>& result)  const   {
00427       return i_item(name, result.m_ptr);
00428     }
00430     template <class TYPE> StatusCode addItem(const std::string& name, Item<TYPE>& result)   {
00431       return i_addItem(name, 1, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00432     }
00434     template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, Item<TYPE>& result, const RANGE low, const RANGE high)   {
00435       return i_addItem(name, 1, "", TYPE(low), TYPE(high), result.m_ptr);
00436     }
00438     template <class TYPE> StatusCode addItem(const std::string& name, long dim, Array<TYPE>& result)   {
00439       return i_addItem(name, dim, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00440     }
00442     template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, long dim, Array<TYPE>& result, const RANGE low, const RANGE high)   {
00443       return i_addItem(name, dim, "", TYPE(low), TYPE(high), result.m_ptr);
00444     }
00448     template <class TYPE, class INDEX, class RANGE> StatusCode addItem(const std::string& name,
00449       Item<INDEX>& index,Array<TYPE>& result, const RANGE low, const RANGE high)   {
00450       return i_addItem(name, index->range().distance(), index->name(), TYPE(low), TYPE(high), result.m_ptr);
00451     }
00453     template <class TYPE, class INDEX> StatusCode addItem(const std::string& name, Item<INDEX>& index, Array<TYPE>& result)   {
00454       return i_addItem(name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00455     }
00457     template <class TYPE> StatusCode addItem(const std::string& name, long dim, long rows, Matrix<TYPE>& result)   {
00458       return i_addItem(name, dim, rows, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00459     }
00461     template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, long dim, long rows, Matrix<TYPE>& result, const RANGE low, const RANGE high)   {
00462       return i_addItem(name, dim, rows, "", TYPE(low), TYPE(high), result.m_ptr);
00463     }
00465     template <class TYPE, class INDEX> StatusCode addItem(const std::string& name, Item<INDEX>& index, Matrix<TYPE>& result, long rows)   {
00466       return i_addItem(name, index->range().distance(), rows, index->name(), Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00467     }
00469     template <class TYPE, class INDEX, class RANGE> StatusCode addItem(const std::string& name, Item<INDEX>& index, Matrix<TYPE>& result, long rows, const RANGE low, const RANGE high)   {
00470       return i_addItem(name, index->range().distance(), rows, index->name(), TYPE(low), TYPE(high), result.m_ptr);
00471     }
00472   };
00473 
00476   class Directory : public DataObject    {
00477   public:
00479     Directory()   {
00480     }
00482     virtual ~Directory()   {
00483     }
00485     static const CLID& classID()    {
00486       return CLID_NTupleDirectory;
00487     }
00489     virtual const CLID& clID()    const   {
00490       return Directory::classID();
00491     }
00492   };
00493 
00496   class File : public Directory    {
00497   protected:
00499     std::string   m_name;
00501     std::string   m_logName;
00503     unsigned char m_type;
00505     bool          m_isOpen;
00506   public:
00507     File() : m_type(0), m_isOpen(false)   {
00508     }
00510     File(unsigned char type, const std::string name, const std::string& logName)
00511     : m_name(name), m_logName(logName), m_type(type), m_isOpen(false)  {
00512     }
00514     virtual ~File()   {
00515     }
00517     static const CLID& classID()    {
00518       return CLID_NTupleFile;
00519     }
00521     virtual const CLID& clID()    const   {
00522       return File::classID();
00523     }
00525     void setType(const unsigned char typ)   {
00526       m_type = typ;
00527     }
00529     const unsigned char type()      const {
00530       return m_type;
00531     }
00533     const std::string& name()    const   {
00534       return m_name;
00535     }
00537     void setName(const std::string& nam)    {
00538       m_name = nam;
00539     }
00541     const std::string& logicalName()    const   {
00542       return m_logName;
00543     }
00545     void setLogicalName( const std::string& l)  {
00546       m_logName = l;
00547     }
00549       void setOpen(bool flag)   {
00550       m_isOpen = flag;
00551     }
00553     bool isOpen()   const   {
00554       return m_isOpen;
00555     }
00556   };
00557 
00558   // inhibit certians types by defining specialized templates which do not allow for 
00559   // construction.
00560   template <> class Array <IOpaqueAddress*>       {private: Array(){}  public: virtual void dummy() = 0; };
00561   template <> class Matrix<IOpaqueAddress*>       {private: Matrix(){} public: virtual void dummy() = 0; };
00562   #ifndef ALLOW_ALL_TYPES
00563       template <> class Item<unsigned char>       {private: Item(){}   public: virtual void dummy() = 0; };
00564       template <> class Array <unsigned char>     {private: Array(){}  public: virtual void dummy() = 0; };
00565       template <> class Matrix<unsigned char>     {private: Matrix(){} public: virtual void dummy() = 0; };
00566       template <> class Item<char>                {private: Item(){}   public: virtual void dummy() = 0; };
00567       template <> class Array <char>              {private: Array(){}  public: virtual void dummy() = 0; };
00568       template <> class Matrix<char>              {private: Matrix(){} public: virtual void dummy() = 0; };
00569       template <> class Item<unsigned short>      {private: Item(){}   public: virtual void dummy() = 0; };
00570       template <> class Array <unsigned short>    {private: Array(){}  public: virtual void dummy() = 0; };
00571       template <> class Matrix<unsigned short>    {private: Matrix(){} public: virtual void dummy() = 0; };
00572       template <> class Item<short>               {private: Item(){}   public: virtual void dummy() = 0; };
00573       template <> class Array <short>             {private: Array(){}  public: virtual void dummy() = 0; };
00574       template <> class Matrix<short>             {private: Matrix(){} public: virtual void dummy() = 0; };
00575       template <> class Item<unsigned int>        {private: Item(){}   public: virtual void dummy() = 0; };
00576       template <> class Array <unsigned int>      {private: Array(){}  public: virtual void dummy() = 0; };
00577       template <> class Matrix<unsigned int>      {private: Matrix(){} public: virtual void dummy() = 0; };
00578       template <> class Item<int>                 {private: Item(){}   public: virtual void dummy() = 0; };
00579       template <> class Array <int>               {private: Array(){}  public: virtual void dummy() = 0; };
00580       template <> class Matrix<int>               {private: Matrix(){} public: virtual void dummy() = 0; };
00581     #else
00582       typedef Item<bool>              BoolItem;
00583       typedef Item<char>              CharItem;
00584       typedef Item<unsigned char>     UCharItem;
00585       typedef Item<short>             ShortItem;
00586       typedef Item<unsigned short>    UShortItem;
00587       typedef Item<long>              LongItem;
00588       typedef Item<unsigned long>     ULongItem;
00589       typedef Item<int>               IntItem;
00590       typedef Item<unsigned int>      UIntItem;
00591       typedef Item<float>             FloatItem;
00592       typedef Item<double>            DoubleItem;
00593       typedef Array<bool>             BoolArray;
00594       typedef Array<char>             CharArray;
00595       typedef Array<unsigned char>    UCharArray;
00596       typedef Array<short>            ShortArray;
00597       typedef Array<unsigned short>   UShortArray;
00598       typedef Array<long>             LongArray;
00599       typedef Array<unsigned long>    ULongArray;
00600       typedef Array<int>              IntArray;
00601       typedef Array<unsigned int>     UIntArray;
00602       typedef Array<float>            FloatArray;
00603       typedef Array<double>           DoubleArray;
00604       typedef Matrix<bool>            BoolMatrix;
00605       typedef Matrix<char>            CharMatrix;
00606       typedef Matrix<unsigned char>   UCharMatrix;
00607       typedef Matrix<short>           ShortMatrix;
00608       typedef Matrix<unsigned short>  UShortMatrix;
00609       typedef Matrix<long>            LongMatrix;
00610       typedef Matrix<unsigned long>   ULongMatrix;
00611       typedef Matrix<int>             IntMatrix;
00612       typedef Matrix<unsigned int>    UIntMatrix;
00613       typedef Matrix<float>           FloatMatrix;
00614       typedef Matrix<double>          DoubleMatrix;
00615   #endif
00616 #undef DECL_MINMAX
00617 };
00618 
00619 // Useful:
00620 typedef SmartDataPtr<NTuple::Tuple>     NTuplePtr;
00621 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
00622 typedef SmartDataPtr<NTuple::File>      NTupleFilePtr;
00623 
00624 #include "GaudiKernel/MsgStream.h"
00625 template <class T>
00626 MsgStream& operator<<(MsgStream& s, const NTuple::Item<T>& obj)   {
00627   return s << T(obj);
00628 }
00629 
00630 template <class T>
00631 std::ostream& operator<<(std::ostream& s, const NTuple::Item<T>& obj)   {
00632   return s << T(obj);
00633 }
00634 
00635 #endif // GAUDIKERNEL_NTUPLE_H

Generated at Wed Nov 21 12:22:04 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000