|
||||
File indexing completed on 2024-04-06 12:03:51
0001 #ifndef DataFormats_Common_FwdRef_h 0002 #define DataFormats_Common_FwdRef_h 0003 0004 /*---------------------------------------------------------------------- 0005 0006 FwdRef: A template for a interproduct reference to a member of a product. 0007 0008 ----------------------------------------------------------------------*/ 0009 /** 0010 \b Summary 0011 0012 The edm::FwdRef<> is a storable reference to an item in a stored 0013 "forward" container, which also contains a reference to an item in a 0014 "backward" container that the "forward" container is derived from. 0015 0016 For example, you could use one to hold a reference back 0017 to one particular track within a derived std::vector<> of tracks, 0018 but you want to keep the original Ref's to the original 0019 std::vector<> of tracks (for instance, if you've made a selection 0020 on the tracks in the list and want to remove the unnecessary ones 0021 from the event). 0022 0023 \b Usage 0024 0025 The edm::FwdRef<> works just like a pointer 0026 \code 0027 edm::FwdRef<Foo> fooPtr = ... //set the value 0028 functionTakingConstFoo(*fooPtr); //get the Foo object 0029 fooPtr->bar(); //call a method of the held Foo object 0030 \endcode 0031 0032 The main purpose of an edm::FwdRef<> is it can be used as a member 0033 datum for a class that is to be stored in the edm::Event where the 0034 user can simultaneously check the "backwards" ref as well as the 0035 default "forward" ref. 0036 0037 \b Customization 0038 0039 The edm::FwdRef<> takes three template parameters, and both 0040 "forward" and "backward" refs must be the same types: 0041 0042 1) \b C: The type of the container which is holding the item 0043 0044 2) \b T: The type of the item. This defaults to C::value_type 0045 0046 3) \b F: A helper class (a functor) which knows how to find a 0047 particular 'T' within the container given an appropriate key. The 0048 type of the key is deduced from F::second_argument. The default 0049 for F is refhelper::FindTrait<C,T>::value. If no specialization 0050 of FindTrait<> is available for the combination (C,T) then it 0051 defaults to getting the iterator to be beginning of the container 0052 and using std::advance() to move to the appropriate key in the 0053 container. 0054 0055 It is possible to customize the 'lookup' algorithm used. 0056 0057 1) The helper class F must provide `value_type`, 0058 `first_argument_type` and `second_argument_type` typedefs. 0059 0060 2) The helper class F must define the function call operator in 0061 such a way that the following call is well-formed: 0062 // f is an instance of type F 0063 // coll is an instance of type C 0064 // k is an instance of type F::key_type 0065 0066 result_type r = f(coll,k); 0067 0068 If one wishes to make a specialized lookup the default lookup for 0069 the container/type pair then one needs to partially specialize 0070 the templated class edm::refhelper::FindTrait<C,T> such that it 0071 has a typedef named 'value' which refers to the specialized 0072 helper class (i.e., F) 0073 0074 The class template FwdRef<C,T,F> supports 'null' references. 0075 0076 -- a default-constructed FwdRef is 'null'; furthermore, it also 0077 has an invalid (or 'null') ProductID. 0078 -- a FwdRef constructed through the single-arguement constructor 0079 that takes a ProductID is also null. 0080 */ 0081 0082 /*---------------------------------------------------------------------- 0083 // This defines the public interface to the class FwdRef<C, T, F>. 0084 // C is the collection type. 0085 // T (default C::value_type) is the type of an element in the collection. 0086 // 0087 // ProductID productID is the product ID of the collection. 0088 // key_type itemKey is the key of the element in the collection. 0089 // C::value_type *itemPtr is a C++ pointer to the element 0090 // FwdRef<C, T, F> const& ref is another FwdRef<C, T, F> 0091 0092 // Constructors 0093 FwdRef(); // Default constructor 0094 FwdRef(FwdRef<C, T> const& ref); // Copy constructor (default, not explicitly specified) 0095 0096 FwdRef(Ref<C,T,F> const & fwdRef, Ref<C,T,F> const & backRef); 0097 0098 // Destructor 0099 virtual ~FwdRef() {} 0100 0101 // Operators and methods 0102 FwdRef<C, T>& operator=(FwdRef<C, T> const&); // assignment (default, not explicitly specified) 0103 T const& operator*() const; // dereference 0104 T const* const operator->() const; // member dereference 0105 bool operator==(FwdRef<C, T> const& ref) const; // equality 0106 bool operator!=(FwdRef<C, T> const& ref) const; // inequality 0107 bool operator<(FwdRef<C, T> const& ref) const; // ordering 0108 bool isNonnull() const; // true if an object is referenced 0109 bool isNull() const; // equivalent to !isNonnull() 0110 bool operator!() const; // equivalent to !isNonnull() 0111 ----------------------------------------------------------------------*/ 0112 0113 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" 0114 #include "DataFormats/Common/interface/Ref.h" 0115 0116 #include <boost/functional.hpp> 0117 0118 namespace edm { 0119 0120 template <typename C, 0121 typename T = typename refhelper::ValueTrait<C>::value, 0122 typename F = typename refhelper::FindTrait<C, T>::value> 0123 class FwdRef { 0124 public: 0125 /// for export 0126 typedef C product_type; 0127 typedef T value_type; 0128 typedef T const element_type; //used for generic programming 0129 typedef F finder_type; 0130 typedef typename boost::binary_traits<F>::second_argument_type argument_type; 0131 typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type; 0132 /// C is the type of the collection 0133 /// T is the type of a member the collection 0134 0135 /// Default constructor needed for reading from persistent store. Not for direct use. 0136 FwdRef() : ref_(), backRef_() {} 0137 0138 /// General purpose constructor from 2 refs (forward and backward. 0139 FwdRef(Ref<C, T, F> const& ref, Ref<C, T, F> const& backRef) : ref_(ref), backRef_(backRef) { 0140 assert(ref.isNull() == backRef.isNull()); 0141 } 0142 0143 /// Destructor 0144 ~FwdRef() {} 0145 0146 /// Dereference operator 0147 T const& operator*() const; 0148 0149 /// Member dereference operator 0150 T const* operator->() const; 0151 0152 /// Returns C++ pointer to the item 0153 T const* get() const { 0154 if (ref_.isAvailable()) { 0155 return ref_.get(); 0156 } else { 0157 return backRef_.get(); 0158 } 0159 } 0160 0161 /// Checks for null 0162 bool isNull() const { return !isNonnull(); } 0163 0164 /// Checks for non-null 0165 //bool isNonnull() const {return id().isValid(); } 0166 bool isNonnull() const { return ref_.isNonnull() || backRef_.isNonnull(); } 0167 0168 /// Checks for null 0169 bool operator!() const { return isNull(); } 0170 0171 Ref<C, T, F> const& ref() const { return ref_; } 0172 Ref<C, T, F> const& backRef() const { return backRef_; } 0173 0174 /// Accessor for product getter. 0175 EDProductGetter const* productGetter() const { 0176 //another thread might cause productGetter() to change its value 0177 EDProductGetter const* getter = ref_.productGetter(); 0178 if (getter) 0179 return getter; 0180 else 0181 return backRef_.productGetter(); 0182 } 0183 0184 /// Accessor for product ID. 0185 ProductID id() const { return ref_.isNonnull() ? ref_.id() : backRef_.id(); } 0186 0187 /// Accessor for product key. 0188 key_type key() const { return ref_.isNonnull() ? ref_.key() : backRef_.key(); } 0189 0190 bool hasProductCache() const { return ref_.hasProductCache() || backRef_.hasProductCache(); } 0191 0192 /// Checks if collection is in memory or available 0193 /// in the Event. No type checking is done. 0194 bool isAvailable() const { return ref_.isAvailable() || backRef_.isAvailable(); } 0195 0196 /// Checks if this ref is transient (i.e. not persistable). 0197 bool isTransient() const { return ref_.isTransient(); } 0198 0199 //Used by ROOT storage 0200 CMS_CLASS_VERSION(10) 0201 0202 private: 0203 Ref<C, T, F> ref_; 0204 Ref<C, T, F> backRef_; 0205 }; 0206 } // namespace edm 0207 0208 #include "DataFormats/Common/interface/RefProd.h" 0209 0210 namespace edm { 0211 0212 /// Dereference operator 0213 template <typename C, typename T, typename F> 0214 inline T const& FwdRef<C, T, F>::operator*() const { 0215 return ref_.isNonnull() && ref_.isAvailable() ? ref_.operator*() : backRef_.operator*(); 0216 } 0217 0218 /// Member dereference operator 0219 template <typename C, typename T, typename F> 0220 inline T const* FwdRef<C, T, F>::operator->() const { 0221 return ref_.isNonnull() && ref_.isAvailable() ? ref_.operator->() : backRef_.operator->(); 0222 } 0223 0224 /// for two FwdRefs to be equal, both the 0225 /// "forward" and the "backward" Refs must be the same 0226 template <typename C, typename T, typename F> 0227 inline bool operator==(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0228 return (lhs.ref() == rhs.ref()) && (lhs.backRef() == rhs.backRef()); 0229 } 0230 0231 /// for a FwdRef to equal a Ref, EITHER the 0232 /// "forward" or the "backward" Refs must equal to the test ref 0233 template <typename C, typename T, typename F> 0234 inline bool operator==(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0235 return (lhs == rhs.ref()) || (lhs == rhs.backRef()); 0236 } 0237 0238 /// for a FwdRef to equal a Ref, EITHER the 0239 /// "forward" or the "backward" Refs must equal to the test ref 0240 template <typename C, typename T, typename F> 0241 inline bool operator==(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { 0242 return (lhs.ref() == rhs) || (lhs.backRef() == rhs); 0243 } 0244 0245 template <typename C, typename T, typename F> 0246 inline bool operator!=(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0247 return !(lhs == rhs); 0248 } 0249 0250 template <typename C, typename T, typename F> 0251 inline bool operator!=(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0252 return !(lhs == rhs); 0253 } 0254 0255 template <typename C, typename T, typename F> 0256 inline bool operator!=(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { 0257 return !(lhs == rhs); 0258 } 0259 0260 /// for inequality operators, ONLY test the forward ref. 0261 /// the ordering of the backward ref is not relevant. 0262 template <typename C, typename T, typename F> 0263 inline bool operator<(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0264 return (lhs.ref() < rhs.ref()); 0265 } 0266 0267 template <typename C, typename T, typename F> 0268 inline bool operator<(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) { 0269 return (lhs < rhs.ref()); 0270 } 0271 0272 template <typename C, typename T, typename F> 0273 inline bool operator<(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) { 0274 return (lhs.ref() < rhs); 0275 } 0276 0277 } // namespace edm 0278 0279 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.2.1 LXR engine. The LXR team |