/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DataFormats/Common/interface/FwdRef.h
279 строк
10 KB
Matti Kortelainen
Move stored types in io_v1 namespace, reset class versions to 3
22 май 2026, 18:18
22 май 2026, 18:18
909f324
Код
Авторство
О чём код?
#ifndef DataFormats_Common_FwdRef_h #define DataFormats_Common_FwdRef_h /*---------------------------------------------------------------------- FwdRef: A template for a interproduct reference to a member of a product. ----------------------------------------------------------------------*/ /** \b Summary The edm::FwdRef<> is a storable reference to an item in a stored "forward" container, which also contains a reference to an item in a "backward" container that the "forward" container is derived from. For example, you could use one to hold a reference back to one particular track within a derived std::vector<> of tracks, but you want to keep the original Ref's to the original std::vector<> of tracks (for instance, if you've made a selection on the tracks in the list and want to remove the unnecessary ones from the event). \b Usage The edm::FwdRef<> works just like a pointer \code edm::FwdRef<Foo> fooPtr = ... //set the value functionTakingConstFoo(*fooPtr); //get the Foo object fooPtr->bar(); //call a method of the held Foo object \endcode The main purpose of an edm::FwdRef<> is it can be used as a member datum for a class that is to be stored in the edm::Event where the user can simultaneously check the "backwards" ref as well as the default "forward" ref. \b Customization The edm::FwdRef<> takes three template parameters, and both "forward" and "backward" refs must be the same types: 1) \b C: The type of the container which is holding the item 2) \b T: The type of the item. This defaults to C::value_type 3) \b F: A helper class (a functor) which knows how to find a particular 'T' within the container given an appropriate key. The type of the key is deduced from F::second_argument. The default for F is refhelper::FindTrait<C,T>::value. If no specialization of FindTrait<> is available for the combination (C,T) then it defaults to getting the iterator to be beginning of the container and using std::advance() to move to the appropriate key in the container. It is possible to customize the 'lookup' algorithm used. 1) The helper class F must provide `value_type`, `first_argument_type` and `second_argument_type` typedefs. 2) The helper class F must define the function call operator in such a way that the following call is well-formed: // f is an instance of type F // coll is an instance of type C // k is an instance of type F::key_type result_type r = f(coll,k); If one wishes to make a specialized lookup the default lookup for the container/type pair then one needs to partially specialize the templated class edm::refhelper::FindTrait<C,T> such that it has a typedef named 'value' which refers to the specialized helper class (i.e., F) The class template FwdRef<C,T,F> supports 'null' references. -- a default-constructed FwdRef is 'null'; furthermore, it also has an invalid (or 'null') ProductID. -- a FwdRef constructed through the single-arguement constructor that takes a ProductID is also null. */ /*---------------------------------------------------------------------- // This defines the public interface to the class FwdRef<C, T, F>. // C is the collection type. // T (default C::value_type) is the type of an element in the collection. // // ProductID productID is the product ID of the collection. // key_type itemKey is the key of the element in the collection. // C::value_type *itemPtr is a C++ pointer to the element // FwdRef<C, T, F> const& ref is another FwdRef<C, T, F> // Constructors FwdRef(); // Default constructor FwdRef(FwdRef<C, T> const& ref); // Copy constructor (default, not explicitly specified) FwdRef(Ref<C,T,F> const & fwdRef, Ref<C,T,F> const & backRef); // Destructor virtual ~FwdRef() {} // Operators and methods FwdRef<C, T>& operator=(FwdRef<C, T> const&); // assignment (default, not explicitly specified) T const& operator*() const; // dereference T const* const operator->() const; // member dereference bool operator==(FwdRef<C, T> const& ref) const; // equality bool operator!=(FwdRef<C, T> const& ref) const; // inequality bool operator<(FwdRef<C, T> const& ref) const; // ordering bool isNonnull() const; // true if an object is referenced bool isNull() const; // equivalent to !isNonnull() bool operator!() const; // equivalent to !isNonnull() ----------------------------------------------------------------------*/ #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" #include "DataFormats/Common/interface/Ref.h" #include <boost/functional.hpp> namespace edm { template <typename C, typename T = typename refhelper::ValueTrait<C>::value, typename F = typename refhelper::FindTrait<C, T>::value> class FwdRef { public: /// for export typedef C product_type; typedef T value_type; typedef T const element_type; //used for generic programming typedef F finder_type; typedef typename boost::binary_traits<F>::second_argument_type argument_type; typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type; /// C is the type of the collection /// T is the type of a member the collection /// Default constructor needed for reading from persistent store. Not for direct use. FwdRef() : ref_(), backRef_() {} /// General purpose constructor from 2 refs (forward and backward. FwdRef(Ref<C, T, F> const& ref, Ref<C, T, F> const& backRef) : ref_(ref), backRef_(backRef) { assert(ref.isNull() == backRef.isNull()); } /// Destructor ~FwdRef() {} /// Dereference operator T const& operator*() const; /// Member dereference operator T const* operator->() const; /// Returns C++ pointer to the item T const* get() const { if (ref_.isAvailable()) { return ref_.get(); } else { return backRef_.get(); } } /// Checks for null bool isNull() const { return !isNonnull(); } /// Checks for non-null //bool isNonnull() const {return id().isValid(); } bool isNonnull() const { return ref_.isNonnull() || backRef_.isNonnull(); } /// Checks for null bool operator!() const { return isNull(); } Ref<C, T, F> const& ref() const { return ref_; } Ref<C, T, F> const& backRef() const { return backRef_; } /// Accessor for product getter. EDProductGetter const* productGetter() const { //another thread might cause productGetter() to change its value EDProductGetter const* getter = ref_.productGetter(); if (getter) return getter; else return backRef_.productGetter(); } /// Accessor for product ID. ProductID id() const { return ref_.isNonnull() ? ref_.id() : backRef_.id(); } /// Accessor for product key. key_type key() const { return ref_.isNonnull() ? ref_.key() : backRef_.key(); } bool hasProductCache() const { return ref_.hasProductCache() || backRef_.hasProductCache(); } /// Checks if collection is in memory or available /// in the Event. No type checking is done. bool isAvailable() const { return ref_.isAvailable() || backRef_.isAvailable(); } /// Checks if this ref is transient (i.e. not persistable). bool isTransient() const { return ref_.isTransient(); } //Used by ROOT storage CMS_CLASS_VERSION(3) private: Ref<C, T, F> ref_; Ref<C, T, F> backRef_; }; } // namespace edm #include "DataFormats/Common/interface/RefProd.h" namespace edm { /// Dereference operator template <typename C, typename T, typename F> inline T const& FwdRef<C, T, F>::operator*() const { return ref_.isNonnull() && ref_.isAvailable() ? ref_.operator*() : backRef_.operator*(); } /// Member dereference operator template <typename C, typename T, typename F> inline T const* FwdRef<C, T, F>::operator->() const { return ref_.isNonnull() && ref_.isAvailable() ? ref_.operator->() : backRef_.operator->(); } /// for two FwdRefs to be equal, both the /// "forward" and the "backward" Refs must be the same template <typename C, typename T, typename F> inline bool operator==(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return (lhs.ref() == rhs.ref()) && (lhs.backRef() == rhs.backRef()); } /// for a FwdRef to equal a Ref, EITHER the /// "forward" or the "backward" Refs must equal to the test ref template <typename C, typename T, typename F> inline bool operator==(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return (lhs == rhs.ref()) || (lhs == rhs.backRef()); } /// for a FwdRef to equal a Ref, EITHER the /// "forward" or the "backward" Refs must equal to the test ref template <typename C, typename T, typename F> inline bool operator==(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { return (lhs.ref() == rhs) || (lhs.backRef() == rhs); } template <typename C, typename T, typename F> inline bool operator!=(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return !(lhs == rhs); } template <typename C, typename T, typename F> inline bool operator!=(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return !(lhs == rhs); } template <typename C, typename T, typename F> inline bool operator!=(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { return !(lhs == rhs); } /// for inequality operators, ONLY test the forward ref. /// the ordering of the backward ref is not relevant. template <typename C, typename T, typename F> inline bool operator<(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return (lhs.ref() < rhs.ref()); } template <typename C, typename T, typename F> inline bool operator<(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { return (lhs < rhs.ref()); } template <typename C, typename T, typename F> inline bool operator<(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { return (lhs.ref() < rhs); } } // namespace edm #endif