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/TestHandle.h"
00114 #include "DataFormats/Common/interface/traits.h"
00115 #include "DataFormats/Provenance/interface/ProductID.h"
00116
00117 #include "boost/functional.hpp"
00118 #include "boost/call_traits.hpp"
00119 #include "boost/type_traits.hpp"
00120 #include "boost/mpl/has_xxx.hpp"
00121 #include "boost/utility/enable_if.hpp"
00122
00123 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
00124
00125 template <typename C, typename K>
00126 typename boost::enable_if<has_key_compare<C>, bool>::type
00127 compare_key(K const& lhs, K const& rhs) {
00128 typedef typename C::key_compare comparison_functor;
00129 return comparison_functor()(lhs, rhs);
00130 }
00131
00132 template <typename C, typename K>
00133 typename boost::disable_if<has_key_compare<C>, bool>::type
00134 compare_key(K const& lhs, K const& rhs) {
00135 return lhs < rhs;
00136 }
00137
00138 #include "DataFormats/Common/interface/RefTraits.h"
00139
00140 namespace edm {
00141 template<typename C, typename T, typename F>
00142 class RefVector;
00143
00144 template<typename T>
00145 class RefToBaseVector;
00146
00147 template <typename C,
00148 typename T = typename refhelper::ValueTrait<C>::value,
00149 typename F = typename refhelper::FindTrait<C, T>::value>
00150 class Ref {
00151 private:
00152 typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F> > VF;
00153 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T> > VBF;
00154 friend class RefVectorIterator<C, T, F>;
00155 friend class RefVector<C, T, F>;
00156 friend class RefVector<RefVector<C, T, F>, T, VF>;
00157 friend class RefVector<RefVector<RefVector<C, T, F>, T, VF>, T, VF>;
00158 friend class RefVector<RefVector<C, T, F>, T, VBF>;
00159 friend class RefVector<RefVector<RefVector<C, T, F>, T, VBF>, T, VBF>;
00161
00162 public:
00164 typedef C product_type;
00165 typedef T value_type;
00166 typedef T const element_type;
00167 typedef F finder_type;
00168 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00169 typedef typename boost::remove_cv<typename boost::remove_reference<argument_type>::type>::type key_type;
00172
00174 Ref() : product_(), index_(key_traits<key_type>::value) {}
00175
00177 Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
00178
00180 Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
00181
00183
00184
00185
00186 Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow=true);
00187
00189
00190
00191
00192
00193 Ref(C const* product, key_type itemKey, bool setNow=true);
00194
00196
00197
00198 Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
00199
00203 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
00204 product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {
00205 }
00206
00208
00209
00210
00211
00212
00213
00214 Ref(ProductID const& iProductID, T const* , key_type iItemKey, C const* iProduct) :
00215 product_(iProductID, iProduct, 0, false), index_(iItemKey)
00216 { }
00217
00221
00222 explicit Ref(ProductID const& iId) :
00223 product_(iId, 0, 0, false), index_(key_traits<key_type>::value)
00224 { }
00225
00227 Ref(RefProd<C> const& refProd, key_type itemKey);
00228
00230 ~Ref() {}
00231
00233 T const&
00234 operator*() const;
00235
00237 T const*
00238 operator->() const;
00239
00241 T const* get() const {
00242 return isNull() ? 0 : this->operator->();
00243 }
00244
00246 bool isNull() const {return !isNonnull(); }
00247
00249 bool isNonnull() const { return index_!=edm::key_traits<key_type>::value; }
00250
00252 bool operator!() const {return isNull();}
00253
00255 ProductID id() const {return product_.id();}
00256
00258 EDProductGetter const* productGetter() const {return product_.productGetter();}
00259
00261
00262 C const* product() const;
00263
00265 key_type key() const {return index_;}
00266
00267
00268 key_type index() const {return index_;}
00269
00271 bool hasProductCache() const {return product_.productPtr() != 0;}
00272
00275 bool isAvailable() const {return product_.isAvailable();}
00276
00278 bool isTransient() const {return product_.isTransient();}
00279
00280 RefCore const& refCore() const {return product_;}
00281
00282
00283 CMS_CLASS_VERSION(10)
00284
00285
00286 Ref(RefCore const& iRefCore, key_type const& iKey) :
00287 product_(iRefCore), index_(iKey) {
00288 }
00289
00290 private:
00291
00292
00293 void checkTypeAtCompileTime(C const*) {}
00294
00295 mutable RefCore product_;
00296 key_type index_;
00297
00298 };
00299 }
00300
00301 #include "DataFormats/Common/interface/RefProd.h"
00302 #include "DataFormats/Common/interface/RefCoreGet.h"
00303 #include "DataFormats/Common/interface/RefItemGet.h"
00304
00305 namespace edm {
00307 template <typename C, typename T, typename F>
00308 inline
00309 Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool setNow) :
00310 product_(handle.id(), handle.product(), 0, false), index_(itemKey){
00311 checkTypeAtCompileTime(handle.product());
00312 assert(key() == itemKey);
00313
00314 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00315 }
00316
00318 template <typename C, typename T, typename F>
00319 inline
00320 Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow) :
00321 product_(handle.id(), handle.product(), 0, false), index_(itemKey) {
00322 checkTypeAtCompileTime(handle.product());
00323 assert(key() == itemKey);
00324
00325 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00326 }
00327
00329 template <typename C, typename T, typename F>
00330 inline
00331 Ref<C, T, F>::Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow) :
00332 product_(refvector.id(), refvector.product(), 0, refvector.isTransient()), index_(itemKey) {
00333 checkTypeAtCompileTime(refvector.product());
00334 assert(key() == itemKey);
00335
00336 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00337 }
00338
00340
00341
00342
00343
00344
00345
00346 template <typename C, typename T, typename F>
00347 inline
00348 Ref<C, T, F>::Ref(C const* iProduct, key_type iItemKey, bool iSetNow) :
00349 product_(ProductID(), iProduct, 0, true), index_(iProduct != 0 ? iItemKey : key_traits<key_type>::value) {
00350 checkTypeAtCompileTime(iProduct);
00351 assert(key() == (iProduct != 0 ? iItemKey : key_traits<key_type>::value));
00352
00353 if (iSetNow && iProduct != 0) {getPtr_<C, T, F>(product_, index_);}
00354 }
00355
00357
00358 template <typename C, typename T, typename F>
00359 inline
00360 Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow) :
00361 product_(handle.id(), handle.product(), 0, true), index_(itemKey) {
00362 checkTypeAtCompileTime(handle.product());
00363 assert(key() == itemKey);
00364
00365 if (setNow) {getPtr_<C, T, F>(product_, index_);}
00366 }
00367
00369 template <typename C, typename T, typename F>
00370 inline
00371 Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
00372 product_(refProd.id(), refProd.refCore().productPtr(), refProd.refCore().productGetter(), refProd.refCore().isTransient()), index_(itemKey) {
00373 assert(index() == itemKey);
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>(product_);
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>(product_, index_);
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>(product_, index_);
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.key() == rhs.key() && lhs.refCore() == rhs.refCore() ;
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.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.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