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 
51  template <typename T>
53  static T* clone(T const* p) { return new T(*p); }
54  static void destroy(T* p) { delete p; }
55  };
56 
57  // --------------------------------------------------------------------
58  //
59  // Copyable smart pointer class template
60  //
61  // --------------------------------------------------------------------
62 
63 
64  template <typename T>
65  class value_ptr {
66 
67  public:
68 
69  // --------------------------------------------------
70  // Default constructor/destructor:
71  // --------------------------------------------------
72 
73  value_ptr() : myP(nullptr) { }
74  explicit value_ptr(T* p) : myP(p) { }
76 
77  // --------------------------------------------------
78  // Copy constructor/copy assignment:
79  // --------------------------------------------------
80 
81  value_ptr(value_ptr const& orig) :
82  myP(createFrom(get_underlying_safe(orig.myP))) {
83  }
84 
85  value_ptr& operator=(value_ptr const& orig) {
86  value_ptr<T> temp(orig);
87  swap(temp);
88  return *this;
89  }
90 
91  // --------------------------------------------------
92  // Move constructor/move assignment:
93  // --------------------------------------------------
94 
95  value_ptr(value_ptr&& orig) :
96  myP(orig.myP) { orig.myP=nullptr; }
97 
99  if (myP!=orig.myP) {
100  delete myP.get();
101  myP=orig.myP;
102  orig.myP=nullptr;
103  }
104  return *this;
105  }
106 
107  // --------------------------------------------------
108  // Access mechanisms:
109  // --------------------------------------------------
110 
111  T const& operator*() const { return *myP; }
112  T& operator*() { return *myP; }
113  T const* operator->() const { return get_underlying_safe(myP); }
114  T* operator->() { return get_underlying_safe(myP); }
115 
116  // --------------------------------------------------
117  // Manipulation:
118  // --------------------------------------------------
119 
120  void swap(value_ptr& orig) { std::swap(myP, orig.myP); }
121 
122  // --------------------------------------------------
123  // Copy-like construct/assign from compatible value_ptr<>:
124  // --------------------------------------------------
125 
126  template <typename U>
127  value_ptr(value_ptr<U> const& orig) :
128  myP(createFrom(orig.operator->())) {
129  }
130 
131  template <typename U>
133  value_ptr<T> temp(orig);
134  swap(temp);
135  return *this;
136  }
137 
138  // --------------------------------------------------
139  // Move-like construct/assign from unique_ptr<>:
140  // --------------------------------------------------
141 
142  value_ptr(std::unique_ptr<T> orig) :
143  myP(orig.release()) { orig=nullptr; }
144 
145  value_ptr& operator=(std::unique_ptr<T> orig) {
146  value_ptr<T> temp(std::move(orig));
147  swap(temp);
148  return *this;
149  }
150 
151  // The following typedef, function, and operator definition
152  // support the following syntax:
153  // value_ptr<T> ptr(..);
154  // if (ptr) { ...
155  // Where the conditional will evaluate as true if and only if the
156  // pointer value_ptr contains is not null.
157  private:
158  typedef void (value_ptr::*bool_type)() const;
160 
161  public:
162  operator bool_type() const {
163  return myP != nullptr ?
165  }
166 
167  private:
168 
169  // --------------------------------------------------
170  // Implementation aid:
171  // --------------------------------------------------
172 
173  template <typename U>
174  static T*
175  createFrom(U const* p) {
176  return p
178  : nullptr;
179  }
180 
181  // --------------------------------------------------
182  // Member data:
183  // --------------------------------------------------
184 
186 
187  }; // value_ptr
188 
189 
190  // --------------------------------------------------------------------
191  //
192  // Free-standing swap()
193  //
194  // --------------------------------------------------------------------
195 
196  template <typename T>
197  inline
198  void
199  swap(value_ptr<T>& vp1, value_ptr<T>& vp2) { vp1.swap(vp2); }
200 
201  // Do not allow nonsensical comparisons that the bool_type
202  // conversion operator definition above would otherwise allow.
203  // The function call inside the next 4 operator definitions is
204  // private, so compilation will fail if there is an attempt to
205  // instantiate these 4 operators.
206  template <typename T, typename U>
207  inline bool operator==(value_ptr<T> const& lhs, U const& rhs) {
209  return false;
210  }
211 
212  template <typename T, typename U>
213  inline bool operator!=(value_ptr<T> const& lhs, U const& rhs) {
215  return false;
216  }
217 
218  template <typename T, typename U>
219  inline bool operator==(U const& lhs, value_ptr<T> const& rhs) {
221  return false;
222  }
223 
224  template <typename T, typename U>
225  inline bool operator!=(U const& lhs, value_ptr<T> const& rhs) {
227  return false;
228  }
229 }
230 
231 
232 #endif // FWCoreUtilities_value_ptr_h
value_ptr(value_ptr &&orig)
Definition: value_ptr.h:95
static T * clone(T const *p)
Definition: value_ptr.h:53
void swap(value_ptr &orig)
Definition: value_ptr.h:120
T const & operator*() const
Definition: value_ptr.h:111
#define nullptr
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
edm::propagate_const< T * > myP
Definition: value_ptr.h:185
static void destroy(T *p)
Definition: value_ptr.h:54
static T * createFrom(U const *p)
Definition: value_ptr.h:175
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
value_ptr(T *p)
Definition: value_ptr.h:74
value_ptr & operator=(value_ptr< U > const &orig)
Definition: value_ptr.h:132
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
value_ptr(value_ptr< U > const &orig)
Definition: value_ptr.h:127
void this_type_does_not_support_comparisons() const
Definition: value_ptr.h:159
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:98
value_ptr & operator=(value_ptr const &orig)
Definition: value_ptr.h:85
value_ptr & operator=(std::unique_ptr< T > orig)
Definition: value_ptr.h:145
value_ptr(std::unique_ptr< T > orig)
Definition: value_ptr.h:142
T * operator->()
Definition: value_ptr.h:114
HLT enums.
value_ptr(value_ptr const &orig)
Definition: value_ptr.h:81
long double T
def move(src, dest)
Definition: eostools.py:510
T const * operator->() const
Definition: value_ptr.h:113
T & operator*()
Definition: value_ptr.h:112