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 
77  value_ptr(value_ptr const& orig) : myP(createFrom(get_underlying_safe(orig.myP))) {}
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); }
107  T* operator->() { 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
value_ptr(value_ptr &&orig)
Definition: value_ptr.h:89
static T * clone(T const *p)
Definition: value_ptr.h:52
void swap(value_ptr &orig)
Definition: value_ptr.h:113
#define nullptr
T const & operator*() const
Definition: value_ptr.h:104
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
edm::propagate_const< T * > myP
Definition: value_ptr.h:170
static void destroy(T *p)
Definition: value_ptr.h:53
static T * createFrom(U const *p)
Definition: value_ptr.h:162
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
value_ptr(T *p)
Definition: value_ptr.h:70
value_ptr & operator=(value_ptr< U > const &orig)
Definition: value_ptr.h:123
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
value_ptr(value_ptr< U > const &orig)
Definition: value_ptr.h:120
void this_type_does_not_support_comparisons() const
Definition: value_ptr.h:149
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
value_ptr & operator=(value_ptr &&orig)
Definition: value_ptr.h:91
value_ptr & operator=(value_ptr const &orig)
Definition: value_ptr.h:79
value_ptr & operator=(std::unique_ptr< T > orig)
Definition: value_ptr.h:135
value_ptr(std::unique_ptr< T > orig)
Definition: value_ptr.h:133
T * operator->()
Definition: value_ptr.h:107
HLT enums.
value_ptr(value_ptr const &orig)
Definition: value_ptr.h:77
long double T
def move(src, dest)
Definition: eostools.py:511
T const * operator->() const
Definition: value_ptr.h:106
T & operator*()
Definition: value_ptr.h:105