00001 #ifndef DataFormats_Common_BaseVectorHolder_h 00002 #define DataFormats_Common_BaseVectorHolder_h 00003 #include "FWCore/Utilities/interface/EDMException.h" 00004 #include "DataFormats/Common/interface/BaseHolder.h" 00005 00006 namespace edm { 00007 class ProductID; 00008 template <typename T> class RefToBase; 00009 namespace reftobase { 00010 template <typename T> 00011 class BaseVectorHolder { 00012 public: 00013 typedef size_t size_type; 00014 typedef T element_type; 00015 typedef RefToBase<T> base_ref_type; 00016 BaseVectorHolder() {} 00017 virtual ~BaseVectorHolder() {} 00018 virtual BaseVectorHolder* clone() const = 0; 00019 virtual BaseVectorHolder* cloneEmpty() const = 0; 00020 virtual base_ref_type const at(size_type idx) const = 0; 00021 virtual bool empty() const = 0; 00022 00023 virtual size_type size() const = 0; 00024 //virtual size_type capacity() const = 0; 00025 //virtual void reserve(size_type n) = 0; 00026 virtual void clear() = 0; 00027 virtual ProductID id() const = 0; 00028 virtual EDProductGetter const* productGetter() const = 0; 00029 void swap(BaseVectorHolder& other) {} // nothing to swap 00030 00031 // the following structure is public 00032 // to allow reflex dictionary to compile 00033 // protected: 00034 struct const_iterator_imp { 00035 typedef ptrdiff_t difference_type; 00036 const_iterator_imp() { } 00037 virtual ~const_iterator_imp() { } 00038 virtual const_iterator_imp * clone() const = 0; 00039 virtual void increase() = 0; 00040 virtual void decrease() = 0; 00041 virtual void increase( difference_type d ) = 0; 00042 virtual void decrease( difference_type d ) = 0; 00043 virtual bool equal_to( const const_iterator_imp * ) const = 0; 00044 virtual bool less_than( const const_iterator_imp * ) const = 0; 00045 virtual void assign( const const_iterator_imp * ) = 0; 00046 virtual base_ref_type deref() const = 0; 00047 virtual difference_type difference( const const_iterator_imp * ) const = 0; 00048 }; 00049 00050 struct const_iterator : public std::iterator <std::random_access_iterator_tag, RefToBase<T> >{ 00051 typedef base_ref_type value_type; 00052 typedef std::auto_ptr<value_type> pointer; 00053 typedef std::ptrdiff_t difference_type; 00054 const_iterator() : i( 0 ) { } 00055 const_iterator( const_iterator_imp * it ) : i( it ) { } 00056 const_iterator( const const_iterator & it ) : i( it.isValid() ? it.i->clone() : 0 ) { } 00057 ~const_iterator() { delete i; } 00058 const_iterator & operator=( const const_iterator & it ) { 00059 if ( isInvalid() ) i = it.i; 00060 else i->assign( it.i ); 00061 return *this; 00062 } 00063 const_iterator& operator++() { 00064 if ( isInvalid() ) 00065 throw edm::Exception( edm::errors::InvalidReference ) 00066 << "Trying to increment an inavlid RefToBaseVector<T>::const_iterator"; 00067 i->increase(); 00068 return *this; 00069 } 00070 const_iterator operator++( int ) { 00071 if ( isInvalid() ) 00072 throw edm::Exception( edm::errors::InvalidReference ) 00073 << "Trying to postincrement an inavlid RefToBaseVector<T>::const_iterator"; 00074 const_iterator ci = *this; 00075 i->increase(); 00076 return ci; 00077 } 00078 const_iterator& operator--() { 00079 if ( isInvalid() ) 00080 throw edm::Exception( edm::errors::InvalidReference ) 00081 << "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator"; 00082 i->decrease(); 00083 return *this; 00084 } 00085 const_iterator operator--( int ) { 00086 if ( isInvalid() ) 00087 throw edm::Exception( edm::errors::InvalidReference ) 00088 << "Trying to postdecrement an inavlid RefToBaseVector<T>::const_iterator"; 00089 const_iterator ci = *this; 00090 i->decrease(); 00091 return ci; 00092 } 00093 difference_type operator-( const const_iterator & o ) const { 00094 if ( isInvalid() && o.isInvalid() ) return 0; 00095 if ( isInvalid() || o.isInvalid() ) 00096 throw edm::Exception( edm::errors::InvalidReference ) 00097 << "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator"; 00098 return i->difference( o.i ); 00099 } 00100 const_iterator operator+( difference_type n ) const { 00101 if ( isInvalid() ) 00102 throw edm::Exception( edm::errors::InvalidReference ) 00103 << "Trying to compute sum with an inavlid RefToBaseVector<T>::const_iterator"; 00104 const_iterator_imp * ii = i->clone(); 00105 ii->increase( n ); 00106 return const_iterator( ii ); 00107 } 00108 const_iterator operator-( difference_type n ) const { 00109 if ( isInvalid() ) 00110 throw edm::Exception( edm::errors::InvalidReference ) 00111 << "Trying to compute difference with an inavlid RefToBaseVector<T>::const_iterator"; 00112 const_iterator_imp * ii = i->clone(); 00113 ii->decrease( n ); 00114 return const_iterator( ii ); 00115 } 00116 bool operator<( const const_iterator & o ) const { 00117 if ( isInvalid() && o.isInvalid() ) return false; 00118 if ( isInvalid() || o.isInvalid() ) 00119 throw edm::Exception( edm::errors::InvalidReference ) 00120 << "Trying to compute < operator with an inavlid RefToBaseVector<T>::const_iterator"; 00121 return i->less_than( o.i ); 00122 } 00123 bool operator==( const const_iterator& ci ) const { 00124 if ( isInvalid() && ci.isInvalid() ) return true; 00125 if ( isInvalid() || ci.isInvalid() ) return false; 00126 return i->equal_to( ci.i ); 00127 } 00128 bool operator!=( const const_iterator& ci ) const { 00129 if ( isInvalid() && ci.isInvalid() ) return false; 00130 if ( isInvalid() || ci.isInvalid() ) return true; 00131 return ! i->equal_to( ci.i ); 00132 } 00133 value_type operator * () const { 00134 if ( isInvalid() ) 00135 throw edm::Exception( edm::errors::InvalidReference ) 00136 << "Trying to dereference an inavlid RefToBaseVector<T>::const_iterator"; 00137 return i->deref(); 00138 } 00139 pointer operator->() const { 00140 return pointer( new value_type( operator*() ) ); 00141 } 00142 const_iterator & operator +=( difference_type d ) { 00143 if ( isInvalid() ) 00144 throw edm::Exception( edm::errors::InvalidReference ) 00145 << "Trying to increment an inavlid RefToBaseVector<T>::const_iterator"; 00146 i->increase( d ); 00147 return *this; 00148 } 00149 const_iterator & operator -=( difference_type d ) { 00150 if ( isInvalid() ) 00151 throw edm::Exception( edm::errors::InvalidReference ) 00152 << "Trying to decrement an inavlid RefToBaseVector<T>::const_iterator"; 00153 i->decrease( d ); 00154 return *this; 00155 } 00156 bool isValid() const { return i != 0; } 00157 bool isInvalid() const { return i == 0; } 00158 00159 private: 00160 const_iterator_imp * i; 00161 }; 00162 00163 virtual const_iterator begin() const = 0; 00164 virtual const_iterator end() const = 0; 00165 virtual void push_back( const BaseHolder<T> * ) = 0; 00166 virtual std::auto_ptr<RefVectorHolderBase> vectorHolder() const = 0; 00167 virtual const void * product() const = 0; 00168 00171 virtual bool isAvailable() const = 0; 00172 00173 }; 00174 00175 // Free swap function 00176 template <typename T> 00177 inline 00178 void 00179 swap(BaseVectorHolder<T>& lhs, BaseVectorHolder<T>& rhs) { 00180 lhs.swap(rhs); 00181 } 00182 } 00183 } 00184 00185 #endif