CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_View_h
00002 #define DataFormats_Common_View_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Framework
00006 // Class  :     View
00007 //
00013 //
00014 // Original Author:
00015 //         Created:  Mon Dec 18 09:48:30 CST 2006
00016 //
00017 
00018 #include "DataFormats/Common/interface/Ptr.h"
00019 #include "DataFormats/Common/interface/PtrVector.h"
00020 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
00021 #include "DataFormats/Common/interface/RefToBaseVector.h"
00022 
00023 #include "boost/iterator/indirect_iterator.hpp"
00024 
00025 #include <vector>
00026 
00027 namespace edm {
00028 
00029   //------------------------------------------------------------------
00030   // Class ViewBase
00031   //
00032   // ViewBase is an abstract base class. It exists only so that we
00033   // make invoke View<T> destructors polymorphically, and copy them
00034   // using clone().
00035   //
00036   //------------------------------------------------------------------
00037 
00038   class ViewBase {
00039   public:
00040     virtual ~ViewBase();
00041     ViewBase* clone() const;
00042 
00043   protected:
00044     ViewBase();
00045     ViewBase(ViewBase const&);
00046     ViewBase& operator=(ViewBase const&);
00047     virtual ViewBase* doClone() const = 0;
00048     void swap(ViewBase&) {} // Nothing to swap
00049   };
00050 
00051   //------------------------------------------------------------------
00066   //------------------------------------------------------------------
00067 
00068 
00069   template<typename T>
00070   class View : public ViewBase {
00071     typedef std::vector<T const*>  seq_t;
00072   public:
00073     typedef T const*   pointer;
00074     typedef T const*   const_pointer;
00075 
00076     typedef T const&   reference;
00077     typedef T const&   const_reference;
00078 
00079     typedef T          value_type;
00080 
00081     typedef boost::indirect_iterator<typename seq_t::const_iterator> const_iterator;
00082 
00083     // This should be a typedef to seq_t::size_type but because this type is used as a template
00084     // argument in a persistened class it must be stable for different architectures
00085     typedef unsigned int  size_type;
00086     typedef typename seq_t::difference_type difference_type;
00087 
00088     typedef boost::indirect_iterator<typename seq_t::const_reverse_iterator> const_reverse_iterator;
00089 
00090     // Compiler-generated copy, and assignment each does the right
00091     // thing.
00092 
00093     View();
00094 
00095     // This function is dangerous, and should only be called from the
00096     // infrastructure code.
00097     View(std::vector<void const*> const& pointers,
00098          helper_vector_ptr const& helpers);
00099 
00100     virtual ~View();
00101 
00102     void swap(View& other);
00103 
00104     View& operator=(View const& rhs);
00105 
00106     size_type capacity() const;
00107 
00108     // Most non-const member functions not present.
00109     // No access to non-const contents provided.
00110 
00111     const_iterator begin() const;
00112     const_iterator end() const;
00113 
00114     const_reverse_iterator rbegin() const;
00115     const_reverse_iterator rend() const;
00116 
00117     size_type size() const;
00118     size_type max_size() const;
00119     bool empty() const;
00120     const_reference at(size_type pos) const;
00121     const_reference operator[](size_type pos) const;
00122     RefToBase<value_type> refAt(size_type i) const;
00123     Ptr<value_type> ptrAt(size_type i) const;
00124     RefToBaseVector<T> const& refVector() const { return refs_; }
00125     PtrVector<T> const& ptrVector() const { return ptrs_; }
00126 
00127     const_reference front() const;
00128     const_reference back() const;
00129     void pop_back();
00130     ProductID id() const;
00131     EDProductGetter const* productGetter() const;
00132 
00133     // No erase, because erase is required to return an *iterator*,
00134     // not a *const_iterator*.
00135 
00136     // The following is for testing only.
00137     static void fill_from_range(T* first, T* last, View& output);
00138 
00139     void const* product() const {
00140       return refs_.product();
00141     }
00142 
00143   private:
00144     seq_t items_;
00145     RefToBaseVector<T> refs_;
00146     PtrVector<T> ptrs_;
00147     ViewBase* doClone() const;
00148   };
00149 
00150   // Associated free functions (same as for std::vector)
00151   template<typename T> bool operator==(View<T> const&, View<T> const&);
00152   template<typename T> bool operator!=(View<T> const&, View<T> const&);
00153   template<typename T> bool operator< (View<T> const&, View<T> const&);
00154   template<typename T> bool operator<=(View<T> const&, View<T> const&);
00155   template<typename T> bool operator> (View<T> const&, View<T> const&);
00156   template<typename T> bool operator>=(View<T> const&, View<T> const&);
00157 
00158   //------------------------------------------------------------------
00159   // Implementation of View<T>
00160   //------------------------------------------------------------------
00161 
00162   template<typename T>
00163   inline
00164   View<T>::View() :
00165     items_(),
00166     refs_(),
00167     ptrs_() {
00168   }
00169 
00170   template<typename T>
00171   View<T>::View(std::vector<void const*> const& pointers,
00172                 helper_vector_ptr const& helpers) :
00173     items_(),
00174     refs_(),
00175     ptrs_() {
00176     size_type numElements = pointers.size();
00177 
00178     // If the two input vectors are not of the same size, there is a
00179     // logic error in the framework code that called this.
00180     // constructor.
00181     if(helpers.get() != 0) {
00182       assert(numElements == helpers->size());
00183 
00184       items_.reserve(numElements);
00185        ptrs_.reserve(refs_.size());
00186       for(std::vector<void const*>::size_type i = 0; i < pointers.size(); ++i) {
00187         void const* p = pointers[i];
00188         items_.push_back(static_cast<pointer>(p));
00189         if(0!=p) {
00190            ptrs_.push_back(Ptr<T>(helpers->id(), static_cast<T const*>(p), helpers->keyForIndex(i)));
00191         } else if(helpers->productGetter() != 0) {
00192            ptrs_.push_back(Ptr<T>(helpers->id(), helpers->keyForIndex(i), helpers->productGetter()));
00193         } else {
00194            ptrs_.push_back(Ptr<T>(helpers->id(), 0, helpers->keyForIndex(i)));
00195         }
00196       }
00197       RefToBaseVector<T> temp(helpers);
00198       refs_.swap(temp);
00199     }
00200   }
00201 
00202   template<typename T>
00203   View<T>::~View() {
00204   }
00205 
00206   template<typename T>
00207   inline
00208   void
00209   View<T>::swap(View& other) {
00210     this->ViewBase::swap(other);
00211     items_.swap(other.items_);
00212     refs_.swap(other.refs_);
00213     ptrs_.swap(other.ptrs_);
00214   }
00215 
00216   template<typename T>
00217   inline
00218   typename  View<T>::size_type
00219   View<T>::capacity() const {
00220     return items_.capacity();
00221   }
00222 
00223   template<typename T>
00224   inline
00225   typename View<T>::const_iterator
00226   View<T>::begin() const {
00227     return items_.begin();
00228   }
00229 
00230   template<typename T>
00231   inline
00232   typename View<T>::const_iterator
00233   View<T>::end() const {
00234     return items_.end();
00235   }
00236 
00237   template<typename T>
00238   inline
00239   typename View<T>::const_reverse_iterator
00240   View<T>::rbegin() const {
00241     return items_.rbegin();
00242   }
00243 
00244   template<typename T>
00245   inline
00246   typename View<T>::const_reverse_iterator
00247   View<T>::rend() const {
00248     return items_.rend();
00249   }
00250 
00251   template<typename T>
00252   inline
00253   typename View<T>::size_type
00254   View<T>::size() const {
00255     return items_.size();
00256   }
00257 
00258   template<typename T>
00259   inline
00260   typename View<T>::size_type
00261   View<T>::max_size() const {
00262     return items_.max_size();
00263   }
00264 
00265   template<typename T>
00266   inline
00267   bool
00268   View<T>::empty() const {
00269     return items_.empty();
00270   }
00271 
00272   template<typename T>
00273   inline
00274   typename View<T>::const_reference
00275   View<T>::at(size_type pos) const {
00276     return *items_.at(pos);
00277   }
00278 
00279   template<typename T>
00280   inline
00281   typename View<T>::const_reference
00282   View<T>::operator[](size_type pos) const {
00283     return *items_[pos];
00284   }
00285 
00286   template<typename T>
00287   inline
00288   RefToBase<T>
00289   View<T>::refAt(size_type i) const {
00290     return refs_[i];
00291   }
00292 
00293   template<typename T>
00294   inline
00295   Ptr<T>
00296   View<T>::ptrAt(size_type i) const {
00297     RefToBase<T> ref = refAt(i);
00298     return Ptr<T>(ref.id(), (ref.isAvailable() ? ref.get(): 0), ref.key());
00299   }
00300 
00301   template<typename T>
00302   inline
00303   typename View<T>::const_reference
00304   View<T>::front() const {
00305     return *items_.front();
00306   }
00307 
00308   template<typename T>
00309   inline
00310   typename View<T>::const_reference
00311   View<T>::back() const {
00312     return *items_.back();
00313   }
00314 
00315   template<typename T>
00316   inline
00317   void
00318   View<T>::pop_back() {
00319     items_.pop_back();
00320   }
00321 
00322   template<typename T>
00323   inline
00324   ProductID
00325   View<T>::id() const {
00326     return refs_.id();
00327   }
00328   template<typename T>
00329   inline
00330   EDProductGetter const*
00331   View<T>::productGetter() const {
00332     return refs_.productGetter();
00333   }
00334 
00335   // The following is for testing only.
00336   template<typename T>
00337   inline
00338   void
00339   View<T>::fill_from_range(T* first, T* last, View& output) {
00340     output.items_.resize(std::distance(first, last));
00341     for(typename View<T>::size_type i = 0; first != last; ++i, ++first)
00342       output.items_[i] = first;
00343   }
00344 
00345   template<typename T>
00346   ViewBase*
00347   View<T>::doClone() const {
00348     return new View(*this);
00349   }
00350 
00351   template<typename T>
00352   inline
00353   View<T>&
00354   View<T>::operator=(View<T> const& rhs) {
00355     View<T> temp(rhs);
00356     this->swap(temp);
00357     return *this;
00358   }
00359 
00360   template<typename T>
00361   inline
00362   bool
00363   operator==(View<T> const& lhs, View<T> const& rhs) {
00364     return
00365       lhs.size() == rhs.size() &&
00366       std::equal(lhs.begin(), lhs.end(), rhs.begin());
00367   }
00368 
00369   template<typename T>
00370   inline
00371   bool
00372   operator!=(View<T> const& lhs, View<T> const& rhs) {
00373     return !(lhs == rhs);
00374   }
00375 
00376   template<typename T>
00377   inline
00378   bool
00379   operator<(View<T> const& lhs, View<T> const& rhs) {
00380     return std::lexicographical_compare(lhs.begin(), lhs.end(),
00381                                         rhs.begin(), rhs.end());
00382   }
00383 
00384   template<typename T>
00385   inline
00386   bool
00387   operator<=(View<T> const& lhs, View<T> const& rhs) {
00388     return !(rhs<lhs);
00389   }
00390 
00391   template<typename T>
00392   inline
00393   bool operator> (View<T> const& lhs, View<T> const& rhs) {
00394     return rhs<lhs;
00395   }
00396 
00397   template<typename T>
00398   inline
00399   bool operator>=(View<T> const& lhs, View<T> const& rhs) {
00400     return !(lhs<rhs);
00401   }
00402 
00403   // Free swap function
00404   template<typename T>
00405   inline
00406   void swap(View<T>& lhs, View<T>& rhs) {
00407     lhs.swap(rhs);
00408   }
00409 }
00410 
00411 #endif