Go to the documentation of this file.00001 #ifndef DataFormats_Common_RefVectorHolder_h
00002 #define DataFormats_Common_RefVectorHolder_h
00003
00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00005 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
00006 #include "FWCore/Utilities/interface/EDMException.h"
00007 #include "DataFormats/Provenance/interface/ProductID.h"
00008
00009 namespace edm {
00010 namespace reftobase {
00011 class RefHolderBase;
00012 template <typename REF> class RefHolder;
00013
00014 template<typename REFV>
00015 class RefVectorHolder : public RefVectorHolderBase {
00016 public:
00017 RefVectorHolder() : RefVectorHolderBase() {
00018 }
00019 RefVectorHolder(REFV const& refs) : RefVectorHolderBase(), refs_(refs) {
00020 }
00021 explicit RefVectorHolder(ProductID const& iId) : RefVectorHolderBase(), refs_(iId) {
00022 }
00023 virtual ~RefVectorHolder() { }
00024 void swap(RefVectorHolder& other);
00025 RefVectorHolder& operator=(RefVectorHolder const& rhs);
00026 virtual bool empty() const;
00027 virtual size_type size() const;
00028 virtual void clear();
00029 virtual void push_back(RefHolderBase const* r);
00030 virtual void reserve(size_type n);
00031 virtual ProductID id() const;
00032 virtual EDProductGetter const* productGetter() const;
00033 virtual RefVectorHolder<REFV> * clone() const;
00034 virtual RefVectorHolder<REFV> * cloneEmpty() const;
00035 void setRefs(REFV const& refs);
00036 virtual void reallyFillView(void const*, ProductID const&, std::vector<void const*> &);
00037 virtual size_t keyForIndex(size_t idx) const;
00038
00039
00040 CMS_CLASS_VERSION(10)
00041
00042 private:
00043 typedef typename RefVectorHolderBase::const_iterator_imp const_iterator_imp;
00044
00045 public:
00046 struct const_iterator_imp_specific : public const_iterator_imp {
00047 typedef ptrdiff_t difference_type;
00048 const_iterator_imp_specific() { }
00049 explicit const_iterator_imp_specific(typename REFV::const_iterator const& it) : i (it) { }
00050 ~const_iterator_imp_specific() { }
00051 const_iterator_imp_specific * clone() const { return new const_iterator_imp_specific(i); }
00052 void increase() { ++i; }
00053 void decrease() { --i; }
00054 void increase(difference_type d) { i += d; }
00055 void decrease(difference_type d) { i -= d; }
00056 bool equal_to(const_iterator_imp const* o) const { return i == dc(o); }
00057 bool less_than(const_iterator_imp const* o) const { return i < dc(o); }
00058 void assign(const_iterator_imp const* o) { i = dc(o); }
00059 boost::shared_ptr<RefHolderBase> deref() const;
00060 difference_type difference(const_iterator_imp const* o) const { return i - dc(o); }
00061 private:
00062 typename REFV::const_iterator const& dc(const_iterator_imp const* o) const {
00063 if (o == 0) {
00064 Exception::throwThis(errors::InvalidReference,
00065 "In RefVectorHolder trying to dereference a null pointer\n");
00066 }
00067 const_iterator_imp_specific const* oo = dynamic_cast<const_iterator_imp_specific const*>(o);
00068 if (oo == 0) {
00069 Exception::throwThis(errors::InvalidReference,
00070 "In RefVectorHolder trying to cast iterator to wrong type\n");
00071 }
00072 return oo->i;
00073 }
00074 typename REFV::const_iterator i;
00075 };
00076
00077 typedef typename RefVectorHolderBase::const_iterator const_iterator;
00078
00079 const_iterator begin() const {
00080 return const_iterator(new const_iterator_imp_specific(refs_.begin()));
00081 }
00082 const_iterator end() const {
00083 return const_iterator(new const_iterator_imp_specific(refs_.end()));
00084 }
00085 virtual void const* product() const {
00086 return refs_.product();
00087 }
00088
00091 virtual bool isAvailable() const { return refs_.isAvailable(); }
00092
00093 private:
00094 virtual boost::shared_ptr<reftobase::RefHolderBase> refBase(size_t idx) const;
00095 REFV refs_;
00096 };
00097
00098
00099
00100
00101
00102 template <typename REFV>
00103 inline
00104 void RefVectorHolder<REFV>::swap(RefVectorHolder<REFV>& other) {
00105 this->RefVectorHolderBase::swap(other);
00106 refs_.swap(other.refs_);
00107 }
00108
00109 template <typename REFV>
00110 inline
00111 RefVectorHolder<REFV>& RefVectorHolder<REFV>::operator=(RefVectorHolder<REFV> const& rhs) {
00112 RefVectorHolder<REFV> temp(rhs);
00113 this->swap(temp);
00114 return *this;
00115 }
00116
00117 template<typename REFV>
00118 inline
00119 bool RefVectorHolder<REFV>::empty() const {
00120 return refs_.empty();
00121 }
00122
00123 template<typename REFV>
00124 inline
00125 typename RefVectorHolder<REFV>::size_type RefVectorHolder<REFV>::size() const {
00126 return refs_.size();
00127 }
00128
00129 template<typename REFV>
00130 inline
00131 void RefVectorHolder<REFV>::clear() {
00132 return refs_.clear();
00133 }
00134
00135 template<typename REFV>
00136 inline
00137 void RefVectorHolder<REFV>::reserve(size_type n) {
00138 typename REFV::size_type s = n;
00139 refs_.reserve(s);
00140 }
00141
00142 template<typename REFV>
00143 inline
00144 ProductID RefVectorHolder<REFV>::id() const {
00145 return refs_.id();
00146 }
00147
00148 template<typename REFV>
00149 inline
00150 EDProductGetter const* RefVectorHolder<REFV>::productGetter() const {
00151 return refs_.productGetter();
00152 }
00153
00154 template<typename REFV>
00155 inline
00156 RefVectorHolder<REFV> * RefVectorHolder<REFV>::clone() const {
00157 return new RefVectorHolder<REFV>(*this);
00158 }
00159
00160 template<typename REFV>
00161 inline
00162 RefVectorHolder<REFV> * RefVectorHolder<REFV>::cloneEmpty() const {
00163 return new RefVectorHolder<REFV>(id());
00164 }
00165
00166 template<typename REFV>
00167 inline
00168 void RefVectorHolder<REFV>::setRefs(REFV const& refs) {
00169 refs_ = refs;
00170 }
00171
00172 template <typename REFV>
00173 inline
00174 size_t RefVectorHolder<REFV>::keyForIndex(size_t idx) const {
00175 return refs_[idx].key();
00176 }
00177
00178
00179 template <typename REFV>
00180 inline
00181 void
00182 swap(RefVectorHolder<REFV>& lhs, RefVectorHolder<REFV>& rhs) {
00183 lhs.swap(rhs);
00184 }
00185 }
00186 }
00187
00188 #include "DataFormats/Common/interface/RefHolder.h"
00189
00190 namespace edm {
00191 namespace reftobase {
00192
00193 template<typename REFV>
00194 void RefVectorHolder<REFV>::push_back(RefHolderBase const* h) {
00195 typedef typename REFV::value_type REF;
00196 RefHolder<REF> const* rh = dynamic_cast<RefHolder<REF> const*>(h);
00197 if(rh == 0) {
00198 Exception::throwThis(errors::InvalidReference,
00199 "RefVectorHolder: attempting to cast a RefHolderBase "
00200 "to an invalid type.\nExpected: ",
00201 typeid(REF).name(),
00202 "\n");
00203 }
00204 refs_.push_back(rh->getRef());
00205 }
00206
00207 template <typename REFV>
00208 boost::shared_ptr<RefHolderBase>
00209 RefVectorHolder<REFV>::refBase(size_t idx) const {
00210 return boost::shared_ptr<RefHolderBase>(new RefHolder<typename REFV::value_type>(refs_[idx]));
00211 }
00212
00213 template<typename REFV>
00214 boost::shared_ptr<RefHolderBase> RefVectorHolder<REFV>::const_iterator_imp_specific::deref() const {
00215 return boost::shared_ptr<RefHolderBase>(new RefHolder<typename REFV::value_type>(*i));
00216 }
00217
00218 }
00219 }
00220
00221 #include "DataFormats/Common/interface/FillView.h"
00222 #include "DataFormats/Common/interface/traits.h"
00223 #include "boost/mpl/if.hpp"
00224
00225 namespace edm {
00226 namespace reftobase {
00227 template<typename REFV>
00228 struct RefVectorHolderNoFillView {
00229 static void reallyFillView(RefVectorHolder<REFV>&, void const*, ProductID const&, std::vector<void const*>&) {
00230 Exception::throwThis(errors::ProductDoesNotSupportViews,
00231 "The product type ",
00232 typeid(typename REFV::collection_type).name(),
00233 "\ndoes not support Views\n");
00234 }
00235 };
00236
00237 template<typename REFV>
00238 struct RefVectorHolderDoFillView {
00239 static void reallyFillView(RefVectorHolder<REFV>& rvh, void const* prod, ProductID const& id , std::vector<void const*> & pointers) {
00240 typedef typename REFV::collection_type collection;
00241 collection const* product = static_cast<collection const*>(prod);
00242 detail::reallyFillView(*product, id, pointers, rvh);
00243 }
00244 };
00245
00246 template<typename REFV>
00247 void RefVectorHolder<REFV>::reallyFillView(void const* iProd, ProductID const& iId , std::vector<void const*> & oPointers) {
00248 typedef
00249 typename boost::mpl::if_c<has_fillView<typename REFV::collection_type>::value,
00250 RefVectorHolderDoFillView<REFV>,
00251 RefVectorHolderNoFillView<REFV> >::type maybe_filler;
00252 maybe_filler::reallyFillView(*this, iProd, iId, oPointers);
00253 }
00254 }
00255 }
00256
00257 #endif