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