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