CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/Common/interface/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.41 2011/03/03 22:04:46 chrjones Exp $
00010 
00011 ----------------------------------------------------------------------*/
00012 
00013 #include <vector>
00014 #include <stdexcept>
00015 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00016 #include "DataFormats/Common/interface/EDProductfwd.h"
00017 #include "DataFormats/Common/interface/Ref.h"
00018 #include "DataFormats/Common/interface/FillView.h"
00019 #include "DataFormats/Common/interface/RefVectorBase.h"
00020 #include "DataFormats/Common/interface/RefHolderBase.h"
00021 #include "DataFormats/Common/interface/RefVectorIterator.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 std::vector<key_type>           KeyVec;
00049 
00050     // size_type is the type of the index into the RefVector
00051     typedef typename KeyVec::size_type      size_type;
00052     typedef RefVectorBase<key_type>         contents_type;
00053     
00056     RefVector() : refVector_() {}
00057 
00058     RefVector(ProductID const& id) : refVector_(id) {}
00060     void push_back(value_type const& ref) 
00061     {refVector_.pushBack(ref.refCore(), ref.key());}
00062 
00064     value_type const operator[](size_type idx) const {
00065       key_type const& key = refVector_.keys()[idx];
00066       RefCore const& prod = refVector_.refCore();
00067       return value_type(prod, key);
00068     }
00069 
00071     value_type const at(size_type idx) const {
00072       key_type const& key = refVector_.keys().at(idx);
00073       RefCore const& prod = refVector_.refCore();
00074       return value_type(prod, key);
00075     }
00076 
00078     contents_type const& refVector() const {return refVector_;}
00079 
00081     bool empty() const {return refVector_.empty();}
00082 
00084     size_type size() const {return refVector_.size();}
00085 
00087     size_type capacity() const {return refVector_.capacity();}
00088 
00090     void reserve(size_type n) {refVector_.reserve(n);}
00091 
00093     const_iterator begin() const;
00094 
00096     const_iterator end() const;
00097 
00099     ProductID id() const {return refVector_.refCore().id();}
00100 
00102     EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00103 
00105     bool isNull() const {return !id().isValid();}
00106 
00108     bool isNonnull() const {return !isNull();}
00109 
00111     bool operator!() const {return isNull();}
00112 
00114     // Accessor must get the product if necessary
00115     C const* product() const;
00116 
00119     bool isAvailable() const {return refVector_.refCore().isAvailable();}
00120 
00122     bool isTransient() const {return refVector_.refCore().isTransient();}
00123 
00125     iterator erase(iterator const& pos);
00126 
00128     void clear() {refVector_.clear();}
00129 
00131     void swap(RefVector<C, T, F> & other);
00132 
00134     RefVector& operator=(RefVector const& rhs);
00135 
00137     bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00138 
00139     void fillView(ProductID const& id,
00140                   std::vector<void const*>& pointers,            
00141                   helper_vector& helpers) const;
00142 
00143     //Needed for ROOT storage
00144     CMS_CLASS_VERSION(10)
00145   private:
00146     contents_type refVector_;
00147   };
00148 
00149   template <typename C, typename T, typename F>
00150   inline
00151   void
00152   RefVector<C, T, F>::swap(RefVector<C, T, F> & other) {
00153     refVector_.swap(other.refVector_);
00154   }
00155 
00156   template <typename C, typename T, typename F>
00157   inline
00158   RefVector<C, T, F>&
00159   RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00160     RefVector<C, T, F> temp(rhs);
00161     this->swap(temp);
00162     return *this;
00163   }
00164 
00165   template <typename C, typename T, typename F>
00166   inline
00167   void
00168   swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b) {
00169     a.swap(b);
00170   }
00171 
00172   template <typename C, typename T, typename F>
00173   void
00174   RefVector<C,T,F>::fillView(ProductID const& id,
00175                              std::vector<void const*>& pointers,
00176                              helper_vector& helpers) const
00177   {
00178     typedef Ref<C,T,F>                     ref_type;
00179     typedef reftobase::RefHolder<ref_type> holder_type;
00180 
00181     pointers.reserve(this->size());
00182     helpers.reserve(this->size());
00183 
00184     size_type key = 0;
00185     for (const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00186       member_type const* address = i->isNull() ? 0 : &**i;
00187       pointers.push_back(address);
00188       holder_type h(ref_type(i->id(), address, i->key(), product() ));
00189       helpers.push_back( & h ); 
00190     }
00191   }
00192 
00193 
00194   template <typename C, typename T, typename F>
00195   inline
00196   void
00197   fillView(RefVector<C,T,F> const& obj,
00198            ProductID const& id,
00199            std::vector<void const*>& pointers,
00200            helper_vector& helpers)
00201   {
00202     obj.fillView(id, pointers, helpers);
00203   }
00204 
00205   template <typename C, typename T, typename F>
00206   struct has_fillView<edm::RefVector<C,T,F> >
00207   {
00208     static bool const value = true;
00209   };
00210 
00211   template <typename C, typename T, typename F>
00212   inline
00213   bool
00214   operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00215     return lhs.refVector() == rhs.refVector();
00216   }
00217 
00218   template <typename C, typename T, typename F>
00219   inline
00220   bool
00221   operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00222     return !(lhs == rhs);
00223   }
00224 
00225   template <typename C, typename T, typename F>
00226   inline
00227   typename RefVector<C, T, F>::iterator 
00228   RefVector<C, T, F>::erase(iterator const& pos) {
00229     typename contents_type::keys_type::size_type index = pos - begin();
00230     typename contents_type::keys_type::iterator newPos = 
00231       refVector_.eraseAtIndex(index);
00232     RefCore const& prod = refVector_.refCore();
00233     //return typename RefVector<C, T, F>::iterator(prod, newPos);
00234     return iterator(prod, newPos);
00235   }
00236 
00237   template <typename C, typename T, typename F>
00238   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00239     return iterator(refVector_.refCore(), refVector_.keys().begin());
00240   }
00241   
00242   template <typename C, typename T, typename F>
00243   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00244     return iterator(refVector_.refCore(), refVector_.keys().end());
00245   }
00246 
00247   template <typename C, typename T, typename F>
00248   std::ostream&
00249   operator<< (std::ostream& os, RefVector<C,T,F> const& r)
00250   {
00251     for (typename RefVector<C,T,F>::const_iterator
00252            i = r.begin(),
00253            e = r.end();
00254          i != e;
00255          ++i)
00256       {
00257         os << *i << '\n';
00258       }
00259     return os;
00260   }
00261 
00262 }
00263 
00264 #include "DataFormats/Common/interface/RefCoreGet.h"
00265 
00266 namespace edm {
00267 
00268   template <typename C, typename T, typename F>
00269   C const* RefVector<C,T,F>::product() const {
00270     return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00271   }
00272 
00273 }
00274 
00275 #include "DataFormats/Common/interface/GetProduct.h"
00276 namespace edm {
00277   namespace detail {
00278     
00279     template<typename C, typename T, typename F>
00280     struct GetProduct<RefVector<C, T, F> > {
00281       typedef T element_type;
00282       typedef typename RefVector<C, T, F>::const_iterator iter;
00283       static const element_type * address( const iter & i ) {
00284         return &**i;
00285       }
00286       static const C * product( const RefVector<C, T, F> & coll ) {
00287         return coll.product();
00288       }
00289     };
00290   }
00291 }
00292 #endif