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