CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/DataFormats/Common/interface/RefToBaseVector.h

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     //void reserve(size_type n);
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     //size_type capacity() const;
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     //Needed for ROOT storage
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   // Implementation of RefToBaseVector<T>
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   // NOTE: the following implementation has unusual signature!
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