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 "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00107 #include "DataFormats/Common/interface/ConstPtrCache.h"
00108 #include "DataFormats/Common/interface/EDProductfwd.h"
00109 #include "DataFormats/Common/interface/EDProductGetter.h"
00110 #include "DataFormats/Common/interface/Handle.h"
00111 #include "DataFormats/Common/interface/OrphanHandle.h"
00112 #include "DataFormats/Common/interface/RefCore.h"
00113 #include "DataFormats/Common/interface/RefCoreWithIndex.h"
00114 #include "DataFormats/Common/interface/TestHandle.h"
00115 #include "DataFormats/Common/interface/traits.h"
00116 #include "DataFormats/Provenance/interface/ProductID.h"
00117
00118 #include "boost/functional.hpp"
00119 #include "boost/call_traits.hpp"
00120 #include "boost/type_traits.hpp"
00121 #include "boost/mpl/has_xxx.hpp"
00122 #include "boost/utility/enable_if.hpp"
00123
00124 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
00125
00126 template <typename C, typename K>
00127 typename boost::enable_if<has_key_compare<C>, bool>::type
00128 compare_key(K const& lhs, K const& rhs) {
00129 typedef typename C::key_compare comparison_functor;
00130 return comparison_functor()(lhs, rhs);
00131 }
00132
00133 template <typename C, typename K>
00134 typename boost::disable_if<has_key_compare<C>, bool>::type
00135 compare_key(K const& lhs, K const& rhs) {
00136 return lhs < rhs;
00137 }
00138
00139 #include "DataFormats/Common/interface/RefTraits.h"
00140
00141 namespace edm {
00142 template<typename C, typename T, typename F>
00143 class RefVector;
00144
00145 template<typename T>
00146 class RefToBaseVector;
00147
00148 template <typename C,
00149 typename T = typename refhelper::ValueTrait<C>::value,
00150 typename F = typename refhelper::FindTrait<C, T>::value>
00151 class Ref {
00152 private:
00153 typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F> > VF;
00154 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00155 friend class RefVectorIterator<C, T, F>;
00156 friend class RefVector<C, T, F>;
00157 friend class RefVector<RefVector<C, T, F>, T, VF>;
00158 friend class RefVector<RefVector<RefVector<C, T, F>, T, VF>, T, VF>;
00159 friend class RefVector<RefVector<C, T, F>, T, VBF>;
00160 friend class RefVector<RefVector<RefVector<C, T, F>, T, VBF>, T, VBF>;
00162
00163 public:
00165 typedef C product_type;
00166 typedef T value_type;
00167 typedef T const element_type;
00168 typedef F finder_type;
00169 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00170 typedef typename boost::remove_cv<typename boost::remove_reference<argument_type>::type>::type key_type;
00173
00175 Ref() : product_(), index_(key_traits<key_type>::value) {}
00176
00178 Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
00179
00181 Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
00182
00184
00185
00186
00187 Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow=true);
00188
00190
00191
00192
00193
00194 Ref(C const* product, key_type itemKey, bool setNow=true);
00195
00197
00198
00199 Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
00200
00204 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00205 product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {
00206 }
00207
00209
00210
00211
00212
00213
00214
00215 Ref(ProductID const& iProductID, T const* , key_type iItemKey, C const* iProduct) :
00216 product_(iProductID, iProduct, 0, false), index_(iItemKey)
00217 { }
00218
00222
00223 explicit Ref(ProductID const& iId) :
00224 product_(iId, 0, 0, false), index_(key_traits<key_type>::value)
00225 { }
00226
00228 Ref(RefProd<C> const& refProd, key_type itemKey);
00229
00231 ~Ref() {}
00232
00234 T const&
00235 operator*() const;
00236
00238 T const*
00239 operator->() const;
00240
00242 T const* get() const {
00243 return isNull() ? 0 : this->operator->();
00244 }
00245
00247 bool isNull() const {return !isNonnull(); }
00248
00250 bool isNonnull() const { return index_!=edm::key_traits<key_type>::value; }
00251
00253 bool operator!() const {return isNull();}
00254
00256 ProductID id() const {return product_.id();}
00257
00259 EDProductGetter const* productGetter() const {return product_.productGetter();}
00260
00262
00263 C const* product() const;
00264
00266 key_type key() const {return index_;}
00267
00268
00269 key_type index() const {return index_;}
00270
00272 bool hasProductCache() const {return product_.productPtr() != 0;}
00273
00276 bool isAvailable() const {return product_.isAvailable();}
00277
00279 bool isTransient() const {return product_.isTransient();}
00280
00281 RefCore const& refCore() const {return product_;}
00282
00283
00284 CMS_CLASS_VERSION(10)
00285
00286
00287 Ref(RefCore const& iRefCore, key_type const& iKey) :
00288 product_(iRefCore), index_(iKey) {
00289 }
00290
00291 private:
00292
00293
00294 void checkTypeAtCompileTime(C const*) {}
00295
00296 mutable RefCore product_;
00297 key_type index_;
00298
00299 };
00300
00301
00302
00303
00304 #define REF_FOR_VECTOR_ARGS std::vector<E>,typename refhelper::ValueTrait<std::vector<E> >::value,typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value
00305
00306 template <typename E>
00307 class Ref<REF_FOR_VECTOR_ARGS> {
00308 private:
00309 typedef typename refhelper::ValueTrait<std::vector<E> >::value T;
00310 typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value F;
00311 typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F> > VF;
00312 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00313 friend class RefVectorIterator<std::vector<E>, T, F>;
00314 friend class RefVector<std::vector<E>, T, F>;
00315 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
00316 friend class RefVector<RefVector<RefVector<std::vector<E>, T, F>, T, VF>, T, VF>;
00317 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
00318 friend class RefVector<RefVector<RefVector<std::vector<E>, T, F>, T, VBF>, T, VBF>;
00320
00321 public:
00323 typedef std::vector<E> product_type;
00324 typedef typename refhelper::ValueTrait<std::vector<E> >::value value_type;
00325 typedef value_type const element_type;
00326 typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value finder_type;
00327 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00328 typedef unsigned int key_type;
00331
00333 Ref() : product_() {}
00334
00336 Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow=true);
00337
00339 Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
00340
00342
00343
00344
00345 Ref(RefVector<product_type, T, F> const& refvector, key_type itemKey, bool setNow=true);
00346
00348
00349
00350
00351
00352 Ref(product_type const* product, key_type itemKey, bool setNow=true);
00353
00355
00356
00357 Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
00358
00362 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00363 product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false,itemKey) {
00364 }
00365
00367
00368
00369
00370
00371
00372
00373 Ref(ProductID const& iProductID, T const* , key_type iItemKey, product_type const* iProduct) :
00374 product_(iProductID, iProduct, 0, false,iItemKey)
00375 { }
00376
00380
00381 explicit Ref(ProductID const& iId) :
00382 product_(iId, 0, 0, false,key_traits<key_type>::value)
00383 { }
00384
00386 Ref(RefProd<product_type> const& refProd, key_type itemKey);
00387
00389 ~Ref() {}
00390
00392 T const&
00393 operator*() const;
00394
00396 T const*
00397 operator->() const;
00398
00400 T const* get() const {
00401 return isNull() ? 0 : this->operator->();
00402 }
00403
00405 bool isNull() const {return !isNonnull(); }
00406
00408 bool isNonnull() const { return key()!=edm::key_traits<key_type>::value; }
00409
00411 bool operator!() const {return isNull();}
00412
00414 ProductID id() const {return product_.id();}
00415
00417 EDProductGetter const* productGetter() const {return product_.productGetter();}
00418
00420
00421 product_type const* product() const;
00422
00424 key_type key() const {return product_.index();}
00425
00426
00427 key_type index() const {return product_.index();}
00428
00430 bool hasProductCache() const {return product_.productPtr() != 0;}
00431
00434 bool isAvailable() const {return product_.isAvailable();}
00435
00437 bool isTransient() const {return product_.isTransient();}
00438
00439 RefCore const& refCore() const {return product_.toRefCore();}
00440
00441
00442 CMS_CLASS_VERSION(11)
00443
00444
00445 Ref(RefCore const& iRefCore, key_type const& iKey) :
00446 product_(iRefCore,iKey) {
00447 }
00448
00449 private:
00450
00451
00452 void checkTypeAtCompileTime(product_type const*) {}
00453
00454 mutable RefCoreWithIndex product_;
00455
00456 };
00457
00458 }
00459
00460 #include "DataFormats/Common/interface/RefProd.h"
00461 #include "DataFormats/Common/interface/RefCoreGet.h"
00462 #include "DataFormats/Common/interface/RefItemGet.h"
00463
00464 namespace edm {
00466 template <typename C, typename T, typename F>
00467 inline
00468 Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool setNow) :
00469 product_(handle.id(), handle.product(), 0, false), index_(itemKey){
00470 checkTypeAtCompileTime(handle.product());
00471 assert(key() == itemKey);
00472
00473 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00474 }
00475
00477 template <typename E>
00478 inline
00479 Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00480 product_(handle.id(), handle.product(), 0, false,itemKey){
00481 checkTypeAtCompileTime(handle.product());
00482 assert(key() == itemKey);
00483
00484 if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), index());}
00485 }
00486
00488 template <typename C, typename T, typename F>
00489 inline
00490 Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow) :
00491 product_(handle.id(), handle.product(), 0, false), index_(itemKey) {
00492 checkTypeAtCompileTime(handle.product());
00493 assert(key() == itemKey);
00494
00495 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00496 }
00497
00499 template <typename E>
00500 inline
00501 Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00502 product_(handle.id(), handle.product(), 0, false,itemKey) {
00503 checkTypeAtCompileTime(handle.product());
00504 assert(key() == itemKey);
00505
00506 if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00507 }
00508
00510 template <typename C, typename T, typename F>
00511 inline
00512 Ref<C, T, F>::Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow) :
00513 product_(refvector.id(), refvector.product(), 0, refvector.isTransient()), index_(itemKey) {
00514 checkTypeAtCompileTime(refvector.product());
00515 assert(key() == itemKey);
00516
00517 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00518 }
00519
00521 template <typename E>
00522 inline
00523 Ref<REF_FOR_VECTOR_ARGS>::Ref(RefVector<REF_FOR_VECTOR_ARGS> const& refvector, key_type itemKey, bool setNow) :
00524 product_(refvector.id(), refvector.product(), 0, refvector.isTransient(),itemKey) {
00525 checkTypeAtCompileTime(refvector.product());
00526 assert(key() == itemKey);
00527
00528 if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00529 }
00530
00532
00533
00534
00535
00536
00537
00538 template <typename C, typename T, typename F>
00539 inline
00540 Ref<C, T, F>::Ref(C const* iProduct, key_type iItemKey, bool iSetNow) :
00541 product_(ProductID(), iProduct, 0, true), index_(iProduct != 0 ? iItemKey : key_traits<key_type>::value) {
00542 checkTypeAtCompileTime(iProduct);
00543 assert(key() == (iProduct != 0 ? iItemKey : key_traits<key_type>::value));
00544
00545 if (iSetNow && iProduct != 0) {getPtr_<C, T, F>(product_, index_);}
00546 }
00547
00548 template <typename E>
00549 inline
00550 Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type iItemKey, bool iSetNow) :
00551 product_(ProductID(), iProduct, 0, true,(iProduct != 0 ? iItemKey : key_traits<key_type>::value)) {
00552 checkTypeAtCompileTime(iProduct);
00553 assert(key() == (iProduct != 0 ? iItemKey : key_traits<key_type>::value));
00554
00555 if (iSetNow && iProduct != 0) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00556 }
00557
00559
00560 template <typename C, typename T, typename F>
00561 inline
00562 Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow) :
00563 product_(handle.id(), handle.product(), 0, true), index_(itemKey) {
00564 checkTypeAtCompileTime(handle.product());
00565 assert(key() == itemKey);
00566
00567 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00568 }
00569
00570 template <typename E>
00571 inline
00572 Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E> > const& handle, key_type itemKey, bool setNow) :
00573 product_(handle.id(), handle.product(), 0, true,itemKey) {
00574 checkTypeAtCompileTime(handle.product());
00575 assert(key() == itemKey);
00576
00577 if (setNow) {getPtr_<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());}
00578 }
00579
00581 template <typename C, typename T, typename F>
00582 inline
00583 Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
00584 product_(refProd.id(), refProd.refCore().productPtr(), refProd.refCore().productGetter(), refProd.refCore().isTransient()), index_(itemKey) {
00585 assert(index() == itemKey);
00586 }
00587
00588 template <typename E>
00589 inline
00590 Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E> > const& refProd, key_type itemKey) :
00591 product_(refProd.id(), refProd.refCore().productPtr(), refProd.refCore().productGetter(), refProd.refCore().isTransient(),itemKey) {
00592 assert(index() == itemKey);
00593 }
00594
00595
00597
00598 template <typename C, typename T, typename F>
00599 inline
00600 C const*
00601 Ref<C, T, F>::product() const {
00602 return isNull() ? 0 : edm::template getProduct<C>(product_);
00603 }
00604 template <typename E>
00605 inline
00606 std::vector<E> const*
00607 Ref<REF_FOR_VECTOR_ARGS>::product() const {
00608 return isNull() ? 0 : edm::template getProduct<std::vector<E> >(product_.toRefCore());
00609 }
00610
00612 template <typename C, typename T, typename F>
00613 inline
00614 T const&
00615 Ref<C, T, F>::operator*() const {
00616 return *getPtr<C, T, F>(product_, index_);
00617 }
00618 template <typename E>
00619 inline
00620 typename refhelper::ValueTrait<std::vector<E> >::value const&
00621 Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
00622 return *getPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
00623 }
00624
00626 template <typename C, typename T, typename F>
00627 inline
00628 T const*
00629 Ref<C, T, F>::operator->() const {
00630 return getPtr<C, T, F>(product_, index_);
00631 }
00632 template <typename E>
00633 inline
00634 typename refhelper::ValueTrait<std::vector<E> >::value const*
00635 Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
00636 return getPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
00637 }
00638
00639 template <typename C, typename T, typename F>
00640 inline
00641 bool
00642 operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00643 return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore() ;
00644 }
00645
00646 template <typename C, typename T, typename F>
00647 inline
00648 bool
00649 operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00650 return !(lhs == rhs);
00651 }
00652
00653 template <typename C, typename T, typename F>
00654 inline
00655 bool
00656 operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00659 return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
00660 }
00661
00662 }
00663
00664 #include "DataFormats/Common/interface/HolderToVectorTrait.h"
00665 #include "DataFormats/Common/interface/Holder.h"
00666 #include "DataFormats/Common/interface/VectorHolder.h"
00667 #include "DataFormats/Common/interface/RefVector.h"
00668
00669 namespace edm {
00670 namespace reftobase {
00671
00672 template <typename T, typename REF>
00673 struct RefHolderToVector {
00674 static std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() {
00675 typedef RefVector<typename REF::product_type,
00676 typename REF::value_type,
00677 typename REF::finder_type> REFV;
00678 return std::auto_ptr<BaseVectorHolder<T> >(new VectorHolder<T, REFV>);
00679 }
00680 static std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00681 typedef RefVector<typename REF::product_type,
00682 typename REF::value_type,
00683 typename REF::finder_type> REFV;
00684 return std::auto_ptr<RefVectorHolderBase>(new RefVectorHolder<REFV>);
00685 }
00686 };
00687
00688 template<typename T1, typename C, typename T, typename F>
00689 struct HolderToVectorTrait<T1, Ref<C, T, F> > {
00690 typedef RefHolderToVector<T1, Ref<C, T, F> > type;
00691 };
00692
00693 template <typename REF>
00694 struct RefRefHolderToRefVector {
00695 static std::auto_ptr<RefVectorHolderBase> makeVectorHolder() {
00696 typedef RefVector<typename REF::product_type,
00697 typename REF::value_type,
00698 typename REF::finder_type> REFV;
00699 return std::auto_ptr<RefVectorHolderBase>(new RefVectorHolder<REFV>);
00700 }
00701 };
00702
00703 template<typename C, typename T, typename F>
00704 struct RefHolderToRefVectorTrait<Ref<C, T, F> > {
00705 typedef RefRefHolderToRefVector<Ref<C, T, F> > type;
00706 };
00707
00708 }
00709 }
00710
00711 #endif