00001
00002
00003 #ifndef GAUDIKERNEL_NTUPLE_H
00004 #define GAUDIKERNEL_NTUPLE_H
00005
00006
00007
00008 #include <string>
00009 #include <limits>
00010 #include <cfloat>
00011 #include <stdexcept>
00012
00013
00014
00015 #include "GaudiKernel/DataTypeInfo.h"
00016 #include "GaudiKernel/DataObject.h"
00017 #include "GaudiKernel/INTuple.h"
00018 #include "GaudiKernel/SmartDataPtr.h"
00019 #include "GaudiKernel/IOpaqueAddress.h"
00020
00021
00022
00023 class NTupleFile;
00024 class NTupleDirectory;
00025
00034 namespace NTuple
00035 {
00036
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>
00049 class Range {
00051 TYP m_lower;
00053 TYP m_upper;
00054 public:
00056 Range(const TYP low, const TYP upper) : m_lower(low), m_upper(upper) {
00057 }
00059 Range(const Range<TYP>& copy) : m_lower(copy.m_lower),
00060 m_upper(copy.m_upper) {
00061 }
00063 Range& operator=(const Range<TYP>& copy) {
00064 m_lower = copy.m_lower;
00065 m_upper = copy.m_upper;
00066 return *this;
00067 }
00069 virtual ~Range() { }
00071 TYP lower() const { return m_lower; }
00073 TYP upper() const { return m_upper; }
00075 TYP distance() const { return m_upper-m_lower; }
00077 static TYP min() { return std::numeric_limits<TYP>::min() ; }
00079 static TYP max() { return std::numeric_limits<TYP>::max() ; }
00080 };
00081
00082 template <> class Range<bool>
00083 {
00084 public:
00086 Range(const bool , const bool ) {}
00088 Range(const Range<bool>& ) {}
00090 virtual ~Range() { }
00092 bool lower() const { return false; }
00094 bool upper() const { return true; }
00096 bool distance() const { return true; }
00098 static bool min() { return false; }
00100 static bool max() { return true; }
00101 };
00102
00103 template <>
00104 inline IOpaqueAddress*
00105 Range<IOpaqueAddress* >::min() { return (IOpaqueAddress*)0x0 ; }
00106 template <>
00107 inline IOpaqueAddress*
00108 Range<IOpaqueAddress* >::max() { return (IOpaqueAddress*)0xffffffff ; }
00109
00112 template <class TYP> class GAUDI_API _Data : virtual public INTupleItem {
00113 protected:
00115 TYP* m_buffer;
00116 public:
00118 typedef Range<TYP> ItemRange;
00120 virtual void setDefault(const TYP d) = 0;
00122 virtual const ItemRange& range() const = 0;
00123 };
00124
00127 template <class TYP> class GAUDI_API _Item : virtual public _Data<TYP> {
00128 public:
00130 virtual ~_Item() {}
00132 static _Item* create(INTuple* tup,
00133 const std::string& name,
00134 const std::type_info& info,
00135 TYP min,
00136 TYP max,
00137 TYP def);
00139 template <class T>
00140 _Item<TYP>& operator=(const _Item<T>& copy) {
00141 *this->m_buffer = copy.get();
00142 return *this;
00143 }
00145 void set(const TYP& item) { *this->m_buffer = item; }
00147 virtual TYP get() const { return *this->m_buffer; }
00148 };
00149
00152 template <class TYP> class GAUDI_API _Array : virtual public _Data<TYP> {
00153 public:
00155 static _Array* create(INTuple* tup,
00156 const std::string& name,
00157 const std::type_info& info,
00158 const std::string& index,
00159 long len,
00160 TYP min,
00161 TYP max,
00162 TYP def);
00164 template <class T>
00165 _Array<TYP>& operator=(const _Array<T>& copy) {
00166 long len = this->length();
00167 if ( len == copy.length() ) {
00168 const T* source = (const T*)copy.buffer();
00169 for ( int i = 0; i < len; i++ ) {
00170 *(this->m_buffer + i) = *(source + i);
00171 }
00172 return *this;
00173 }
00174 throw std::out_of_range
00175 ("N-tuple matrix cannot be copied! The index range does not match!");
00176 return *this;
00177 }
00179 const TYP& data(long i) const { return *(this->m_buffer + i); }
00181 TYP& data(long i) { return *(this->m_buffer + i); }
00182 };
00183
00186 template <class TYP> class GAUDI_API _Matrix : virtual public _Data<TYP> {
00187 protected:
00189 long m_rows;
00190 public:
00192 static _Matrix* create(INTuple* tup,
00193 const std::string& name,
00194 const std::type_info& info,
00195 const std::string& index,
00196 long ncol,
00197 long nrow,
00198 TYP min,
00199 TYP max,
00200 TYP def);
00202 template <class T>
00203 _Matrix<TYP>& operator=(const _Matrix<T>& copy) {
00204 long len = this->length();
00205 if ( len == copy.length() ) {
00206 const T* source = (const T*)copy.buffer();
00207 for ( int i = 0; i < len; i++ ) {
00208 *(this->m_buffer + i) = *(source + i);
00209 }
00210 return *this;
00211 }
00212 throw std::out_of_range
00213 ("N-tuple matrix cannot be copied! The index range does not match!");
00214 return *this;
00215 }
00217 TYP* column(long i) { return (this->m_buffer + i*m_rows); }
00219 const TYP* column(long i) const { return (this->m_buffer + i*m_rows); }
00220 };
00221
00224 template <class TYP> class _Accessor {
00225 friend class Tuple;
00226 private:
00227 _Accessor<TYP>& operator=(const _Accessor<TYP>&) {
00228 return *this;
00229 }
00230 protected:
00232 mutable TYP* m_ptr;
00233 public:
00235 _Accessor() : m_ptr(0) { }
00237 virtual ~_Accessor() { }
00239 bool operator !() const { return m_ptr != 0; }
00241 operator const void*() const { return m_ptr; }
00243 TYP* operator->() { return m_ptr; }
00245 const TYP* operator->() const { return m_ptr; }
00247 const Range<TYP>& range() const { return m_ptr->range(); }
00248 };
00249
00252 template <class TYP> class Item : virtual public _Accessor< _Item<TYP> > {
00253 typedef Item<TYP> _My;
00254 public:
00256 Item() { }
00258 operator const TYP () const { return this->m_ptr->get(); }
00260 TYP operator*() { return this->m_ptr->get(); }
00262 const TYP operator*() const { return this->m_ptr->get(); }
00263
00264 Item& operator ++ () { return *this += TYP(1); }
00265 Item& operator ++ (int) { return *this += TYP(1); }
00266 Item& operator -- () { return *this -= TYP(1); }
00267 Item& operator -- (int) { return *this -= TYP(1); }
00269 Item& operator=(const TYP data) {
00270 this->m_ptr->set( data );
00271 return *this;
00272 }
00274 template<class T>
00275 Item& operator=(const Item<T>& data) {
00276 this->m_ptr->set( data->get() );
00277 return *this;
00278 }
00279 Item<TYP>& operator += (const TYP data) {
00280 this->m_ptr->set ( this->m_ptr->get() + data );
00281 return *this;
00282 }
00283 Item<TYP>& operator -= (const TYP data) {
00284 this->m_ptr->set ( this->m_ptr->get() - data );
00285 return *this;
00286 }
00287 Item<TYP>& operator *= (const TYP data) {
00288 this->m_ptr->set ( this->m_ptr->get() * data );
00289 return *this;
00290 }
00291 Item<TYP>& operator /= (const TYP data) {
00292 this->m_ptr->set ( this->m_ptr->get() / data );
00293 return *this;
00294 }
00295 };
00296
00299 template <> class Item<bool> : virtual public _Accessor< _Item<bool> > {
00300 typedef Item<bool> _My;
00301 public:
00303 Item() { }
00305 operator bool () const { return this->m_ptr->get(); }
00307 Item& operator=(const bool data) {
00308 this->m_ptr->set( data );
00309 return *this;
00310 }
00312 template<class T>
00313 Item& operator=(const Item<T>& data) {
00314 this->m_ptr->set( data->get() );
00315 return *this;
00316 }
00317 };
00318
00321 template <class TYP> class Array : virtual public _Accessor < _Array<TYP> > {
00322 public:
00324 Array() { }
00326 template <class T>
00327 Array& operator=(const Array<T>& copy) {
00328 *(this->m_ptr) = *(copy.operator->());
00329 return *this;
00330 }
00332 template <class T>
00333 TYP& operator[] (const T i) { return this->m_ptr->data(i); }
00335 template <class T>
00336 const TYP& operator[] (const T i) const { return this->m_ptr->data(i); }
00337 virtual ~Array() {}
00338 };
00339
00342 template <class TYP> class Matrix : virtual public _Accessor< _Matrix<TYP> > {
00343 public:
00345 Matrix() { }
00347 template <class T>
00348 Matrix& operator=(const Matrix<T>& copy) {
00349 *(this->m_ptr) = *(copy.operator->());
00350 return *this;
00351 }
00353 template <class T>
00354 TYP* operator[] (const T i) { return this->m_ptr->column(i); }
00356 template <class T>
00357 const TYP* operator[] (const T i) const { return this->m_ptr->column(i); }
00358 virtual ~Matrix() {}
00359 };
00360
00367 class Tuple : public DataObject, virtual public INTuple {
00368
00369 protected:
00371 template <class TYPE> StatusCode i_item(const std::string& name,
00372 _Item<TYPE>*& result) const {
00373 try {
00374 result = dynamic_cast< _Item<TYPE>* > (i_find(name));
00375 }
00376 catch (...) {
00377 result = 0;
00378 }
00379 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00380 }
00382 template <class TYPE> StatusCode i_item(const std::string& name,
00383 _Item<TYPE*>*& result) const {
00384 try {
00385 _Item<void*>* p = dynamic_cast< _Item<void*>* > (i_find(name));
00386 result = (_Item<TYPE*>*)p;
00387 }
00388 catch (...) {
00389 result = 0;
00390 }
00391 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00392 }
00394 StatusCode i_item(const std::string& name,
00395 _Item<IOpaqueAddress*>*& result) const {
00396 try {
00397 result = dynamic_cast< _Item<IOpaqueAddress*>* > (i_find(name));
00398 }
00399 catch (...) {
00400 result = 0;
00401 }
00402 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00403 }
00405 template <class TYPE> StatusCode i_item(const std::string& name,
00406 _Array<TYPE>*& result) const {
00407 try {
00408 if ( clID() == CLID_ColumnWiseTuple ) {
00409 result = dynamic_cast< _Array<TYPE>* > (i_find(name));
00410 }
00411 }
00412 catch (...) {
00413 result = 0;
00414 }
00415 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00416 }
00418 template <class TYPE> StatusCode i_item(const std::string& name,
00419 _Matrix<TYPE>*& result) const {
00420 try {
00421 if ( clID() == CLID_ColumnWiseTuple ) {
00422 result = dynamic_cast< _Matrix<TYPE>* > (i_find(name));
00423 }
00424 }
00425 catch (...) {
00426 result = 0;
00427 }
00428 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00429 }
00431 template <class TYPE>
00432 StatusCode i_addItem(const std::string& name,
00433 long,
00434 const std::string&,
00435 TYPE low,
00436 TYPE high,
00437 _Item<TYPE>*& result) {
00438 if ( !i_find(name) ) {
00439 TYPE nil;
00440 nil = 0;
00441 return add( result = _Item<TYPE>::create(this, name, typeid(TYPE), low, high, nil) );
00442 }
00443 return StatusCode::FAILURE;
00444 }
00446 template <class TYPE>
00447 StatusCode i_addItem(const std::string& name,
00448 long dim,
00449 const std::string& index,
00450 TYPE low,
00451 TYPE high,
00452 _Array<TYPE>*& result) {
00453 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00454 return add( result = _Array<TYPE>::create(this,
00455 name,
00456 typeid(TYPE),
00457 index,
00458 dim,
00459 low,
00460 high,
00461 TYPE(0)) );
00462 }
00463 return StatusCode::FAILURE;
00464 }
00466 template <class TYPE>
00467 StatusCode i_addItem(const std::string& name,
00468 long dim1,
00469 long dim2,
00470 const std::string& index,
00471 TYPE low,
00472 TYPE high,
00473 _Matrix<TYPE>*& result) {
00474 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00475 return add( result = _Matrix<TYPE>::create(this,
00476 name,
00477 typeid(TYPE),
00478 index,
00479 dim1,
00480 dim2,
00481 low,
00482 high,
00483 TYPE(0)) );
00484 }
00485 return StatusCode::FAILURE;
00486 }
00487 template <class TYPE> StatusCode
00488 i_addObject(const std::string& name,_Item<TYPE*>*& result,const std::type_info& ) {
00489 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00490 return add( result = (_Item<TYPE*>*)_Item<void*>::create(this, name, typeid(TYPE),0,0,0) );
00491 }
00492 return StatusCode::FAILURE;
00493 }
00494
00495 public:
00497 virtual ~Tuple() {
00498 }
00500 template <class TYPE> StatusCode item(const std::string& name,
00501 Item<TYPE>& result)
00502 {
00503 return i_item(name, result.m_ptr);
00504 }
00506 template <class TYPE> StatusCode item(const std::string& name,
00507 const Item<TYPE>& result) const
00508 {
00509 return i_item(name, result.m_ptr);
00510 }
00512 template <class TYPE> StatusCode
00513 item(const std::string& name, Array<TYPE>& result)
00514 {
00515 return i_item(name, result.m_ptr);
00516 }
00518 template <class TYPE> StatusCode item(const std::string& name,
00519 const Array<TYPE>& result) const
00520 {
00521 return i_item(name, result.m_ptr);
00522 }
00524 template <class TYPE> StatusCode item(const std::string& name,
00525 Matrix<TYPE>& result)
00526 {
00527 return i_item(name, result.m_ptr);
00528 }
00529
00531 template <class TYPE> StatusCode item( const std::string& name,
00532 const Matrix<TYPE>& result) const
00533 {
00534 return i_item(name, result.m_ptr);
00535 }
00536
00550 template <class TYPE> StatusCode
00551 addItem(const std::string& name, Item<TYPE>& itm) {
00552 typedef Range<TYPE> _R;
00553 return i_addItem(name, 1, "", _R::min(), _R::max(), itm.m_ptr);
00554 }
00555
00564 template <class TYPE> StatusCode
00565 addItem(const std::string& name, Item<TYPE*>& itm) {
00566 return i_addObject(name,itm.m_ptr,typeid(TYPE));
00567 }
00568
00577 StatusCode
00578 addItem(const std::string& name, Item<IOpaqueAddress*>& itm) {
00579 typedef Range<IOpaqueAddress*> _R;
00580 return i_addItem(name, 1, "", _R::min(), _R::max(), itm.m_ptr);
00581 }
00582
00600 template <class TYPE, class RANGE> StatusCode
00601 addItem(const std::string& name,
00602 Item<TYPE>& itm,
00603 const RANGE low,
00604 const RANGE high)
00605 {
00606 return i_addItem( name, 1, "", TYPE(low), TYPE(high), itm.m_ptr);
00607 }
00608
00622 template <class TYPE> StatusCode
00623 addItem(const std::string& name,
00624 long dim,
00625 Array<TYPE>& array)
00626 {
00627 return i_addItem(name,
00628 dim,
00629 "",
00630 Range<TYPE>::min(),
00631 Range<TYPE>::max(),
00632 array.m_ptr);
00633 }
00634
00654 template <class TYPE, class RANGE> StatusCode
00655 addItem(const std::string& name,
00656 long dim,
00657 Array<TYPE>& array,
00658 const RANGE low,
00659 const RANGE high)
00660 {
00661 return i_addItem(name,
00662 dim,
00663 "",
00664 TYPE(low),
00665 TYPE(high),
00666 array.m_ptr);
00667 }
00668
00699 template <class TYPE, class INDEX, class RANGE> StatusCode
00700 addItem(const std::string& name,
00701 Item<INDEX>& index,
00702 Array<TYPE>& array,
00703 const RANGE low,
00704 const RANGE high)
00705 {
00706 return i_addItem( name,
00707 index->range().distance(),
00708 index->name(),
00709 TYPE(low),
00710 TYPE(high),
00711 array.m_ptr);
00712 }
00713
00739 template <class TYPE, class INDEX, class RANGE> StatusCode
00740 addIndexedItem( const std::string& name,
00741 Item<INDEX>& index,
00742 Array<TYPE>& array,
00743 const RANGE low,
00744 const RANGE high)
00745 {
00746 return i_addItem( name,
00747 index->range().distance(),
00748 index->name(),
00749 TYPE(low),
00750 TYPE(high),
00751 array.m_ptr);
00752 }
00753
00778 template <class TYPE, class INDEX> StatusCode
00779 addItem(const std::string& name,
00780 Item<INDEX>& index,
00781 Array<TYPE>& array)
00782 {
00783 return i_addItem( name,
00784 index->range().distance(),
00785 index->name(),
00786 Range<TYPE>::min(),
00787 Range<TYPE>::max(),
00788 array.m_ptr);
00789 }
00790
00810 template <class TYPE, class INDEX> StatusCode
00811 addIndexedItem( const std::string& name,
00812 Item<INDEX>& index,
00813 Array<TYPE>& array)
00814 {
00815 return i_addItem( name,
00816 index->range().distance(),
00817 index->name(),
00818 Range<TYPE>::min(),
00819 Range<TYPE>::max(),
00820 array.m_ptr);
00821 }
00822
00840 template <class TYPE> StatusCode
00841 addItem(const std::string& name,
00842 long cols,
00843 long rows,
00844 Matrix<TYPE>& matrix)
00845 {
00846 return i_addItem(name,
00847 cols,
00848 rows,
00849 "",
00850 Range<TYPE>::min(),
00851 Range<TYPE>::max(),
00852 matrix.m_ptr);
00853 }
00854
00877 template <class TYPE, class RANGE> StatusCode
00878 addItem(const std::string& name,
00879 long cols,
00880 long rows,
00881 Matrix<TYPE>& result,
00882 const RANGE low,
00883 const RANGE high)
00884 {
00885 return i_addItem(name,
00886 cols,
00887 rows,
00888 "",
00889 TYPE(low),
00890 TYPE(high),
00891 result.m_ptr);
00892 }
00893
00919 template <class TYPE, class INDEX> StatusCode
00920 addItem(const std::string& name,
00921 Item<INDEX>& index,
00922 Matrix<TYPE>& matrix,
00923 long rows)
00924 {
00925 return i_addItem( name,
00926 index->range().distance(),
00927 rows,
00928 index->name(),
00929 Range<TYPE>::min(),
00930 Range<TYPE>::max(),
00931 matrix.m_ptr);
00932 }
00933
00954 template <class TYPE, class INDEX> StatusCode
00955 addIndexedItem( const std::string& name,
00956 Item<INDEX>& col_index,
00957 long rows,
00958 Matrix<TYPE>& matrix)
00959 {
00960 return i_addItem( name,
00961 col_index->range().distance(),
00962 rows,
00963 col_index->name(),
00964 Range<TYPE>::min(),
00965 Range<TYPE>::max(),
00966 matrix.m_ptr);
00967 }
00968
01001 template <class TYPE, class INDEX, class RANGE> StatusCode
01002 addItem(const std::string& name,
01003 Item<INDEX>& index,
01004 Matrix<TYPE>& matrix,
01005 long rows,
01006 const RANGE low,
01007 const RANGE high)
01008 {
01009 return i_addItem( name,
01010 index->range().distance(),
01011 rows,
01012 index->name(),
01013 TYPE(low),
01014 TYPE(high),
01015 matrix.m_ptr);
01016 }
01017
01045 template <class TYPE, class INDEX, class RANGE> StatusCode
01046 addIndexedItem( const std::string& name,
01047 Item<INDEX>& index,
01048 long rows,
01049 Matrix<TYPE>& matrix,
01050 const RANGE low,
01051 const RANGE high)
01052 {
01053 return i_addItem( name,
01054 index->range().distance(),
01055 rows,
01056 index->name(),
01057 TYPE(low),
01058 TYPE(high),
01059 matrix.m_ptr);
01060 }
01061 };
01062
01065 class Directory : public DataObject {
01066 public:
01068 Directory() {
01069 }
01071 virtual ~Directory() {
01072 }
01074 static const CLID& classID() {
01075 return CLID_NTupleDirectory;
01076 }
01078 virtual const CLID& clID() const {
01079 return classID();
01080 }
01081 };
01082
01085 class File : public Directory {
01086 protected:
01088 std::string m_name;
01090 std::string m_logName;
01092 long m_type;
01094 bool m_isOpen;
01095 public:
01096 File() : m_type(0), m_isOpen(false) {
01097 }
01099 File(long type, const std::string name, const std::string& logName)
01100 : m_name(name), m_logName(logName), m_type(type), m_isOpen(false) {
01101 }
01103 virtual ~File() {
01104 }
01106 static const CLID& classID() {
01107 return CLID_NTupleFile;
01108 }
01110 virtual const CLID& clID() const {
01111 return classID();
01112 }
01114 void setType(const long typ) {
01115 m_type = typ;
01116 }
01118 long type() const {
01119 return m_type;
01120 }
01122 const std::string& name() const {
01123 return m_name;
01124 }
01126 void setName(const std::string& nam) {
01127 m_name = nam;
01128 }
01130 const std::string& logicalName() const {
01131 return m_logName;
01132 }
01134 void setLogicalName( const std::string& l) {
01135 m_logName = l;
01136 }
01138 void setOpen(bool flag) {
01139 m_isOpen = flag;
01140 }
01142 bool isOpen() const {
01143 return m_isOpen;
01144 }
01145 };
01146
01147
01148
01149 template <>
01150 class Array <IOpaqueAddress*>
01151 {
01152 private:
01153 Array(){}
01154 public:
01155 virtual ~Array() {}
01156 virtual void dummy() = 0;
01157 };
01158 template <>
01159 class Matrix<IOpaqueAddress*>
01160 {
01161 private:
01162 Matrix(){}
01163 public:
01164 virtual ~Matrix() {}
01165 virtual void dummy() = 0;
01166 };
01167
01168 #ifndef ALLOW_ALL_TYPES
01169 #else
01170 typedef Item<bool> BoolItem;
01171 typedef Item<char> CharItem;
01172 typedef Item<unsigned char> UCharItem;
01173 typedef Item<short> ShortItem;
01174 typedef Item<unsigned short> UShortItem;
01175 typedef Item<long> LongItem;
01176 typedef Item<long long> LongLongItem;
01177 typedef Item<unsigned long> ULongItem;
01178 typedef Item<unsigned long long> ULongLongItem;
01179 typedef Item<int> IntItem;
01180 typedef Item<unsigned int> UIntItem;
01181 typedef Item<float> FloatItem;
01182 typedef Item<double> DoubleItem;
01183 typedef Array<bool> BoolArray;
01184 typedef Array<char> CharArray;
01185 typedef Array<unsigned char> UCharArray;
01186 typedef Array<short> ShortArray;
01187 typedef Array<unsigned short> UShortArray;
01188 typedef Array<long> LongArray;
01189 typedef Array<unsigned long> ULongArray;
01190 typedef Array<int> IntArray;
01191 typedef Array<unsigned int> UIntArray;
01192 typedef Array<float> FloatArray;
01193 typedef Array<double> DoubleArray;
01194 typedef Matrix<bool> BoolMatrix;
01195 typedef Matrix<char> CharMatrix;
01196 typedef Matrix<unsigned char> UCharMatrix;
01197 typedef Matrix<short> ShortMatrix;
01198 typedef Matrix<unsigned short> UShortMatrix;
01199 typedef Matrix<long> LongMatrix;
01200 typedef Matrix<unsigned long> ULongMatrix;
01201 typedef Matrix<int> IntMatrix;
01202 typedef Matrix<unsigned int> UIntMatrix;
01203 typedef Matrix<float> FloatMatrix;
01204 typedef Matrix<double> DoubleMatrix;
01205 #endif
01206
01207 template <class T>
01208 inline std::ostream& operator<<(std::ostream& s, const Item<T>& obj)
01209 {
01210 return s << T(obj);
01211 }
01212 }
01213
01214
01215 typedef SmartDataPtr<NTuple::Tuple> NTuplePtr;
01216 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
01217 typedef SmartDataPtr<NTuple::File> NTupleFilePtr;
01218
01219 #endif // GAUDIKERNEL_NTUPLE_H