00001 #ifndef DataFormats_Common_Ref_h
00002 #define DataFormats_Common_Ref_h
00003
00004
00005
00006
00007
00008
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #include "boost/functional.hpp"
00107 #include "boost/call_traits.hpp"
00108 #include "boost/type_traits.hpp"
00109 #include "boost/mpl/has_xxx.hpp"
00110 #include "boost/utility/enable_if.hpp"
00111
00112 #include "DataFormats/Provenance/interface/ProductID.h"
00113 #include "DataFormats/Common/interface/EDProductGetter.h"
00114 #include "DataFormats/Common/interface/EDProductfwd.h"
00115 #include "DataFormats/Common/interface/RefBase.h"
00116 #include "DataFormats/Common/interface/traits.h"
00117 #include "DataFormats/Common/interface/Handle.h"
00118 #include "DataFormats/Common/interface/OrphanHandle.h"
00119 #include "DataFormats/Common/interface/TestHandle.h"
00120
00121 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
00122
00123 template <typename C, typename K>
00124 typename boost::enable_if<has_key_compare<C>, bool>::type
00125 compare_key(K const& lhs, K const& rhs) {
00126 typedef typename C::key_compare comparison_functor;
00127 return comparison_functor()(lhs, rhs);
00128 }
00129
00130 template <typename C, typename K>
00131 typename boost::disable_if<has_key_compare<C>, bool>::type
00132 compare_key(K const& lhs, K const& rhs) {
00133 return lhs < rhs;
00134 }
00135
00136 #include "DataFormats/Common/interface/RefTraits.h"
00137
00138 namespace edm {
00139 template<typename C, typename T, typename F>
00140 class RefVector;
00141
00142 template<typename T>
00143 class RefToBaseVector;
00144
00145 template <typename C,
00146 typename T = typename refhelper::ValueTrait<C>::value,
00147 typename F = typename refhelper::FindTrait<C, T>::value>
00148 class Ref {
00149 private:
00150 typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F> > VF;
00151 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00152 friend class RefVectorIterator<C, T, F>;
00153 friend class RefVector<C, T, F>;
00154 friend class RefVector<RefVector<C, T, F>, T, VF>;
00155 friend class RefVector<RefVector<RefVector<C, T, F>, T, VF>, T, VF>;
00156 friend class RefVector<RefVector<C, T, F>, T, VBF>;
00157 friend class RefVector<RefVector<RefVector<C, T, F>, T, VBF>, T, VBF>;
00159
00160 public:
00162 typedef C product_type;
00163 typedef T value_type;
00164 typedef T const element_type;
00165 typedef F finder_type;
00166 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00167 typedef typename boost::remove_cv<typename boost::remove_reference<argument_type>::type>::type key_type;
00170
00172 Ref() : ref_() {}
00173
00175 Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
00176
00178 Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
00179
00181
00182
00183
00184 Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow=true);
00185
00187
00188
00189
00190
00191 Ref(C const* product, key_type itemKey, bool setNow=true);
00192
00194
00195
00196 Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
00197
00201 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00202 ref_(productID, 0, itemKey, 0, mustBeNonZero(prodGetter, "Ref", productID), false) {
00203 }
00204
00206
00207
00208
00209
00210
00211
00212 Ref(ProductID const& productID, T const* item, key_type item_key, C const* product ) :
00213 ref_(productID, product, item_key, item, 0, false) {
00214 }
00215
00219
00220 explicit Ref(ProductID const& id) :
00221 ref_(id, 0, key_traits<key_type>::value, 0, 0, false)
00222 { }
00223
00225 Ref(RefProd<C> const& refProd, key_type itemKey);
00226
00228 ~Ref() {}
00229
00231 T const&
00232 operator*() const;
00233
00235 T const*
00236 operator->() const;
00237
00239 T const* get() const {
00240 return isNull() ? 0 : this->operator->();
00241 }
00242
00244 bool isNull() const {return !isNonnull(); }
00245
00247
00248 bool isNonnull() const { return ref_.isNonnull(); }
00249
00251 bool operator!() const {return isNull();}
00252
00254 ProductID id() const {return ref_.refCore().id();}
00255
00257 EDProductGetter const* productGetter() const {return ref_.refCore().productGetter();}
00258
00260
00261 C const* product() const;
00262
00264 key_type key() const {return ref_.item().key();}
00265
00266
00267 key_type index() const {return ref_.item().key();}
00268
00270 RefBase<key_type> const& ref() const {return ref_;}
00271
00272 bool hasProductCache() const {return ref_.refCore().productPtr() != 0;}
00273
00274 bool hasCache() const {return ref_.item().ptr() != 0;}
00275
00278 bool isAvailable() const {return ref_.refCore().isAvailable();}
00279
00281 bool isTransient() const {return ref_.refCore().isTransient();}
00282
00283 private:
00284
00285 Ref(RefCore const& refCore, RefItem<key_type> const& item) :
00286 ref_(refCore, item) {
00287 }
00288
00289 private:
00290
00291
00292 void checkTypeAtCompileTime(C const*) {}
00293
00294 RefBase<key_type> ref_;
00295 };
00296 }
00297
00298 #include "DataFormats/Common/interface/RefProd.h"
00299 #include "DataFormats/Common/interface/RefCoreGet.h"
00300 #include "DataFormats/Common/interface/RefItemGet.h"
00301
00302 namespace edm {
00304 template <typename C, typename T, typename F>
00305 inline
00306 Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool setNow) :
00307 ref_(handle.id(), handle.product(), itemKey, 0, 0, false) {
00308 checkTypeAtCompileTime(handle.product());
00309 assert(ref_.item().key() == itemKey);
00310
00311 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00312 }
00313
00315 template <typename C, typename T, typename F>
00316 inline
00317 Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow) :
00318 ref_(handle.id(), handle.product(), itemKey, 0, 0, false) {
00319 checkTypeAtCompileTime(handle.product());
00320 assert(ref_.item().key() == itemKey);
00321
00322 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00323 }
00324
00326 template <typename C, typename T, typename F>
00327 inline
00328 Ref<C, T, F>::Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow) :
00329 ref_(refvector.id(), refvector.product(), itemKey, 0, 0, refvector.isTransient()) {
00330 checkTypeAtCompileTime(refvector.product());
00331 assert(ref_.item().key() == itemKey);
00332
00333 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00334 }
00335
00337
00338
00339
00340
00341
00342
00343 template <typename C, typename T, typename F>
00344 inline
00345 Ref<C, T, F>::Ref(C const* product, key_type itemKey, bool setNow) :
00346 ref_(ProductID(), product, product != 0 ? itemKey : key_traits<key_type>::value, 0, 0, true) {
00347 checkTypeAtCompileTime(product);
00348 assert(ref_.item().key() == (product != 0 ? itemKey : key_traits<key_type>::value));
00349
00350 if (setNow && product != 0) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00351 }
00352
00354
00355 template <typename C, typename T, typename F>
00356 inline
00357 Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow) :
00358 ref_(handle.id(), handle.product(), itemKey, 0, 0, true) {
00359 checkTypeAtCompileTime(handle.product());
00360 assert(ref_.item().key() == itemKey);
00361
00362 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00363 }
00364
00366 template <typename C, typename T, typename F>
00367 inline
00368 Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
00369 ref_(refProd.id(), refProd.refCore().productPtr(), itemKey, 0, refProd.refCore().productGetter(), refProd.refCore().isTransient()) {
00370 assert(ref_.item().key() == itemKey);
00371 if (0 != refProd.refCore().productPtr()) {
00372 ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));
00373 }
00374 }
00375
00377
00378 template <typename C, typename T, typename F>
00379 inline
00380 C const*
00381 Ref<C, T, F>::product() const {
00382 return isNull() ? 0 : edm::template getProduct<C>(ref_.refCore());
00383 }
00384
00386 template <typename C, typename T, typename F>
00387 inline
00388 T const&
00389 Ref<C, T, F>::operator*() const {
00390 return *getPtr<C, T, F>(ref_.refCore(), ref_.item());
00391 }
00392
00394 template <typename C, typename T, typename F>
00395 inline
00396 T const*
00397 Ref<C, T, F>::operator->() const {
00398 return getPtr<C, T, F>(ref_.refCore(), ref_.item());
00399 }
00400
00401 template <typename C, typename T, typename F>
00402 inline
00403 bool
00404 operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00405 return lhs.ref() == rhs.ref();
00406 }
00407
00408 template <typename C, typename T, typename F>
00409 inline
00410 bool
00411 operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00412 return !(lhs == rhs);
00413 }
00414
00415 template <typename C, typename T, typename F>
00416 inline
00417 bool
00418 operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00421 return (lhs.ref().refCore() == rhs.ref().refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.ref().refCore() < rhs.ref().refCore());
00422 }
00423
00424 }
00425
00426 #include "DataFormats/Common/interface/HolderToVectorTrait.h"
00427 #include "DataFormats/Common/interface/Holder.h"
00428 #include "DataFormats/Common/interface/VectorHolder.h"
00429 #include "DataFormats/Common/interface/RefVector.h"
00430
00431 namespace edm {
00432 namespace reftobase {
00433
00434 template <typename T, typename REF>
00435 struct RefHolderToVector {
00436 static std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() {
00437 typedef RefVector<typename REF::product_type,
00438 typename REF::value_type,
00439 typename REF::finder_type> REFV;
00440 return std::auto_ptr<BaseVectorHolder<T> >( new VectorHolder<T, REFV> );
00441 }
00442 static std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00443 typedef RefVector<typename REF::product_type,
00444 typename REF::value_type,
00445 typename REF::finder_type> REFV;
00446 return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV> );
00447 }
00448 };
00449
00450 template<typename T1, typename C, typename T, typename F>
00451 struct HolderToVectorTrait<T1, Ref<C, T, F> > {
00452 typedef RefHolderToVector<T1, Ref<C, T, F> > type;
00453 };
00454
00455 template <typename REF>
00456 struct RefRefHolderToRefVector {
00457 static std::auto_ptr<RefVectorHolderBase> makeVectorHolder() {
00458 typedef RefVector<typename REF::product_type,
00459 typename REF::value_type,
00460 typename REF::finder_type> REFV;
00461 return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV> );
00462 }
00463 };
00464
00465 template<typename C, typename T, typename F>
00466 struct RefHolderToRefVectorTrait<Ref<C, T, F> > {
00467 typedef RefRefHolderToRefVector<Ref<C, T, F> > type;
00468 };
00469
00470 }
00471 }
00472
00473 #endif