CMS 3D CMS Logo

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