CMS 3D CMS Logo

value_ptr.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_value_ptr_h
2 #define FWCore_Utilities_value_ptr_h
3 
4 // ----------------------------------------------------------------------
5 //
6 // value_ptr.h - Smart pointer permitting copying of pointed-to object.
7 //
8 // Purpose: value_ptr provides a smart pointer template that provides
9 // sole ownership of the pointed-to object. When a value_ptr object is
10 // copied, the new value_ptr object is given a copy of the object pointed
11 // to by the original value_ptr object.
12 //
13 // The value_ptr_traits template is provided to allow specialization
14 // of the copying behavior. See the notes below.
15 //
16 // Use value_ptr only when deep-copying of the pointed-to object
17 // is desireable. Use std::shared_ptr when sharing of the
18 // pointed-to object is desirable. Use std::unique_ptr
19 // when no copying is desirable.
20 //
21 // The design of value_ptr is taken from Herb Sutter's More
22 // Exceptional C++, with modifications by Marc Paterno and further
23 // modifications by Walter Brown. This version is based on the
24 // ValuePtr found in the Fermilab ZOOM library.
25 //
26 //
27 // Supports the following syntax
28 // value_ptr<T> ptr(...);
29 // if (ptr) { ...
30 // Where the conditional will evaluate as true if and only if the
31 // pointer the value_ptr contains is not null.
32 //
33 // ----------------------------------------------------------------------
34 
35 #include <algorithm> // for std::swap()
36 #include <memory>
39 
40 namespace edm {
41 
42  // --------------------------------------------------------------------
43  //
44  // Auxiliary traits class template providing default clone()
45  // Users should specialize this template for types that have their
46  // own self-copy operations; failure to do so may lead to slicing!
47  //
48  // --------------------------------------------------------------------
49 
50  template <typename T>
52  static T* clone(T const* p) { return new T(*p); }
53  static void destroy(T* p) { delete p; }
54  };
55 
56  // --------------------------------------------------------------------
57  //
58  // Copyable smart pointer class template
59  //
60  // --------------------------------------------------------------------
61 
62  template <typename T>
63  class value_ptr {
64  public:
65  // --------------------------------------------------
66  // Default constructor/destructor:
67  // --------------------------------------------------
68 
69  value_ptr() : myP(nullptr) {}
70  explicit value_ptr(T* p) : myP(p) {}
72 
73  // --------------------------------------------------
74  // Copy constructor/copy assignment:
75  // --------------------------------------------------
76 
78 
79  value_ptr& operator=(value_ptr const& orig) {
80  value_ptr<T> temp(orig);
81  swap(temp);
82  return *this;
83  }
84 
85  // --------------------------------------------------
86  // Move constructor/move assignment:
87  // --------------------------------------------------
88 
89  value_ptr(value_ptr&& orig) : myP(orig.myP) { orig.myP = nullptr; }
90 
92  if (myP != orig.myP) {
93  delete myP.get();
94  myP = orig.myP;
95  orig.myP = nullptr;
96  }
97  return *this;
98  }
99 
100  // --------------------------------------------------
101  // Access mechanisms:
102  // --------------------------------------------------
103 
104  T const& operator*() const { return *myP; }
105  T& operator*() { return *myP; }
106  T const* operator->() const { return get_underlying_safe(myP); }
108 
109  // --------------------------------------------------
110  // Manipulation:
111  // --------------------------------------------------
112 
113  void swap(value_ptr& orig) { std::swap(myP, orig.myP); }
114 
115  // --------------------------------------------------
116  // Copy-like construct/assign from compatible value_ptr<>:
117  // --------------------------------------------------
118 
119  template <typename U>
120  value_ptr(value_ptr<U> const& orig) : myP(createFrom(orig.operator->())) {}
121 
122  template <typename U>
124  value_ptr<T> temp(orig);
125  swap(temp);
126  return *this;
127  }
128 
129  // --------------------------------------------------
130  // Move-like construct/assign from unique_ptr<>:
131  // --------------------------------------------------
132 
133  value_ptr(std::unique_ptr<T> orig) : myP(orig.release()) { orig = nullptr; }
134 
135  value_ptr& operator=(std::unique_ptr<T> orig) {
136  value_ptr<T> temp(std::move(orig));
137  swap(temp);
138  return *this;
139  }
140 
141  // The following typedef, function, and operator definition
142  // support the following syntax:
143  // value_ptr<T> ptr(..);
144  // if (ptr) { ...
145  // Where the conditional will evaluate as true if and only if the
146  // pointer value_ptr contains is not null.
147  private:
148  typedef void (value_ptr::*bool_type)() const;
150 
151  public:
152  operator bool_type() const {
153  return myP != nullptr ? &value_ptr<T>::this_type_does_not_support_comparisons : nullptr;
154  }
155 
156  private:
157  // --------------------------------------------------
158  // Implementation aid:
159  // --------------------------------------------------
160 
161  template <typename U>
162  static T* createFrom(U const* p) {
163  return p ? value_ptr_traits<U>::clone(p) : nullptr;
164  }
165 
166  // --------------------------------------------------
167  // Member data:
168  // --------------------------------------------------
169 
171 
172  }; // value_ptr
173 
174  // --------------------------------------------------------------------
175  //
176  // Free-standing swap()
177  //
178  // --------------------------------------------------------------------
179 
180  template <typename T>
181  inline void swap(value_ptr<T>& vp1, value_ptr<T>& vp2) {
182  vp1.swap(vp2);
183  }
184 
185  // Do not allow nonsensical comparisons that the bool_type
186  // conversion operator definition above would otherwise allow.
187  // The function call inside the next 4 operator definitions is
188  // private, so compilation will fail if there is an attempt to
189  // instantiate these 4 operators.
190  template <typename T, typename U>
191  inline bool operator==(value_ptr<T> const& lhs, U const& rhs) {
193  return false;
194  }
195 
196  template <typename T, typename U>
197  inline bool operator!=(value_ptr<T> const& lhs, U const& rhs) {
199  return false;
200  }
201 
202  template <typename T, typename U>
203  inline bool operator==(U const& lhs, value_ptr<T> const& rhs) {
205  return false;
206  }
207 
208  template <typename T, typename U>
209  inline bool operator!=(U const& lhs, value_ptr<T> const& rhs) {
211  return false;
212  }
213 } // namespace edm
214 
215 #endif // FWCoreUtilities_value_ptr_h
propagate_const.h
edm
HLT enums.
Definition: AlignableModifier.h:19
edm::value_ptr::bool_type
void(value_ptr::* bool_type)() const
Definition: value_ptr.h:148
edm::swap
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
edm::propagate_const::get
constexpr element_type const * get() const
Definition: propagate_const.h:64
edm::value_ptr::myP
edm::propagate_const< T * > myP
Definition: value_ptr.h:170
edm::value_ptr::value_ptr
value_ptr(value_ptr< U > const &orig)
Definition: value_ptr.h:120
edm::get_underlying_safe
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
Definition: get_underlying_safe.h:41
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
edm::value_ptr::operator->
T const * operator->() const
Definition: value_ptr.h:106
edm::value_ptr::operator=
value_ptr & operator=(value_ptr< U > const &orig)
Definition: value_ptr.h:123
Utilities.operator
operator
Definition: Utilities.py:24
edm::value_ptr::value_ptr
value_ptr(value_ptr &&orig)
Definition: value_ptr.h:89
edm::value_ptr_traits::destroy
static void destroy(T *p)
Definition: value_ptr.h:53
edm::value_ptr::swap
void swap(value_ptr &orig)
Definition: value_ptr.h:113
edm::propagate_const< T * >
edm::operator!=
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
Definition: debugging_allocator.h:75
edm::value_ptr::operator*
T const & operator*() const
Definition: value_ptr.h:104
std::swap
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Definition: DataFrameContainer.h:209
edm::value_ptr::value_ptr
value_ptr()
Definition: value_ptr.h:69
edm::operator==
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
Definition: debugging_allocator.h:72
edm::value_ptr_traits
Definition: value_ptr.h:51
edm::value_ptr::operator=
value_ptr & operator=(std::unique_ptr< T > orig)
Definition: value_ptr.h:135
edm::value_ptr::this_type_does_not_support_comparisons
void this_type_does_not_support_comparisons() const
Definition: value_ptr.h:149
edm::value_ptr::operator=
value_ptr & operator=(value_ptr &&orig)
Definition: value_ptr.h:91
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
edm::value_ptr::value_ptr
value_ptr(value_ptr const &orig)
Definition: value_ptr.h:77
AlCaHLTBitMon_ParallelJobs.p
def p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
fetchall_from_DQM_v2.release
release
Definition: fetchall_from_DQM_v2.py:92
edm::value_ptr::operator->
T * operator->()
Definition: value_ptr.h:107
edm::value_ptr
Definition: value_ptr.h:63
edm::value_ptr::createFrom
static T * createFrom(U const *p)
Definition: value_ptr.h:162
edm::value_ptr_traits::clone
static T * clone(T const *p)
Definition: value_ptr.h:52
edm::value_ptr::value_ptr
value_ptr(T *p)
Definition: value_ptr.h:70
eostools.move
def move(src, dest)
Definition: eostools.py:511
T
long double T
Definition: Basic3DVectorLD.h:48
edm::value_ptr::operator*
T & operator*()
Definition: value_ptr.h:105
edm::value_ptr::~value_ptr
~value_ptr()
Definition: value_ptr.h:71
funct::void
TEMPL(T2) struct Divides void
Definition: Factorize.h:24
edm::value_ptr::operator=
value_ptr & operator=(value_ptr const &orig)
Definition: value_ptr.h:79
get_underlying_safe.h
edm::value_ptr::value_ptr
value_ptr(std::unique_ptr< T > orig)
Definition: value_ptr.h:133