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