CMS 3D CMS Logo

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