00001 #ifndef DataFormats_Common_Ref_h
00002 #define DataFormats_Common_Ref_h
00003
00004
00005
00006
00007
00008
00009
00010
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
00107
00108 #include "boost/functional.hpp"
00109 #include "boost/call_traits.hpp"
00110 #include "boost/type_traits.hpp"
00111 #include "boost/mpl/has_xxx.hpp"
00112 #include "boost/utility/enable_if.hpp"
00113
00114 #include "DataFormats/Provenance/interface/ProductID.h"
00115 #include "DataFormats/Common/interface/EDProductGetter.h"
00116 #include "DataFormats/Common/interface/EDProductfwd.h"
00117 #include "DataFormats/Common/interface/RefBase.h"
00118 #include "DataFormats/Common/interface/traits.h"
00119 #include "DataFormats/Common/interface/Handle.h"
00120 #include "DataFormats/Common/interface/OrphanHandle.h"
00121 #include "DataFormats/Common/interface/TestHandle.h"
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() : ref_() {}
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 ref_(productID, 0, itemKey, 0, mustBeNonZero(prodGetter, "Ref", productID), false) {
00205 }
00206
00208
00209
00210
00211
00212
00213
00214 Ref(ProductID const& productID, T const* item, key_type item_key, C const* product ) :
00215 ref_(productID, product, item_key, item, 0, false) {
00216 }
00217
00221
00222 explicit Ref(ProductID const& id) :
00223 ref_(id, 0, key_traits<key_type>::value, 0, 0, false)
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
00250 bool isNonnull() const { return ref_.isNonnull(); }
00251
00253 bool operator!() const {return isNull();}
00254
00256 ProductID id() const {return ref_.refCore().id();}
00257
00259 EDProductGetter const* productGetter() const {return ref_.refCore().productGetter();}
00260
00262
00263 C const* product() const;
00264
00266 key_type key() const {return ref_.item().key();}
00267
00268
00269 key_type index() const {return ref_.item().key();}
00270
00272 RefBase<key_type> const& ref() const {return ref_;}
00273
00274 bool hasProductCache() const {return ref_.refCore().productPtr() != 0;}
00275
00276 bool hasCache() const {return ref_.item().ptr() != 0;}
00277
00280 bool isAvailable() const {return ref_.refCore().isAvailable();}
00281
00283 bool isTransient() const {return ref_.refCore().isTransient();}
00284
00285 private:
00286
00287 Ref(RefCore const& refCore, RefItem<key_type> const& item) :
00288 ref_(refCore, item) {
00289 }
00290
00291 private:
00292
00293
00294 void checkTypeAtCompileTime(C const* ptr) {}
00295
00296 RefBase<key_type> ref_;
00297 };
00298 }
00299
00300 #include "DataFormats/Common/interface/RefProd.h"
00301 #include "DataFormats/Common/interface/RefCoreGet.h"
00302 #include "DataFormats/Common/interface/RefItemGet.h"
00303
00304 namespace edm {
00306 template <typename C, typename T, typename F>
00307 inline
00308 Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool setNow) :
00309 ref_(handle.id(), handle.product(), itemKey, 0, 0, false) {
00310 checkTypeAtCompileTime(handle.product());
00311 assert(ref_.item().key() == itemKey);
00312
00313 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00314 }
00315
00317 template <typename C, typename T, typename F>
00318 inline
00319 Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow) :
00320 ref_(handle.id(), handle.product(), itemKey, 0, 0, false) {
00321 checkTypeAtCompileTime(handle.product());
00322 assert(ref_.item().key() == itemKey);
00323
00324 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00325 }
00326
00328 template <typename C, typename T, typename F>
00329 inline
00330 Ref<C, T, F>::Ref(RefVector<C, T, F> const& refvector, key_type itemKey, bool setNow) :
00331 ref_(refvector.id(), refvector.product(), itemKey, 0, 0, refvector.isTransient()) {
00332 checkTypeAtCompileTime(refvector.product());
00333 assert(ref_.item().key() == itemKey);
00334
00335 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00336 }
00337
00339
00340
00341
00342
00343
00344
00345 template <typename C, typename T, typename F>
00346 inline
00347 Ref<C, T, F>::Ref(C const* product, key_type itemKey, bool setNow) :
00348 ref_(ProductID(), product, product != 0 ? itemKey : key_traits<key_type>::value, 0, 0, true) {
00349 checkTypeAtCompileTime(product);
00350 assert(ref_.item().key() == (product != 0 ? itemKey : key_traits<key_type>::value));
00351
00352 if (setNow && product != 0) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00353 }
00354
00356
00357 template <typename C, typename T, typename F>
00358 inline
00359 Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow) :
00360 ref_(handle.id(), handle.product(), itemKey, 0, 0, true) {
00361 checkTypeAtCompileTime(handle.product());
00362 assert(ref_.item().key() == itemKey);
00363
00364 if (setNow) {ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));}
00365 }
00366
00368 template <typename C, typename T, typename F>
00369 inline
00370 Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
00371 ref_(refProd.id(), refProd.refCore().productPtr(), itemKey, 0, refProd.refCore().productGetter(), refProd.refCore().isTransient()) {
00372 assert(ref_.item().key() == itemKey);
00373 if (0 != refProd.refCore().productPtr()) {
00374 ref_.item().setPtr(getPtr_<C, T, F>(ref_.refCore(), ref_.item()));
00375 }
00376 }
00377
00379
00380 template <typename C, typename T, typename F>
00381 inline
00382 C const*
00383 Ref<C, T, F>::product() const {
00384 return isNull() ? 0 : edm::template getProduct<C>(ref_.refCore());
00385 }
00386
00388 template <typename C, typename T, typename F>
00389 inline
00390 T const&
00391 Ref<C, T, F>::operator*() const {
00392 return *getPtr<C, T, F>(ref_.refCore(), ref_.item());
00393 }
00394
00396 template <typename C, typename T, typename F>
00397 inline
00398 T const*
00399 Ref<C, T, F>::operator->() const {
00400 return getPtr<C, T, F>(ref_.refCore(), ref_.item());
00401 }
00402
00403 template <typename C, typename T, typename F>
00404 inline
00405 bool
00406 operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00407 return lhs.ref() == rhs.ref();
00408 }
00409
00410 template <typename C, typename T, typename F>
00411 inline
00412 bool
00413 operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00414 return !(lhs == rhs);
00415 }
00416
00417 template <typename C, typename T, typename F>
00418 inline
00419 bool
00420 operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00423 return (lhs.ref().refCore() == rhs.ref().refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.ref().refCore() < rhs.ref().refCore());
00424 }
00425
00426 }
00427
00428 #include "DataFormats/Common/interface/HolderToVectorTrait.h"
00429 #include "DataFormats/Common/interface/Holder.h"
00430 #include "DataFormats/Common/interface/VectorHolder.h"
00431 #include "DataFormats/Common/interface/RefVector.h"
00432
00433 namespace edm {
00434 namespace reftobase {
00435
00436 template <typename T, typename REF>
00437 struct RefHolderToVector {
00438 static std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() {
00439 typedef RefVector<typename REF::product_type,
00440 typename REF::value_type,
00441 typename REF::finder_type> REFV;
00442 return std::auto_ptr<BaseVectorHolder<T> >( new VectorHolder<T, REFV> );
00443 }
00444 static std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() {
00445 typedef RefVector<typename REF::product_type,
00446 typename REF::value_type,
00447 typename REF::finder_type> REFV;
00448 return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV> );
00449 }
00450 };
00451
00452 template<typename T1, typename C, typename T, typename F>
00453 struct HolderToVectorTrait<T1, Ref<C, T, F> > {
00454 typedef RefHolderToVector<T1, Ref<C, T, F> > type;
00455 };
00456
00457 template <typename REF>
00458 struct RefRefHolderToRefVector {
00459 static std::auto_ptr<RefVectorHolderBase> makeVectorHolder() {
00460 typedef RefVector<typename REF::product_type,
00461 typename REF::value_type,
00462 typename REF::finder_type> REFV;
00463 return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV> );
00464 }
00465 };
00466
00467 template<typename C, typename T, typename F>
00468 struct RefHolderToRefVectorTrait<Ref<C, T, F> > {
00469 typedef RefRefHolderToRefVector<Ref<C, T, F> > type;
00470 };
00471
00472 }
00473 }
00474
00475 #endif