CMS 3D CMS Logo

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.8 2008/06/03 21:30:15 wmtan 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     typedef typename seq_t::size_type size_type;
00089     typedef typename seq_t::difference_type difference_type;
00090 
00091     typedef boost::indirect_iterator<typename seq_t::const_reverse_iterator> const_reverse_iterator;
00092 
00093     // Compiler-generated copy, and assignment each does the right
00094     // thing.
00095 
00096     View();
00097 
00098     // This function is dangerous, and should only be called from the
00099     // infrastructure code.
00100     View(std::vector<void const*> const& pointers,
00101          helper_vector_ptr const& helpers);
00102 
00103     virtual ~View();
00104 
00105     void swap(View& other);
00106 
00107     View& operator=(View const& rhs);
00108 
00109     size_type capacity() const;
00110 
00111     // Most non-const member functions not present.
00112     // No access to non-const contents provided.
00113 
00114     const_iterator begin() const;
00115     const_iterator end() const;
00116 
00117     const_reverse_iterator rbegin() const;
00118     const_reverse_iterator rend() const;
00119 
00120     size_type size() const;
00121     size_type max_size() const;
00122     bool empty() const;
00123     const_reference at(size_type pos) const;
00124     const_reference operator[](size_type pos) const;
00125     RefToBase<value_type> refAt(size_type i) const;
00126     Ptr<value_type> ptrAt(size_type i) const;
00127     const RefToBaseVector<T> & refVector() const { return refs_; }
00128     const PtrVector<T> & ptrVector() const { return ptrs_; }
00129 
00130     const_reference front() const;
00131     const_reference back() const;
00132     void pop_back();
00133     ProductID id() const;
00134     EDProductGetter const* productGetter() const;
00135 
00136     // No erase, because erase is required to return an *iterator*,
00137     // not a *const_iterator*.
00138 
00139     // The following is for testing only.
00140     static void fill_from_range(T* first, T* last, View& output);
00141 
00142     const void * product() const {
00143       return refs_.product();
00144     }
00145 
00146   private:
00147     seq_t items_;
00148     RefToBaseVector<T> refs_;
00149     PtrVector<T> ptrs_;
00150     ViewBase* doClone() const;
00151   };
00152 
00153   // Associated free functions (same as for std::vector)
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   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 
00161   //------------------------------------------------------------------
00162   // Implementation of View<T>
00163   //------------------------------------------------------------------
00164 
00165   template <typename T>
00166   inline
00167   View<T>::View() : 
00168     items_(),
00169     refs_(),
00170     ptrs_()
00171   { }
00172 
00173   template <typename T>
00174   View<T>::View(std::vector<void const*> const& pointers,
00175                 helper_vector_ptr const& helpers) : 
00176     items_(),
00177     refs_(),
00178     ptrs_() {
00179     size_type numElements = pointers.size();
00180 
00181     // If the two input vectors are not of the same size, there is a
00182     // logic error in the framework code that called this.
00183     // constructor.
00184     if( helpers.get() != 0 ) {
00185       assert (numElements == helpers->size());
00186       
00187       items_.reserve(numElements);
00188       for (std::vector<void const*>::size_type i = 0; i < pointers.size(); ++i) {
00189         items_.push_back(static_cast<pointer>(pointers[i]));
00190       }
00191       RefToBaseVector<T> temp(helpers);
00192       refs_.swap(temp); 
00193       ptrs_.reserve(refs_.size());
00194       for(typename RefToBaseVector<T>::const_iterator i = refs_.begin(); i != refs_.end(); ++i) {
00195         RefToBase<T> ref = *i;
00196         if (ref.get() != 0) {
00197           ptrs_.push_back(Ptr<T>(ref.id(), ref.get(), ref.key()));
00198         } else if (ref.productGetter() != 0) {
00199           ptrs_.push_back(Ptr<T>(ref.id(), ref.key(), ref.productGetter()));
00200         } else {
00201           ptrs_.push_back(Ptr<T>(ref.id(), 0, ref.key()));
00202         }
00203       }
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

Generated on Tue Jun 9 17:30:39 2009 for CMSSW by  doxygen 1.5.4