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