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 _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 _Item : virtual public _Data<TYP> {
00128 public:
00130 static _Item* create(INTuple* tup,
00131 const std::string& name,
00132 const std::type_info& info,
00133 TYP min,
00134 TYP max,
00135 TYP def);
00137 template <class T>
00138 _Item<TYP>& operator=(const _Item<T>& copy) {
00139 *this->m_buffer = copy.get();
00140 return *this;
00141 }
00143 void set(const TYP& item) { *this->m_buffer = item; }
00145 virtual TYP get() const { return *this->m_buffer; }
00146 };
00147
00150 template <class TYP> class _Array : virtual public _Data<TYP> {
00151 public:
00153 static _Array* create(INTuple* tup,
00154 const std::string& name,
00155 const std::type_info& info,
00156 const std::string& index,
00157 long len,
00158 TYP min,
00159 TYP max,
00160 TYP def);
00162 template <class T>
00163 _Array<TYP>& operator=(const _Array<T>& copy) {
00164 long len = this->length();
00165 if ( len == copy.length() ) {
00166 const T* source = (const T*)copy.buffer();
00167 for ( int i = 0; i < len; i++ ) {
00168 *(this->m_buffer + i) = *(source + i);
00169 }
00170 return *this;
00171 }
00172 throw std::out_of_range
00173 ("N-tuple matrix cannot be copied! The index range does not match!");
00174 return *this;
00175 }
00177 const TYP& data(long i) const { return *(this->m_buffer + i); }
00179 TYP& data(long i) { return *(this->m_buffer + i); }
00180 };
00181
00184 template <class TYP> class _Matrix : virtual public _Data<TYP> {
00185 protected:
00187 long m_rows;
00188 public:
00190 static _Matrix* create(INTuple* tup,
00191 const std::string& name,
00192 const std::type_info& info,
00193 const std::string& index,
00194 long ncol,
00195 long nrow,
00196 TYP min,
00197 TYP max,
00198 TYP def);
00200 template <class T>
00201 _Matrix<TYP>& operator=(const _Matrix<T>& copy) {
00202 long len = this->length();
00203 if ( len == copy.length() ) {
00204 const T* source = (const T*)copy.buffer();
00205 for ( int i = 0; i < len; i++ ) {
00206 *(this->m_buffer + i) = *(source + i);
00207 }
00208 return *this;
00209 }
00210 throw std::out_of_range
00211 ("N-tuple matrix cannot be copied! The index range does not match!");
00212 return *this;
00213 }
00215 TYP* column(long i) { return (this->m_buffer + i*m_rows); }
00217 const TYP* column(long i) const { return (this->m_buffer + i*m_rows); }
00218 };
00219
00222 template <class TYP> class _Accessor {
00223 friend class Tuple;
00224 private:
00225 _Accessor<TYP>& operator=(const _Accessor<TYP>& copy) {
00226 return *this;
00227 }
00228 protected:
00230 mutable TYP* m_ptr;
00231 public:
00233 _Accessor() : m_ptr(0) { }
00235 virtual ~_Accessor() { }
00237 bool operator !() const { return m_ptr != 0; }
00239 operator const void*() const { return m_ptr; }
00241 TYP* operator->() { return m_ptr; }
00243 const TYP* operator->() const { return m_ptr; }
00245 const Range<TYP>& range() const { return m_ptr->range(); }
00246 };
00247
00250 template <class TYP> class Item : virtual public _Accessor< _Item<TYP> > {
00251 typedef Item<TYP> _My;
00252 public:
00254 Item() { }
00256 operator const TYP () const { return this->m_ptr->get(); }
00258 TYP operator*() { return this->m_ptr->get(); }
00260 const TYP operator*() const { return this->m_ptr->get(); }
00261
00262 Item& operator ++ () { return *this += TYP(1); }
00263 Item& operator ++ (int) { return *this += TYP(1); }
00264 Item& operator -- () { return *this -= TYP(1); }
00265 Item& operator -- (int) { return *this -= TYP(1); }
00267 Item& operator=(const TYP data) {
00268 this->m_ptr->set( data );
00269 return *this;
00270 }
00272 template<class T>
00273 Item& operator=(const Item<T>& data) {
00274 this->m_ptr->set( data->get() );
00275 return *this;
00276 }
00277 Item<TYP>& operator += (const TYP data) {
00278 this->m_ptr->set ( this->m_ptr->get() + data );
00279 return *this;
00280 }
00281 Item<TYP>& operator -= (const TYP data) {
00282 this->m_ptr->set ( this->m_ptr->get() - data );
00283 return *this;
00284 }
00285 Item<TYP>& operator *= (const TYP data) {
00286 this->m_ptr->set ( this->m_ptr->get() * data );
00287 return *this;
00288 }
00289 Item<TYP>& operator /= (const TYP data) {
00290 this->m_ptr->set ( this->m_ptr->get() / data );
00291 return *this;
00292 }
00293 };
00294
00297 template <> class Item<bool> : virtual public _Accessor< _Item<bool> > {
00298 typedef Item<bool> _My;
00299 public:
00301 Item() { }
00303 operator bool () const { return this->m_ptr->get(); }
00305 Item& operator=(const bool data) {
00306 this->m_ptr->set( data );
00307 return *this;
00308 }
00310 template<class T>
00311 Item& operator=(const Item<T>& data) {
00312 this->m_ptr->set( data->get() );
00313 return *this;
00314 }
00315 };
00316
00319 template <class TYP> class Array : virtual public _Accessor < _Array<TYP> > {
00320 public:
00322 Array() { }
00324 template <class T>
00325 Array& operator=(const Array<T>& copy) {
00326 *(this->m_ptr) = *(copy.operator->());
00327 return *this;
00328 }
00330 template <class T>
00331 TYP& operator[] (const T i) { return this->m_ptr->data(i); }
00333 template <class T>
00334 const TYP& operator[] (const T i) const { return this->m_ptr->data(i); }
00335 virtual ~Array() {}
00336 };
00337
00340 template <class TYP> class Matrix : virtual public _Accessor< _Matrix<TYP> > {
00341 public:
00343 Matrix() { }
00345 template <class T>
00346 Matrix& operator=(const Matrix<T>& copy) {
00347 *(this->m_ptr) = *(copy.operator->());
00348 return *this;
00349 }
00351 template <class T>
00352 TYP* operator[] (const T i) { return this->m_ptr->column(i); }
00354 template <class T>
00355 const TYP* operator[] (const T i) const { return this->m_ptr->column(i); }
00356 virtual ~Matrix() {}
00357 };
00358
00365 class Tuple : public DataObject, virtual public INTuple {
00366
00367 protected:
00369 template <class TYPE> StatusCode i_item(const std::string& name,
00370 _Item<TYPE>*& result) const {
00371 try {
00372 result = dynamic_cast< _Item<TYPE>* > (i_find(name));
00373 }
00374 catch (...) {
00375 result = 0;
00376 }
00377 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00378 }
00380 template <class TYPE> StatusCode i_item(const std::string& name,
00381 _Item<TYPE*>*& result) const {
00382 try {
00383 _Item<void*>* p = dynamic_cast< _Item<void*>* > (i_find(name));
00384 result = (_Item<TYPE*>*)p;
00385 }
00386 catch (...) {
00387 result = 0;
00388 }
00389 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00390 }
00392 StatusCode i_item(const std::string& name,
00393 _Item<IOpaqueAddress*>*& result) const {
00394 try {
00395 result = dynamic_cast< _Item<IOpaqueAddress*>* > (i_find(name));
00396 }
00397 catch (...) {
00398 result = 0;
00399 }
00400 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00401 }
00403 template <class TYPE> StatusCode i_item(const std::string& name,
00404 _Array<TYPE>*& result) const {
00405 try {
00406 if ( clID() == CLID_ColumnWiseTuple ) {
00407 result = dynamic_cast< _Array<TYPE>* > (i_find(name));
00408 }
00409 }
00410 catch (...) {
00411 result = 0;
00412 }
00413 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00414 }
00416 template <class TYPE> StatusCode i_item(const std::string& name,
00417 _Matrix<TYPE>*& result) const {
00418 try {
00419 if ( clID() == CLID_ColumnWiseTuple ) {
00420 result = dynamic_cast< _Matrix<TYPE>* > (i_find(name));
00421 }
00422 }
00423 catch (...) {
00424 result = 0;
00425 }
00426 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00427 }
00429 template <class TYPE>
00430 StatusCode i_addItem(const std::string& name,
00431 long,
00432 const std::string&,
00433 TYPE low,
00434 TYPE high,
00435 _Item<TYPE>*& result) {
00436 if ( !i_find(name) ) {
00437 TYPE nil;
00438 nil = 0;
00439 return add( result = _Item<TYPE>::create(this, name, typeid(TYPE), low, high, nil) );
00440 }
00441 return StatusCode::FAILURE;
00442 }
00444 template <class TYPE>
00445 StatusCode i_addItem(const std::string& name,
00446 long dim,
00447 const std::string& index,
00448 TYPE low,
00449 TYPE high,
00450 _Array<TYPE>*& result) {
00451 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00452 return add( result = _Array<TYPE>::create(this,
00453 name,
00454 typeid(TYPE),
00455 index,
00456 dim,
00457 low,
00458 high,
00459 TYPE(0)) );
00460 }
00461 return StatusCode::FAILURE;
00462 }
00464 template <class TYPE>
00465 StatusCode i_addItem(const std::string& name,
00466 long dim1,
00467 long dim2,
00468 const std::string& index,
00469 TYPE low,
00470 TYPE high,
00471 _Matrix<TYPE>*& result) {
00472 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00473 return add( result = _Matrix<TYPE>::create(this,
00474 name,
00475 typeid(TYPE),
00476 index,
00477 dim1,
00478 dim2,
00479 low,
00480 high,
00481 TYPE(0)) );
00482 }
00483 return StatusCode::FAILURE;
00484 }
00485 template <class TYPE> StatusCode
00486 i_addObject(const std::string& name,_Item<TYPE*>*& result,const std::type_info& ) {
00487 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00488 return add( result = (_Item<TYPE*>*)_Item<void*>::create(this, name, typeid(TYPE),0,0,0) );
00489 }
00490 return StatusCode::FAILURE;
00491 }
00492
00493 public:
00495 virtual ~Tuple() {
00496 }
00498 template <class TYPE> StatusCode item(const std::string& name,
00499 Item<TYPE>& result)
00500 {
00501 return i_item(name, result.m_ptr);
00502 }
00504 template <class TYPE> StatusCode item(const std::string& name,
00505 const Item<TYPE>& result) const
00506 {
00507 return i_item(name, result.m_ptr);
00508 }
00510 template <class TYPE> StatusCode
00511 item(const std::string& name, Array<TYPE>& result)
00512 {
00513 return i_item(name, result.m_ptr);
00514 }
00516 template <class TYPE> StatusCode item(const std::string& name,
00517 const Array<TYPE>& result) const
00518 {
00519 return i_item(name, result.m_ptr);
00520 }
00522 template <class TYPE> StatusCode item(const std::string& name,
00523 Matrix<TYPE>& result)
00524 {
00525 return i_item(name, result.m_ptr);
00526 }
00527
00529 template <class TYPE> StatusCode item( const std::string& name,
00530 const Matrix<TYPE>& result) const
00531 {
00532 return i_item(name, result.m_ptr);
00533 }
00534
00548 template <class TYPE> StatusCode
00549 addItem(const std::string& name, Item<TYPE>& itm) {
00550 typedef Range<TYPE> _R;
00551 return i_addItem(name, 1, "", _R::min(), _R::max(), itm.m_ptr);
00552 }
00553
00562 template <class TYPE> StatusCode
00563 addItem(const std::string& name, Item<TYPE*>& itm) {
00564 return i_addObject(name,itm.m_ptr,typeid(TYPE));
00565 }
00566
00575 StatusCode
00576 addItem(const std::string& name, Item<IOpaqueAddress*>& itm) {
00577 typedef Range<IOpaqueAddress*> _R;
00578 return i_addItem(name, 1, "", _R::min(), _R::max(), itm.m_ptr);
00579 }
00580
00598 template <class TYPE, class RANGE> StatusCode
00599 addItem(const std::string& name,
00600 Item<TYPE>& itm,
00601 const RANGE low,
00602 const RANGE high)
00603 {
00604 return i_addItem( name, 1, "", TYPE(low), TYPE(high), itm.m_ptr);
00605 }
00606
00620 template <class TYPE> StatusCode
00621 addItem(const std::string& name,
00622 long dim,
00623 Array<TYPE>& array)
00624 {
00625 return i_addItem(name,
00626 dim,
00627 "",
00628 Range<TYPE>::min(),
00629 Range<TYPE>::max(),
00630 array.m_ptr);
00631 }
00632
00652 template <class TYPE, class RANGE> StatusCode
00653 addItem(const std::string& name,
00654 long dim,
00655 Array<TYPE>& array,
00656 const RANGE low,
00657 const RANGE high)
00658 {
00659 return i_addItem(name,
00660 dim,
00661 "",
00662 TYPE(low),
00663 TYPE(high),
00664 array.m_ptr);
00665 }
00666
00697 template <class TYPE, class INDEX, class RANGE> StatusCode
00698 addItem(const std::string& name,
00699 Item<INDEX>& index,
00700 Array<TYPE>& array,
00701 const RANGE low,
00702 const RANGE high)
00703 {
00704 return i_addItem( name,
00705 index->range().distance(),
00706 index->name(),
00707 TYPE(low),
00708 TYPE(high),
00709 array.m_ptr);
00710 }
00711
00737 template <class TYPE, class INDEX, class RANGE> StatusCode
00738 addIndexedItem( const std::string& name,
00739 Item<INDEX>& index,
00740 Array<TYPE>& array,
00741 const RANGE low,
00742 const RANGE high)
00743 {
00744 return i_addItem( name,
00745 index->range().distance(),
00746 index->name(),
00747 TYPE(low),
00748 TYPE(high),
00749 array.m_ptr);
00750 }
00751
00776 template <class TYPE, class INDEX> StatusCode
00777 addItem(const std::string& name,
00778 Item<INDEX>& index,
00779 Array<TYPE>& array)
00780 {
00781 return i_addItem( name,
00782 index->range().distance(),
00783 index->name(),
00784 Range<TYPE>::min(),
00785 Range<TYPE>::max(),
00786 array.m_ptr);
00787 }
00788
00808 template <class TYPE, class INDEX> StatusCode
00809 addIndexedItem( const std::string& name,
00810 Item<INDEX>& index,
00811 Array<TYPE>& array)
00812 {
00813 return i_addItem( name,
00814 index->range().distance(),
00815 index->name(),
00816 Range<TYPE>::min(),
00817 Range<TYPE>::max(),
00818 array.m_ptr);
00819 }
00820
00838 template <class TYPE> StatusCode
00839 addItem(const std::string& name,
00840 long cols,
00841 long rows,
00842 Matrix<TYPE>& matrix)
00843 {
00844 return i_addItem(name,
00845 cols,
00846 rows,
00847 "",
00848 Range<TYPE>::min(),
00849 Range<TYPE>::max(),
00850 matrix.m_ptr);
00851 }
00852
00875 template <class TYPE, class RANGE> StatusCode
00876 addItem(const std::string& name,
00877 long cols,
00878 long rows,
00879 Matrix<TYPE>& result,
00880 const RANGE low,
00881 const RANGE high)
00882 {
00883 return i_addItem(name,
00884 cols,
00885 rows,
00886 "",
00887 TYPE(low),
00888 TYPE(high),
00889 result.m_ptr);
00890 }
00891
00917 template <class TYPE, class INDEX> StatusCode
00918 addItem(const std::string& name,
00919 Item<INDEX>& index,
00920 Matrix<TYPE>& matrix,
00921 long rows)
00922 {
00923 return i_addItem( name,
00924 index->range().distance(),
00925 rows,
00926 index->name(),
00927 Range<TYPE>::min(),
00928 Range<TYPE>::max(),
00929 matrix.m_ptr);
00930 }
00931
00952 template <class TYPE, class INDEX> StatusCode
00953 addIndexedItem( const std::string& name,
00954 Item<INDEX>& col_index,
00955 long rows,
00956 Matrix<TYPE>& matrix)
00957 {
00958 return i_addItem( name,
00959 col_index->range().distance(),
00960 rows,
00961 col_index->name(),
00962 Range<TYPE>::min(),
00963 Range<TYPE>::max(),
00964 matrix.m_ptr);
00965 }
00966
00999 template <class TYPE, class INDEX, class RANGE> StatusCode
01000 addItem(const std::string& name,
01001 Item<INDEX>& index,
01002 Matrix<TYPE>& matrix,
01003 long rows,
01004 const RANGE low,
01005 const RANGE high)
01006 {
01007 return i_addItem( name,
01008 index->range().distance(),
01009 rows,
01010 index->name(),
01011 TYPE(low),
01012 TYPE(high),
01013 matrix.m_ptr);
01014 }
01015
01043 template <class TYPE, class INDEX, class RANGE> StatusCode
01044 addIndexedItem( const std::string& name,
01045 Item<INDEX>& index,
01046 long rows,
01047 Matrix<TYPE>& matrix,
01048 const RANGE low,
01049 const RANGE high)
01050 {
01051 return i_addItem( name,
01052 index->range().distance(),
01053 rows,
01054 index->name(),
01055 TYPE(low),
01056 TYPE(high),
01057 matrix.m_ptr);
01058 }
01059 };
01060
01063 class Directory : public DataObject {
01064 public:
01066 Directory() {
01067 }
01069 virtual ~Directory() {
01070 }
01072 static const CLID& classID() {
01073 return CLID_NTupleDirectory;
01074 }
01076 virtual const CLID& clID() const {
01077 return Directory::classID();
01078 }
01079 };
01080
01083 class File : public Directory {
01084 protected:
01086 std::string m_name;
01088 std::string m_logName;
01090 long m_type;
01092 bool m_isOpen;
01093 public:
01094 File() : m_type(0), m_isOpen(false) {
01095 }
01097 File(long type, const std::string name, const std::string& logName)
01098 : m_name(name), m_logName(logName), m_type(type), m_isOpen(false) {
01099 }
01101 virtual ~File() {
01102 }
01104 static const CLID& classID() {
01105 return CLID_NTupleFile;
01106 }
01108 virtual const CLID& clID() const {
01109 return File::classID();
01110 }
01112 void setType(const long typ) {
01113 m_type = typ;
01114 }
01116 long type() const {
01117 return m_type;
01118 }
01120 const std::string& name() const {
01121 return m_name;
01122 }
01124 void setName(const std::string& nam) {
01125 m_name = nam;
01126 }
01128 const std::string& logicalName() const {
01129 return m_logName;
01130 }
01132 void setLogicalName( const std::string& l) {
01133 m_logName = l;
01134 }
01136 void setOpen(bool flag) {
01137 m_isOpen = flag;
01138 }
01140 bool isOpen() const {
01141 return m_isOpen;
01142 }
01143 };
01144
01145
01146
01147 template <>
01148 class Array <IOpaqueAddress*>
01149 {
01150 private:
01151 Array(){}
01152 public:
01153 virtual ~Array() {}
01154 virtual void dummy() = 0;
01155 };
01156 template <>
01157 class Matrix<IOpaqueAddress*>
01158 {
01159 private:
01160 Matrix(){}
01161 public:
01162 virtual ~Matrix() {}
01163 virtual void dummy() = 0;
01164 };
01165
01166 #ifndef ALLOW_ALL_TYPES
01167 #else
01168 typedef Item<bool> BoolItem;
01169 typedef Item<char> CharItem;
01170 typedef Item<unsigned char> UCharItem;
01171 typedef Item<short> ShortItem;
01172 typedef Item<unsigned short> UShortItem;
01173 typedef Item<long> LongItem;
01174 typedef Item<unsigned long> ULongItem;
01175 typedef Item<int> IntItem;
01176 typedef Item<unsigned int> UIntItem;
01177 typedef Item<float> FloatItem;
01178 typedef Item<double> DoubleItem;
01179 typedef Array<bool> BoolArray;
01180 typedef Array<char> CharArray;
01181 typedef Array<unsigned char> UCharArray;
01182 typedef Array<short> ShortArray;
01183 typedef Array<unsigned short> UShortArray;
01184 typedef Array<long> LongArray;
01185 typedef Array<unsigned long> ULongArray;
01186 typedef Array<int> IntArray;
01187 typedef Array<unsigned int> UIntArray;
01188 typedef Array<float> FloatArray;
01189 typedef Array<double> DoubleArray;
01190 typedef Matrix<bool> BoolMatrix;
01191 typedef Matrix<char> CharMatrix;
01192 typedef Matrix<unsigned char> UCharMatrix;
01193 typedef Matrix<short> ShortMatrix;
01194 typedef Matrix<unsigned short> UShortMatrix;
01195 typedef Matrix<long> LongMatrix;
01196 typedef Matrix<unsigned long> ULongMatrix;
01197 typedef Matrix<int> IntMatrix;
01198 typedef Matrix<unsigned int> UIntMatrix;
01199 typedef Matrix<float> FloatMatrix;
01200 typedef Matrix<double> DoubleMatrix;
01201 #endif
01202 }
01203
01204
01205 typedef SmartDataPtr<NTuple::Tuple> NTuplePtr;
01206 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
01207 typedef SmartDataPtr<NTuple::File> NTupleFilePtr;
01208
01209 template <class T>
01210 std::ostream& operator<<(std::ostream& s, const NTuple::Item<T>& obj)
01211 {
01212 return s << T(obj);
01213 }
01214
01215 #endif // GAUDIKERNEL_NTUPLE_H