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