Go to the documentation of this file.00001 #ifndef DataFormats_Common_RefToBaseVector_h
00002 #define DataFormats_Common_RefToBaseVector_h
00003
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 private:
00071 holder_type * holder_;
00072 };
00073 }
00074
00075 #include "DataFormats/Common/interface/RefToBase.h"
00076 #include "DataFormats/Common/interface/VectorHolder.h"
00077 #include "DataFormats/Common/interface/IndirectVectorHolder.h"
00078 #include "DataFormats/Common/interface/RefVectorHolder.h"
00079 #include "FWCore/Utilities/interface/EDMException.h"
00080 #include "DataFormats/Common/interface/traits.h"
00081
00082 namespace edm {
00083 template <class T>
00084 inline
00085 void
00086 swap(RefToBaseVector<T>& a, RefToBaseVector<T>& b) {
00087 a.swap(b);
00088 }
00089
00090 template <class T>
00091 inline
00092 bool
00093 operator== (RefToBaseVector<T> const& a,
00094 RefToBaseVector<T> const& b)
00095 {
00096 if ( a.isInvalid() && b.isInvalid() ) return true;
00097 if ( a.isInvalid() || b.isInvalid() ) return false;
00098 return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
00099 }
00100
00101
00102
00103
00104
00105 template <class T>
00106 inline
00107 RefToBaseVector<T>::RefToBaseVector() :
00108 holder_(0)
00109 { }
00110
00111 template <class T>
00112 template <class REFV>
00113 inline
00114 RefToBaseVector<T>::RefToBaseVector(const REFV& iRef) :
00115 holder_(new reftobase::VectorHolder<T,REFV>(iRef))
00116 { }
00117
00118 template <class T>
00119 inline
00120 RefToBaseVector<T>::RefToBaseVector(const RefToBaseVector<T>& iOther) :
00121 holder_(iOther.holder_ ? iOther.holder_->clone() : 0)
00122 { }
00123
00124 template <class T>
00125 inline
00126 RefToBaseVector<T>::RefToBaseVector(boost::shared_ptr<reftobase::RefVectorHolderBase> p) :
00127 holder_(new reftobase::IndirectVectorHolder<T>(p)) {
00128 }
00129
00130 template <class T>
00131 inline
00132 RefToBaseVector<T>&
00133 RefToBaseVector<T>::operator=(const RefToBaseVector& iRHS) {
00134 RefToBaseVector temp(iRHS);
00135 this->swap(temp);
00136 return *this;
00137 }
00138
00139 template <class T>
00140 inline
00141 void
00142 RefToBaseVector<T>::swap(RefToBaseVector& other) {
00143 std::swap(holder_, other.holder_);
00144 }
00145
00146 template <class T>
00147 inline
00148 RefToBaseVector<T>::~RefToBaseVector()
00149 {
00150 delete holder_;
00151 }
00152
00153 template <class T>
00154 inline
00155 typename RefToBaseVector<T>::value_type
00156 RefToBaseVector<T>::at(size_type idx) const
00157 {
00158 if ( holder_ == 0 )
00159 Exception::throwThis( errors::InvalidReference,
00160 "Trying to dereference null RefToBaseVector<T> in method: at(",
00161 idx,
00162 ")\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