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 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00023
00024 #include <stdexcept>
00025 #include <vector>
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;
00044 typedef const_reference reference;
00045
00046
00047 typedef typename value_type::key_type key_type;
00048 typedef std::vector<key_type> KeyVec;
00049
00050
00051 typedef typename KeyVec::size_type size_type;
00052 typedef RefVectorBase<key_type> contents_type;
00053
00056 RefVector() : refVector_() {}
00057 RefVector(RefVector const& rh) : refVector_(rh.refVector_){}
00058 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00059 RefVector(RefVector && rh) noexcept : refVector_(std::move(rh.refVector_)){}
00060 #endif
00061
00062 RefVector(ProductID const& iId) : refVector_(iId) {}
00064 void push_back(value_type const& ref) {
00065 refVector_.pushBack(ref.refCore(), ref.key());
00066 }
00067
00069 value_type const operator[](size_type idx) const {
00070 key_type const& key = refVector_.keys()[idx];
00071 RefCore const& prod = refVector_.refCore();
00072 return value_type(prod, key);
00073 }
00074
00076 value_type const at(size_type idx) const {
00077 key_type const& key = refVector_.keys().at(idx);
00078 RefCore const& prod = refVector_.refCore();
00079 return value_type(prod, key);
00080 }
00081
00083 contents_type const& refVector() const {return refVector_;}
00084
00086 bool empty() const {return refVector_.empty();}
00087
00089 size_type size() const {return refVector_.size();}
00090
00092 size_type capacity() const {return refVector_.capacity();}
00093
00095 void reserve(size_type n) {refVector_.reserve(n);}
00096
00098 const_iterator begin() const;
00099
00101 const_iterator end() const;
00102
00104 ProductID id() const {return refVector_.refCore().id();}
00105
00107 EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00108
00110 bool isNull() const {return !id().isValid();}
00111
00113 bool isNonnull() const {return !isNull();}
00114
00116 bool operator!() const {return isNull();}
00117
00119
00120 C const* product() const;
00121
00124 bool isAvailable() const {return refVector_.refCore().isAvailable();}
00125
00127 bool isTransient() const {return refVector_.refCore().isTransient();}
00128
00130 iterator erase(iterator const& pos);
00131
00133 void clear() {refVector_.clear();}
00134
00136 void swap(RefVector<C, T, F> & other) noexcept;
00137
00139 RefVector& operator=(RefVector const& rhs);
00140 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00141 RefVector& operator=(RefVector && rhs) noexcept {
00142 refVector_ = std::move(rhs.refVector_);
00143 return *this;
00144 }
00145 #endif
00146
00147 bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00148
00149 void fillView(ProductID const& id,
00150 std::vector<void const*>& pointers,
00151 helper_vector& helpers) const;
00152
00153
00154 CMS_CLASS_VERSION(10)
00155 private:
00156 contents_type refVector_;
00157 };
00158
00159 template<typename C, typename T, typename F>
00160 inline
00161 void
00162 RefVector<C, T, F>::swap(RefVector<C, T, F> & other) noexcept {
00163 refVector_.swap(other.refVector_);
00164 }
00165
00166 template<typename C, typename T, typename F>
00167 inline
00168 RefVector<C, T, F>&
00169 RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00170 RefVector<C, T, F> temp(rhs);
00171 this->swap(temp);
00172 return *this;
00173 }
00174
00175 template<typename C, typename T, typename F>
00176 inline
00177 void
00178 swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b) noexcept {
00179 a.swap(b);
00180 }
00181
00182 template<typename C, typename T, typename F>
00183 void
00184 RefVector<C,T,F>::fillView(ProductID const&,
00185 std::vector<void const*>& pointers,
00186 helper_vector& helpers) const {
00187 typedef Ref<C,T,F> ref_type;
00188 typedef reftobase::RefHolder<ref_type> holder_type;
00189
00190 pointers.reserve(this->size());
00191 helpers.reserve(this->size());
00192
00193 size_type key = 0;
00194 for(const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00195 member_type const* address = i->isNull() ? 0 : &**i;
00196 pointers.push_back(address);
00197 holder_type h(ref_type(i->id(), address, i->key(), product()));
00198 helpers.push_back(&h);
00199 }
00200 }
00201
00202 template<typename C, typename T, typename F>
00203 inline
00204 void
00205 fillView(RefVector<C,T,F> const& obj,
00206 ProductID const& id,
00207 std::vector<void const*>& pointers,
00208 helper_vector& helpers) {
00209 obj.fillView(id, pointers, helpers);
00210 }
00211
00212 template<typename C, typename T, typename F>
00213 struct has_fillView<RefVector<C,T,F> > {
00214 static bool const value = true;
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.refVector() == rhs.refVector();
00222 }
00223
00224 template<typename C, typename T, typename F>
00225 inline
00226 bool
00227 operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00228 return !(lhs == rhs);
00229 }
00230
00231 template<typename C, typename T, typename F>
00232 inline
00233 typename RefVector<C, T, F>::iterator
00234 RefVector<C, T, F>::erase(iterator const& pos) {
00235 typename contents_type::keys_type::size_type index = pos - begin();
00236 typename contents_type::keys_type::iterator newPos =
00237 refVector_.eraseAtIndex(index);
00238 RefCore const& prod = refVector_.refCore();
00239
00240 return iterator(prod, newPos);
00241 }
00242
00243 template<typename C, typename T, typename F>
00244 typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00245 return iterator(refVector_.refCore(), refVector_.keys().begin());
00246 }
00247
00248 template<typename C, typename T, typename F>
00249 typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00250 return iterator(refVector_.refCore(), refVector_.keys().end());
00251 }
00252
00253 template<typename C, typename T, typename F>
00254 std::ostream&
00255 operator<<(std::ostream& os, RefVector<C,T,F> const& r) {
00256 for(typename RefVector<C,T,F>::const_iterator
00257 i = r.begin(),
00258 e = r.end();
00259 i != e;
00260 ++i) {
00261 os << *i << '\n';
00262 }
00263 return os;
00264 }
00265 }
00266
00267 #include "DataFormats/Common/interface/RefCoreGet.h"
00268
00269 namespace edm {
00270
00271 template<typename C, typename T, typename F>
00272 C const* RefVector<C,T,F>::product() const {
00273 return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00274 }
00275 }
00276
00277 #include "DataFormats/Common/interface/GetProduct.h"
00278 namespace edm {
00279 namespace detail {
00280
00281 template<typename C, typename T, typename F>
00282 struct GetProduct<RefVector<C, T, F> > {
00283 typedef T element_type;
00284 typedef typename RefVector<C, T, F>::const_iterator iter;
00285 static element_type const* address(iter const& i) {
00286 return &**i;
00287 }
00288 static C const* product(RefVector<C, T, F> const& coll) {
00289 return coll.product();
00290 }
00291 };
00292 }
00293 }
00294 #endif