CMS 3D CMS Logo

RefVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefVector_h
00002 #define DataFormats_Common_RefVector_h
00003 
00004 /*----------------------------------------------------------------------
00005   
00006 RefVector: A template for a vector of interproduct references.
00007         Each vector element is a reference to a member of the same product.
00008 
00009 $Id: RefVector.h,v 1.39 2009/02/12 19:46:18 wmtan Exp $
00010 
00011 ----------------------------------------------------------------------*/
00012 
00013 #include <vector>
00014 #include <stdexcept>
00015 #include "DataFormats/Common/interface/EDProductfwd.h"
00016 #include "DataFormats/Common/interface/Ref.h"
00017 #include "DataFormats/Common/interface/FillView.h"
00018 #include "DataFormats/Common/interface/RefVectorBase.h"
00019 #include "DataFormats/Common/interface/RefHolderBase.h"
00020 #include "DataFormats/Common/interface/RefVectorIterator.h"
00021 #include "DataFormats/Common/interface/RefItem.h"
00022 #include "DataFormats/Provenance/interface/ProductID.h"
00023 #include "DataFormats/Common/interface/traits.h"
00024 #include "DataFormats/Common/interface/RefTraits.h"
00025 #include "DataFormats/Common/interface/RefVectorTraits.h"
00026 
00027 namespace edm {
00028 
00029   template <typename T>
00030   T const* getProduct(RefCore const& ref);
00031 
00032   template <typename C, 
00033             typename T = typename refhelper::ValueTrait<C>::value, 
00034             typename F = typename refhelper::FindTrait<C, T>::value>
00035   class RefVector {
00036   public:
00037     typedef C                               collection_type;
00038     typedef T                               member_type;
00039     typedef F                               finder_type;
00040     typedef typename refhelper::RefVectorTrait<C, T, F>::iterator_type iterator;
00041     typedef iterator                        const_iterator;
00042     typedef typename refhelper::RefVectorTrait<C, T, F>::ref_type value_type;
00043     typedef value_type const                const_reference; // better this than the default 'const value_type &'
00044     typedef const_reference                 reference;       // as operator[] returns 'const R' and not 'R &'
00045 
00046     // key_type is the type of the key into the collection
00047     typedef typename value_type::key_type   key_type;
00048     typedef RefItem<key_type>               RefItemType;
00049     typedef std::vector<RefItemType>        RefItemVec;
00050 
00051     // size_type is the type of the index into the RefVector
00052     typedef typename RefItemVec::size_type  size_type;
00053     typedef RefVectorBase<key_type>         contents_type;
00054     
00057     RefVector() : refVector_() {}
00058 
00059     RefVector(ProductID const& id) : refVector_(id) {}
00061     void push_back(value_type const& ref) 
00062     {refVector_.pushBack(ref.ref().refCore(), ref.ref().item());}
00063 
00065     value_type const operator[](size_type idx) const {
00066       RefItemType const& item = refVector_.items()[idx];
00067       RefCore const& prod = refVector_.refCore();
00068       return value_type(prod, item);
00069     }
00070 
00072     value_type const at(size_type idx) const {
00073       RefItemType const& item = refVector_.items().at(idx);
00074       RefCore const& prod = refVector_.refCore();
00075       return value_type(prod, item);
00076     }
00077 
00079     contents_type const& refVector() const {return refVector_;}
00080 
00082     bool empty() const {return refVector_.empty();}
00083 
00085     size_type size() const {return refVector_.size();}
00086 
00088     size_type capacity() const {return refVector_.capacity();}
00089 
00091     void reserve(size_type n) {refVector_.reserve(n);}
00092 
00094     const_iterator begin() const;
00095 
00097     const_iterator end() const;
00098 
00100     ProductID id() const {return refVector_.refCore().id();}
00101 
00103     EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00104 
00106     bool isNull() const {return !id().isValid();}
00107 
00109     bool isNonnull() const {return !isNull();}
00110 
00112     bool operator!() const {return isNull();}
00113 
00115     // Accessor must get the product if necessary
00116     C const* product() const;
00117 
00120     bool isAvailable() const {return refVector_.refCore().isAvailable();}
00121 
00123     bool isTransient() const {return refVector_.refCore().isTransient();}
00124 
00126     iterator erase(iterator const& pos);
00127 
00129     void clear() {refVector_.clear();}
00130 
00132     void swap(RefVector<C, T, F> & other);
00133 
00135     RefVector& operator=(RefVector const& rhs);
00136 
00138     bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00139 
00140     void fillView(ProductID const& id,
00141                   std::vector<void const*>& pointers,            
00142                   helper_vector& helpers) const;
00143 
00144   private:
00145     contents_type refVector_;
00146   };
00147 
00148   template <typename C, typename T, typename F>
00149   inline
00150   void
00151   RefVector<C, T, F>::swap(RefVector<C, T, F> & other) {
00152     refVector_.swap(other.refVector_);
00153   }
00154 
00155   template <typename C, typename T, typename F>
00156   inline
00157   RefVector<C, T, F>&
00158   RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00159     RefVector<C, T, F> temp(rhs);
00160     this->swap(temp);
00161     return *this;
00162   }
00163 
00164   template <typename C, typename T, typename F>
00165   inline
00166   void
00167   swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b) {
00168     a.swap(b);
00169   }
00170 
00171   template <typename C, typename T, typename F>
00172   void
00173   RefVector<C,T,F>::fillView(ProductID const& id,
00174                              std::vector<void const*>& pointers,
00175                              helper_vector& helpers) const
00176   {
00177     typedef Ref<C,T,F>                     ref_type;
00178     typedef reftobase::RefHolder<ref_type> holder_type;
00179 
00180     pointers.reserve(this->size());
00181     helpers.reserve(this->size());
00182 
00183     size_type key = 0;
00184     for (const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00185       member_type const* address = i->isNull() ? 0 : &**i;
00186       pointers.push_back(address);
00187       holder_type h(ref_type(i->id(), address, i->key(), product() ));
00188       helpers.push_back( & h ); 
00189     }
00190   }
00191 
00192 
00193   template <typename C, typename T, typename F>
00194   inline
00195   void
00196   fillView(RefVector<C,T,F> const& obj,
00197            ProductID const& id,
00198            std::vector<void const*>& pointers,
00199            helper_vector& helpers)
00200   {
00201     obj.fillView(id, pointers, helpers);
00202   }
00203 
00204   template <typename C, typename T, typename F>
00205   struct has_fillView<edm::RefVector<C,T,F> >
00206   {
00207     static bool const value = true;
00208   };
00209 
00210   template <typename C, typename T, typename F>
00211   inline
00212   bool
00213   operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00214     return lhs.refVector() == rhs.refVector();
00215   }
00216 
00217   template <typename C, typename T, typename F>
00218   inline
00219   bool
00220   operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00221     return !(lhs == rhs);
00222   }
00223 
00224   template <typename C, typename T, typename F>
00225   inline
00226   typename RefVector<C, T, F>::iterator 
00227   RefVector<C, T, F>::erase(iterator const& pos) {
00228     typename contents_type::RefItems::size_type index = pos - begin();
00229     typename contents_type::RefItems::iterator newPos = 
00230       refVector_.eraseAtIndex(index);
00231     RefCore const& prod = refVector_.refCore();
00232     //return typename RefVector<C, T, F>::iterator(prod, newPos);
00233     return iterator(prod, newPos);
00234   }
00235 
00236   template <typename C, typename T, typename F>
00237   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00238     return iterator(refVector_.refCore(), refVector_.items().begin());
00239   }
00240   
00241   template <typename C, typename T, typename F>
00242   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00243     return iterator(refVector_.refCore(), refVector_.items().end());
00244   }
00245 
00246   template <typename C, typename T, typename F>
00247   std::ostream&
00248   operator<< (std::ostream& os, RefVector<C,T,F> const& r)
00249   {
00250     for (typename RefVector<C,T,F>::const_iterator
00251            i = r.begin(),
00252            e = r.end();
00253          i != e;
00254          ++i)
00255       {
00256         os << *i << '\n';
00257       }
00258     return os;
00259   }
00260 
00261 }
00262 
00263 #include "DataFormats/Common/interface/RefCoreGet.h"
00264 
00265 namespace edm {
00266 
00267   template <typename C, typename T, typename F>
00268   C const* RefVector<C,T,F>::product() const {
00269     return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00270   }
00271 
00272 }
00273 
00274 #include "DataFormats/Common/interface/GetProduct.h"
00275 namespace edm {
00276   namespace detail {
00277     
00278     template<typename C, typename T, typename F>
00279     struct GetProduct<RefVector<C, T, F> > {
00280       typedef T element_type;
00281       typedef typename RefVector<C, T, F>::const_iterator iter;
00282       static const element_type * address( const iter & i ) {
00283         return &**i;
00284       }
00285       static const C * product( const RefVector<C, T, F> & coll ) {
00286         return coll.product();
00287       }
00288     };
00289   }
00290 }
00291 #endif

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