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