00001 #ifndef DataFormats_Common_RefToBaseVector_h
00002 #define DataFormats_Common_RefToBaseVector_h
00003
00011 #include "DataFormats/Provenance/interface/ProductID.h"
00012 #include "boost/shared_ptr.hpp"
00013 #include <vector>
00014
00015 namespace edm {
00016 template<typename T> class RefToBase;
00017 template<typename T> class View;
00018 template<typename C> class Handle;
00019 class EDProductGetter;
00020 namespace reftobase {
00021 template<typename T> class BaseVectorHolder;
00022 class RefVectorHolderBase;
00023 }
00024
00025 template <class T>
00026 class RefToBaseVector {
00027 public:
00028 typedef RefToBase<T> value_type;
00029 typedef T member_type;
00030 typedef reftobase::BaseVectorHolder<T> holder_type;
00031 typedef typename holder_type::size_type size_type;
00032 typedef typename holder_type::const_iterator const_iterator;
00033
00034 RefToBaseVector();
00035 RefToBaseVector(RefToBaseVector const& );
00036 template<class REFV>
00037 explicit RefToBaseVector(REFV const& );
00038 template<typename C>
00039 explicit RefToBaseVector(Handle<C> const& );
00040 template<typename T1>
00041 explicit RefToBaseVector(Handle<View<T1> > const& );
00042 RefToBaseVector(boost::shared_ptr<reftobase::RefVectorHolderBase> p);
00043 RefToBaseVector& operator=(RefToBaseVector const& iRHS);
00044 void swap(RefToBaseVector& other);
00045
00046 ~RefToBaseVector();
00047
00048
00049 void clear();
00050
00051 value_type at(size_type idx) const;
00052 value_type operator[](size_type idx) const;
00053 bool isValid() const { return holder_ != 0; }
00054 bool isInvalid() const { return holder_ == 0; }
00055 bool empty() const;
00056 size_type size() const;
00057
00058 ProductID id() const;
00059 EDProductGetter const * productGetter() const;
00060 const_iterator begin() const;
00061 const_iterator end() const;
00062
00063 void push_back( const RefToBase<T> & );
00064
00065 void fillView(std::vector<void const*>& pointers) const;
00066 std::auto_ptr<reftobase::RefVectorHolderBase> vectorHolder() const;
00067 const void * product() const;
00068
00071 bool isAvailable() const { return holder_->isAvailable(); }
00072 private:
00073 holder_type * holder_;
00074 };
00075 }
00076
00077 #include "DataFormats/Common/interface/RefToBase.h"
00078 #include "DataFormats/Common/interface/VectorHolder.h"
00079 #include "DataFormats/Common/interface/IndirectVectorHolder.h"
00080 #include "DataFormats/Common/interface/RefVectorHolder.h"
00081 #include "FWCore/Utilities/interface/EDMException.h"
00082 #include "DataFormats/Common/interface/traits.h"
00083
00084 namespace edm {
00085 template <class T>
00086 inline
00087 void
00088 swap(RefToBaseVector<T>& a, RefToBaseVector<T>& b) {
00089 a.swap(b);
00090 }
00091
00092 template <class T>
00093 inline
00094 bool
00095 operator== (RefToBaseVector<T> const& a,
00096 RefToBaseVector<T> const& b)
00097 {
00098 if ( a.isInvalid() && b.isInvalid() ) return true;
00099 if ( a.isInvalid() || b.isInvalid() ) return false;
00100 return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
00101 }
00102
00103
00104
00105
00106
00107 template <class T>
00108 inline
00109 RefToBaseVector<T>::RefToBaseVector() :
00110 holder_(0)
00111 { }
00112
00113 template <class T>
00114 template <class REFV>
00115 inline
00116 RefToBaseVector<T>::RefToBaseVector(const REFV& iRef) :
00117 holder_(new reftobase::VectorHolder<T,REFV>(iRef))
00118 { }
00119
00120 template <class T>
00121 inline
00122 RefToBaseVector<T>::RefToBaseVector(const RefToBaseVector<T>& iOther) :
00123 holder_(iOther.holder_ ? iOther.holder_->clone() : 0)
00124 { }
00125
00126 template <class T>
00127 inline
00128 RefToBaseVector<T>::RefToBaseVector(boost::shared_ptr<reftobase::RefVectorHolderBase> p) :
00129 holder_(new reftobase::IndirectVectorHolder<T>(p)) {
00130 }
00131
00132 template <class T>
00133 inline
00134 RefToBaseVector<T>&
00135 RefToBaseVector<T>::operator=(const RefToBaseVector& iRHS) {
00136 RefToBaseVector temp(iRHS);
00137 this->swap(temp);
00138 return *this;
00139 }
00140
00141 template <class T>
00142 inline
00143 void
00144 RefToBaseVector<T>::swap(RefToBaseVector& other) {
00145 std::swap(holder_, other.holder_);
00146 }
00147
00148 template <class T>
00149 inline
00150 RefToBaseVector<T>::~RefToBaseVector()
00151 {
00152 delete holder_;
00153 }
00154
00155 template <class T>
00156 inline
00157 typename RefToBaseVector<T>::value_type
00158 RefToBaseVector<T>::at(size_type idx) const
00159 {
00160 if ( holder_ == 0 )
00161 throw edm::Exception( edm::errors::InvalidReference )
00162 << "Trying to dereference null RefToBaseVector<T> in method: at(" << idx <<")\n";
00163 return holder_->at( idx );
00164 }
00165
00166 template <class T>
00167 inline
00168 typename RefToBaseVector<T>::value_type
00169 RefToBaseVector<T>::operator[](size_type idx) const
00170 {
00171 return at( idx );
00172 }
00173
00174 template <class T>
00175 inline
00176 bool
00177 RefToBaseVector<T>::empty() const
00178 {
00179 return holder_ ? holder_->empty() : true;
00180 }
00181
00182 template <class T>
00183 inline
00184 typename RefToBaseVector<T>::size_type
00185 RefToBaseVector<T>::size() const
00186 {
00187 return holder_ ? holder_->size() : 0;
00188 }
00189
00190 template <class T>
00191 inline
00192 void
00193 RefToBaseVector<T>::clear()
00194 {
00195 if ( holder_ != 0 )
00196 holder_->clear();
00197 }
00198
00199 template <class T>
00200 inline
00201 ProductID
00202 RefToBaseVector<T>::id() const
00203 {
00204 return holder_ ? holder_->id() : ProductID();
00205 }
00206
00207 template <class T>
00208 inline
00209 EDProductGetter const *
00210 RefToBaseVector<T>::productGetter() const
00211 {
00212 return holder_ ? holder_->productGetter() : 0;
00213 }
00214
00215 template <class T>
00216 inline
00217 typename RefToBaseVector<T>::const_iterator
00218 RefToBaseVector<T>::begin() const
00219 {
00220 return holder_ ? holder_->begin() : const_iterator();
00221 }
00222
00223 template <class T>
00224 inline
00225 typename RefToBaseVector<T>::const_iterator
00226 RefToBaseVector<T>::end() const
00227 {
00228 return holder_ ? holder_->end() : const_iterator();
00229 }
00230
00231 template <typename T>
00232 void
00233 RefToBaseVector<T>::fillView(std::vector<void const*>& pointers) const
00234 {
00235 pointers.reserve(this->size());
00236 for (const_iterator i=begin(), e=end(); i!=e; ++i) {
00237 RefToBase<T> ref = * i;
00238 member_type const * address = ref.isNull() ? 0 : & * ref;
00239 pointers.push_back(address);
00240 }
00241 }
00242
00243
00244 template <typename T>
00245 inline void fillView(RefToBaseVector<T> const& obj,
00246 std::vector<void const*>& pointers) {
00247 obj.fillView(pointers);
00248 }
00249
00250 template <typename T>
00251 struct has_fillView<RefToBaseVector<T> > {
00252 static bool const value = true;
00253 };
00254
00255 template <typename T>
00256 void RefToBaseVector<T>::push_back( const RefToBase<T> & r ) {
00257 if ( holder_ == 0 ) {
00258 std::auto_ptr<reftobase::BaseVectorHolder<T> > p = r.holder_->makeVectorHolder();
00259 holder_ = p.release();
00260 }
00261 holder_->push_back( r.holder_ );
00262 }
00263
00264 template <typename T>
00265 std::auto_ptr<reftobase::RefVectorHolderBase> RefToBaseVector<T>::vectorHolder() const {
00266 return holder_ ? holder_->vectorHolder() : std::auto_ptr<reftobase::RefVectorHolderBase>();
00267 }
00268
00269 template <typename T>
00270 const void * RefToBaseVector<T>::product() const {
00271 return holder_ ? holder_->product() : 0;
00272 }
00273
00274 }
00275
00276 #include "DataFormats/Common/interface/RefVector.h"
00277 #include "DataFormats/Common/interface/Handle.h"
00278 #include "DataFormats/Common/interface/View.h"
00279
00280 namespace edm {
00281
00282 template<typename T>
00283 template<typename C>
00284 RefToBaseVector<T>::RefToBaseVector(const Handle<C> & h ) :
00285 holder_(new reftobase::VectorHolder<T, RefVector<C, typename refhelper::ValueTrait<C>::value,
00286 typename refhelper::FindTrait<C, T>::value> >(h.id())) {
00287 }
00288
00289 template<typename T>
00290 template<typename T1>
00291 RefToBaseVector<T>::RefToBaseVector(const Handle<View<T1> > & h ) :
00292 holder_(h->refVector().holder_->cloneEmpty()) {
00293 }
00294
00295 }
00296 #endif