00001 #ifndef DataFormats_Common_IndirectVectorHolder_h 00002 #define DataFormats_Common_IndirectVectorHolder_h 00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" 00004 #include "DataFormats/Common/interface/BaseVectorHolder.h" 00005 #include "DataFormats/Common/interface/RefVectorHolderBase.h" 00006 #include "DataFormats/Common/interface/IndirectHolder.h" 00007 #include <memory> 00008 00009 namespace edm { 00010 namespace reftobase { 00011 00012 template <typename T> 00013 class IndirectVectorHolder : public BaseVectorHolder<T> { 00014 public: 00015 typedef BaseVectorHolder<T> base_type; 00016 typedef typename base_type::size_type size_type; 00017 typedef typename base_type::element_type element_type; 00018 typedef typename base_type::base_ref_type base_ref_type; 00019 typedef typename base_type::const_iterator const_iterator; 00020 00021 IndirectVectorHolder(); 00022 IndirectVectorHolder( const IndirectVectorHolder & other); 00023 IndirectVectorHolder(boost::shared_ptr<RefVectorHolderBase> p); 00024 IndirectVectorHolder(RefVectorHolderBase * p); 00025 virtual ~IndirectVectorHolder(); 00026 IndirectVectorHolder& operator= (IndirectVectorHolder const& rhs); 00027 void swap(IndirectVectorHolder& other); 00028 virtual BaseVectorHolder<T>* clone() const; 00029 virtual BaseVectorHolder<T>* cloneEmpty() const; 00030 virtual ProductID id() const; 00031 virtual EDProductGetter const* productGetter() const; 00032 virtual bool empty() const; 00033 virtual size_type size() const; 00034 virtual void clear(); 00035 virtual base_ref_type const at(size_type idx) const; 00036 virtual std::auto_ptr<reftobase::RefVectorHolderBase> vectorHolder() const { 00037 return std::auto_ptr<reftobase::RefVectorHolderBase>( helper_->clone() ); 00038 } 00039 virtual void push_back( const BaseHolder<T> * r ) { 00040 typedef IndirectHolder<T> holder_type; 00041 const holder_type * h = dynamic_cast<const holder_type *>( r ); 00042 if( h == 0 ) 00043 Exception::throwThis( errors::InvalidReference, 00044 "In IndirectHolder<T> trying to push_back wrong reference type"); 00045 helper_->push_back( h->helper_ ); 00046 } 00047 virtual const void * product() const { 00048 return helper_->product(); 00049 } 00050 00053 virtual bool isAvailable() const { return helper_->isAvailable(); } 00054 00055 //Used by ROOT storage 00056 CMS_CLASS_VERSION(10) 00057 00058 private: 00059 typedef typename base_type::const_iterator_imp const_iterator_imp; 00060 RefVectorHolderBase * helper_; 00061 00062 public: 00063 struct const_iterator_imp_specific : public const_iterator_imp { 00064 typedef ptrdiff_t difference_type; 00065 const_iterator_imp_specific() { } 00066 explicit const_iterator_imp_specific( const typename RefVectorHolderBase::const_iterator & it ) : i ( it ) { } 00067 ~const_iterator_imp_specific() { } 00068 const_iterator_imp_specific * clone() const { return new const_iterator_imp_specific( i ); } 00069 void increase() { ++i; } 00070 void decrease() { --i; } 00071 void increase( difference_type d ) { i += d; } 00072 void decrease( difference_type d ) { i -= d; } 00073 bool equal_to( const const_iterator_imp * o ) const { return i == dc( o ); } 00074 bool less_than( const const_iterator_imp * o ) const { return i < dc( o ); } 00075 void assign( const const_iterator_imp * o ) { i = dc( o ); } 00076 base_ref_type deref() const { 00077 return base_ref_type( * i ); 00078 } 00079 difference_type difference( const const_iterator_imp * o ) const { return i - dc( o ); } 00080 private: 00081 const typename RefVectorHolderBase::const_iterator & dc( const const_iterator_imp * o ) const { 00082 if ( o == 0 ) { 00083 Exception::throwThis( edm::errors::InvalidReference, 00084 "In IndirectVectorHolder trying to dereference a null pointer"); 00085 } 00086 const const_iterator_imp_specific * oo = dynamic_cast<const const_iterator_imp_specific *>( o ); 00087 if ( oo == 0 ) { 00088 Exception::throwThis( errors::InvalidReference, 00089 "In IndirectVectorHolder trying to cast iterator to wrong type "); 00090 } 00091 return oo->i; 00092 } 00093 typename RefVectorHolderBase::const_iterator i; 00094 }; 00095 00096 const_iterator begin() const { 00097 return const_iterator( new const_iterator_imp_specific( helper_->begin() ) ); 00098 } 00099 const_iterator end() const { 00100 return const_iterator( new const_iterator_imp_specific( helper_->end() ) ); 00101 } 00102 }; 00103 00104 template <typename T> 00105 IndirectVectorHolder<T>::IndirectVectorHolder() : BaseVectorHolder<T>(), helper_( 0 ) { } 00106 00107 template <typename T> 00108 IndirectVectorHolder<T>::IndirectVectorHolder(boost::shared_ptr<RefVectorHolderBase> p) : 00109 BaseVectorHolder<T>(), helper_(p->clone()) { } 00110 00111 template <typename T> 00112 IndirectVectorHolder<T>::IndirectVectorHolder(RefVectorHolderBase * p) : 00113 BaseVectorHolder<T>(), helper_(p) { } 00114 00115 template <typename T> 00116 IndirectVectorHolder<T>::IndirectVectorHolder( const IndirectVectorHolder & other ) : 00117 BaseVectorHolder<T>(), helper_( other.helper_->clone() ) { } 00118 00119 template <typename T> 00120 IndirectVectorHolder<T>::~IndirectVectorHolder() { 00121 delete helper_; 00122 } 00123 00124 template <typename T> 00125 inline void IndirectVectorHolder<T>::swap(IndirectVectorHolder& other) { 00126 this->BaseVectorHolder<T>::swap(other); 00127 std::swap(helper_, other.helper_); 00128 } 00129 00130 template <typename T> 00131 inline IndirectVectorHolder<T>& 00132 IndirectVectorHolder<T>::operator=(IndirectVectorHolder const& rhs) { 00133 IndirectVectorHolder temp(rhs); 00134 swap(temp); 00135 return *this; 00136 } 00137 00138 template <typename T> 00139 BaseVectorHolder<T>* 00140 IndirectVectorHolder<T>::clone() const { 00141 return new IndirectVectorHolder<T>(*this); 00142 } 00143 00144 template <typename T> 00145 BaseVectorHolder<T>* 00146 IndirectVectorHolder<T>::cloneEmpty() const { 00147 return new IndirectVectorHolder<T>( helper_->cloneEmpty() ); 00148 } 00149 00150 template <typename T> 00151 ProductID 00152 IndirectVectorHolder<T>::id() const { 00153 return helper_->id(); 00154 } 00155 00156 template <typename T> 00157 EDProductGetter const* IndirectVectorHolder<T>::productGetter() const { 00158 return helper_->productGetter(); 00159 } 00160 00161 template <typename T> 00162 bool IndirectVectorHolder<T>::empty() const { 00163 return helper_->empty(); 00164 } 00165 00166 template <typename T> 00167 typename IndirectVectorHolder<T>::size_type IndirectVectorHolder<T>::size() const { 00168 return helper_->size(); 00169 } 00170 00171 template <typename T> 00172 void IndirectVectorHolder<T>::clear() { 00173 return helper_->clear(); 00174 } 00175 00176 template <typename T> 00177 typename IndirectVectorHolder<T>::base_ref_type const IndirectVectorHolder<T>::at(size_type idx) const { 00178 return helper_ ? helper_->template getRef<T>( idx ) : typename IndirectVectorHolder<T>::base_ref_type(); 00179 } 00180 00181 // Free swap function 00182 template <typename T> 00183 inline 00184 void swap(IndirectVectorHolder<T>& lhs, IndirectVectorHolder<T>& rhs) { 00185 lhs.swap(rhs); 00186 } 00187 } 00188 } 00189 00190 #endif 00191 00192