|
||||
File indexing completed on 2024-04-06 12:13:13
0001 #ifndef FWCore_Utilities_value_ptr_h 0002 #define FWCore_Utilities_value_ptr_h 0003 0004 // ---------------------------------------------------------------------- 0005 // 0006 // value_ptr.h - Smart pointer permitting copying of pointed-to object. 0007 // 0008 // Purpose: value_ptr provides a smart pointer template that provides 0009 // sole ownership of the pointed-to object. When a value_ptr object is 0010 // copied, the new value_ptr object is given a copy of the object pointed 0011 // to by the original value_ptr object. 0012 // 0013 // The value_ptr_traits template is provided to allow specialization 0014 // of the copying behavior. See the notes below. 0015 // 0016 // Use value_ptr only when deep-copying of the pointed-to object 0017 // is desireable. Use std::shared_ptr when sharing of the 0018 // pointed-to object is desirable. Use std::unique_ptr 0019 // when no copying is desirable. 0020 // 0021 // The design of value_ptr is taken from Herb Sutter's More 0022 // Exceptional C++, with modifications by Marc Paterno and further 0023 // modifications by Walter Brown. This version is based on the 0024 // ValuePtr found in the Fermilab ZOOM library. 0025 // 0026 // 0027 // Supports the following syntax 0028 // value_ptr<T> ptr(...); 0029 // if (ptr) { ... 0030 // Where the conditional will evaluate as true if and only if the 0031 // pointer the value_ptr contains is not null. 0032 // 0033 // ---------------------------------------------------------------------- 0034 0035 #include <algorithm> // for std::swap() 0036 #include <memory> 0037 #include "FWCore/Utilities/interface/get_underlying_safe.h" 0038 #include "FWCore/Utilities/interface/propagate_const.h" 0039 0040 namespace edm { 0041 0042 // -------------------------------------------------------------------- 0043 // 0044 // Auxiliary traits class template providing default clone() 0045 // Users should specialize this template for types that have their 0046 // own self-copy operations; failure to do so may lead to slicing! 0047 // 0048 // -------------------------------------------------------------------- 0049 0050 template <typename T> 0051 struct value_ptr_traits { 0052 static T* clone(T const* p) { return new T(*p); } 0053 static void destroy(T* p) { delete p; } 0054 }; 0055 0056 // -------------------------------------------------------------------- 0057 // 0058 // Copyable smart pointer class template 0059 // 0060 // -------------------------------------------------------------------- 0061 0062 template <typename T> 0063 class value_ptr { 0064 public: 0065 // -------------------------------------------------- 0066 // Default constructor/destructor: 0067 // -------------------------------------------------- 0068 0069 value_ptr() : myP(nullptr) {} 0070 explicit value_ptr(T* p) : myP(p) {} 0071 ~value_ptr() { value_ptr_traits<T>::destroy(myP.get()); } 0072 0073 // -------------------------------------------------- 0074 // Copy constructor/copy assignment: 0075 // -------------------------------------------------- 0076 0077 value_ptr(value_ptr const& orig) : myP(createFrom(get_underlying_safe(orig.myP))) {} 0078 0079 value_ptr& operator=(value_ptr const& orig) { 0080 value_ptr<T> temp(orig); 0081 swap(temp); 0082 return *this; 0083 } 0084 0085 // -------------------------------------------------- 0086 // Move constructor/move assignment: 0087 // -------------------------------------------------- 0088 0089 value_ptr(value_ptr&& orig) : myP(orig.myP) { orig.myP = nullptr; } 0090 0091 value_ptr& operator=(value_ptr&& orig) { 0092 if (myP != orig.myP) { 0093 delete myP.get(); 0094 myP = orig.myP; 0095 orig.myP = nullptr; 0096 } 0097 return *this; 0098 } 0099 0100 // -------------------------------------------------- 0101 // Access mechanisms: 0102 // -------------------------------------------------- 0103 0104 T const& operator*() const { return *myP; } 0105 T& operator*() { return *myP; } 0106 T const* operator->() const { return get_underlying_safe(myP); } 0107 T* operator->() { return get_underlying_safe(myP); } 0108 0109 // -------------------------------------------------- 0110 // Manipulation: 0111 // -------------------------------------------------- 0112 0113 void swap(value_ptr& orig) { std::swap(myP, orig.myP); } 0114 0115 // -------------------------------------------------- 0116 // Copy-like construct/assign from compatible value_ptr<>: 0117 // -------------------------------------------------- 0118 0119 template <typename U> 0120 value_ptr(value_ptr<U> const& orig) : myP(createFrom(orig.operator->())) {} 0121 0122 template <typename U> 0123 value_ptr& operator=(value_ptr<U> const& orig) { 0124 value_ptr<T> temp(orig); 0125 swap(temp); 0126 return *this; 0127 } 0128 0129 // -------------------------------------------------- 0130 // Move-like construct/assign from unique_ptr<>: 0131 // -------------------------------------------------- 0132 0133 value_ptr(std::unique_ptr<T> orig) : myP(orig.release()) { orig = nullptr; } 0134 0135 value_ptr& operator=(std::unique_ptr<T> orig) { 0136 value_ptr<T> temp(std::move(orig)); 0137 swap(temp); 0138 return *this; 0139 } 0140 0141 // The following typedef, function, and operator definition 0142 // support the following syntax: 0143 // value_ptr<T> ptr(..); 0144 // if (ptr) { ... 0145 // Where the conditional will evaluate as true if and only if the 0146 // pointer value_ptr contains is not null. 0147 private: 0148 typedef void (value_ptr::*bool_type)() const; 0149 void this_type_does_not_support_comparisons() const {} 0150 0151 public: 0152 operator bool_type() const { 0153 return myP != nullptr ? &value_ptr<T>::this_type_does_not_support_comparisons : nullptr; 0154 } 0155 0156 private: 0157 // -------------------------------------------------- 0158 // Implementation aid: 0159 // -------------------------------------------------- 0160 0161 template <typename U> 0162 static T* createFrom(U const* p) { 0163 return p ? value_ptr_traits<U>::clone(p) : nullptr; 0164 } 0165 0166 // -------------------------------------------------- 0167 // Member data: 0168 // -------------------------------------------------- 0169 0170 edm::propagate_const<T*> myP; 0171 0172 }; // value_ptr 0173 0174 // -------------------------------------------------------------------- 0175 // 0176 // Free-standing swap() 0177 // 0178 // -------------------------------------------------------------------- 0179 0180 template <typename T> 0181 inline void swap(value_ptr<T>& vp1, value_ptr<T>& vp2) { 0182 vp1.swap(vp2); 0183 } 0184 0185 // Do not allow nonsensical comparisons that the bool_type 0186 // conversion operator definition above would otherwise allow. 0187 // The function call inside the next 4 operator definitions is 0188 // private, so compilation will fail if there is an attempt to 0189 // instantiate these 4 operators. 0190 template <typename T, typename U> 0191 inline bool operator==(value_ptr<T> const& lhs, U const& rhs) { 0192 lhs.this_type_does_not_support_comparisons(); 0193 return false; 0194 } 0195 0196 template <typename T, typename U> 0197 inline bool operator!=(value_ptr<T> const& lhs, U const& rhs) { 0198 lhs.this_type_does_not_support_comparisons(); 0199 return false; 0200 } 0201 0202 template <typename T, typename U> 0203 inline bool operator==(U const& lhs, value_ptr<T> const& rhs) { 0204 rhs.this_type_does_not_support_comparisons(); 0205 return false; 0206 } 0207 0208 template <typename T, typename U> 0209 inline bool operator!=(U const& lhs, value_ptr<T> const& rhs) { 0210 rhs.this_type_does_not_support_comparisons(); 0211 return false; 0212 } 0213 } // namespace edm 0214 0215 #endif // FWCoreUtilities_value_ptr_h
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.2.1 LXR engine. The LXR team |