CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/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 
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   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   // Implementation of RefToBaseVector<T>
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   // NOTE: the following implementation has unusual signature!
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