refPtrI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 OpenFOAM Foundation
9  Copyright (C) 2018-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "error.H"
30 #include <typeinfo>
31 
32 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33 
34 template<class T>
35 template<class... Args>
37 {
38  return refPtr<T>(new T(std::forward<Args>(args)...));
39 }
40 
41 
42 template<class T>
43 template<class U, class... Args>
45 {
46  return refPtr<T>(new U(std::forward<Args>(args)...));
47 }
48 
49 
50 template<class T>
52 {
53  return "refPtr<" + word(typeid(T).name()) + '>';
54 }
55 
56 
57 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
58 
59 template<class T>
60 inline constexpr Foam::refPtr<T>::refPtr() noexcept
61 :
62  ptr_(nullptr),
63  type_(PTR)
64 {}
65 
66 
67 template<class T>
68 inline constexpr Foam::refPtr<T>::refPtr(std::nullptr_t) noexcept
69 :
70  ptr_(nullptr),
71  type_(PTR)
72 {}
73 
74 
75 template<class T>
76 inline constexpr Foam::refPtr<T>::refPtr(T* p) noexcept
77 :
78  ptr_(p),
79  type_(PTR)
80 {}
81 
82 
83 template<class T>
84 inline Foam::refPtr<T>::refPtr(autoPtr<T>&& rhs) noexcept
85 :
86  refPtr<T>(rhs.release())
87 {}
88 
89 
90 template<class T>
91 inline Foam::refPtr<T>::refPtr(std::unique_ptr<T>&& rhs) noexcept
92 :
93  refPtr<T>(rhs.release())
94 {}
95 
96 
97 template<class T>
98 inline constexpr Foam::refPtr<T>::refPtr(const T& obj) noexcept
99 :
100  ptr_(const_cast<T*>(&obj)),
101  type_(CREF)
102 {}
103 
104 
105 template<class T>
106 inline Foam::refPtr<T>::refPtr(refPtr<T>&& rhs) noexcept
107 :
108  ptr_(rhs.ptr_),
109  type_(rhs.type_)
110 {
111  rhs.ptr_ = nullptr;
112  rhs.type_ = PTR;
113 }
114 
115 
116 template<class T>
118 :
119  ptr_(rhs.ptr_),
120  type_(rhs.type_)
121 {
122  if (type_ == PTR)
123  {
124  if (ptr_)
125  {
126  rhs.type_ = REF; // (shallow copy)
127  }
128  else
129  {
131  << "Attempted copy of a deallocated "
132  << this->typeName()
133  << abort(FatalError);
134  }
135  }
136 }
137 
138 
139 template<class T>
140 inline Foam::refPtr<T>::refPtr(const refPtr<T>& rhs, bool reuse)
141 :
142  ptr_(rhs.ptr_),
143  type_(rhs.type_)
144 {
145  if (type_ == PTR)
146  {
147  if (ptr_)
148  {
149  if (reuse)
150  {
151  rhs.ptr_ = nullptr;
152  // Note: rhs.type_ already set as PTR
153  }
154  else
155  {
156  rhs.type_ = REF; // (shallow copy)
157  }
158  }
159  else
160  {
162  << "Attempted copy of a deallocated "
163  << this->typeName()
164  << abort(FatalError);
165  }
166  }
167 }
168 
169 
170 template<class T>
172 {
173  clear();
174 }
175 
176 
177 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
178 
179 template<class T>
180 inline bool Foam::refPtr<T>::movable() const noexcept
181 {
182  return (type_ == PTR && ptr_);
183 }
184 
185 
186 template<class T>
187 inline const T& Foam::refPtr<T>::cref() const
188 {
189  if (type_ == PTR)
190  {
191  if (!ptr_)
192  {
194  << this->typeName() << " deallocated"
195  << abort(FatalError);
196  }
197  }
198 
199  return *ptr_; // const reference
200 }
201 
202 
203 template<class T>
204 inline T& Foam::refPtr<T>::ref() const
205 {
206  if (type_ == PTR)
207  {
208  if (!ptr_)
209  {
211  << this->typeName() << " deallocated"
212  << abort(FatalError);
213  }
214  }
215  else if (type_ == CREF)
216  {
218  << "Attempted non-const reference to const object from a "
219  << this->typeName()
220  << abort(FatalError);
221  }
222 
223  return *ptr_; // non-const reference
224 }
225 
226 
227 template<class T>
229 {
230  return const_cast<T&>(cref());
231 }
232 
233 
234 template<class T>
235 inline T* Foam::refPtr<T>::ptr() const
236 {
237  if (!ptr_)
238  {
240  << this->typeName() << " deallocated"
241  << abort(FatalError);
242  }
243 
244  if (type_ == PTR)
245  {
246  // Release pointer
247  T* p = ptr_;
248  ptr_ = nullptr;
249 
250  return p;
251  }
252 
253  return ptr_->clone().ptr();
254 }
255 
256 
257 template<class T>
258 inline void Foam::refPtr<T>::clear() const noexcept
259 {
260  if (type_ == PTR && ptr_)
261  {
262  delete ptr_;
263  ptr_ = nullptr;
264  }
265 }
266 
267 
268 template<class T>
269 inline void Foam::refPtr<T>::reset(T* p) noexcept
270 {
271  clear();
272  ptr_ = p;
273  type_ = PTR;
274 }
275 
276 
277 template<class T>
278 inline void Foam::refPtr<T>::reset(refPtr<T>&& other) noexcept
279 {
280  if (&other == this)
281  {
282  return; // Self-assignment is a no-op
283  }
284 
285  clear();
286  ptr_ = other.ptr_;
287  type_ = other.type_;
288 
289  other.ptr_ = nullptr;
290  other.type_ = PTR;
291 }
292 
293 
294 template<class T>
295 inline void Foam::refPtr<T>::cref(const T& obj) noexcept
296 {
297  clear();
298  ptr_ = const_cast<T*>(&obj);
299  type_ = CREF;
300 }
301 
302 
303 template<class T>
304 inline void Foam::refPtr<T>::ref(T& obj) noexcept
305 {
306  clear();
307  ptr_ = &obj;
308  type_ = REF;
309 }
310 
311 
312 template<class T>
313 inline void Foam::refPtr<T>::swap(refPtr<T>& other) noexcept
314 {
315  // Swap is just copy/assign for pointer and enum types
316  // Self-swap is effectively ignored
317  T* p = ptr_;
318  ptr_ = other.ptr_;
319  other.ptr_ = p;
320 
321  refType t = type_;
322  type_ = other.type_;
323  other.type_ = t;
324 }
325 
326 
327 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
328 
329 template<class T>
330 inline const T* Foam::refPtr<T>::operator->() const
331 {
332  if (type_ == PTR)
333  {
334  if (!ptr_)
335  {
337  << this->typeName() << " deallocated"
338  << abort(FatalError);
339  }
340  }
341 
342  return ptr_;
343 }
344 
345 
346 template<class T>
348 {
349  if (type_ == PTR)
350  {
351  if (!ptr_)
352  {
354  << this->typeName() << " deallocated"
355  << abort(FatalError);
356  }
357  }
358  else if (type_ == CREF)
359  {
361  << "Attempt to cast const object to non-const for a "
362  << this->typeName()
363  << abort(FatalError);
364  }
365 
366  return ptr_;
367 }
368 
369 
370 template<class T>
371 inline void Foam::refPtr<T>::operator=(const refPtr<T>& other)
372 {
373  if (&other == this)
374  {
375  return; // Self-assignment is a no-op
376  }
377 
378  clear();
379 
380  if (other.type_ == PTR)
381  {
382  ptr_ = other.ptr_;
383  type_ = PTR;
384  other.ptr_ = nullptr;
385 
386  if (!ptr_)
387  {
389  << "Attempted assignment of a deallocated "
390  << this->typeName()
391  << abort(FatalError);
392  }
393  }
394  else
395  {
397  << "Attempted assignment of an object reference of type "
398  << typeid(T).name()
399  << abort(FatalError);
400  }
401 }
402 
403 
404 template<class T>
405 inline void Foam::refPtr<T>::operator=(refPtr<T>&& other) noexcept
406 {
407  if (&other == this)
408  {
409  return; // Self-assignment is a no-op
410  }
411 
412  clear();
413  ptr_ = other.ptr_;
414  type_ = other.type_;
415 
416  other.ptr_ = nullptr;
417  other.type_ = PTR;
418 }
419 
420 
421 template<class T>
423 {
424  if (!p)
425  {
427  << "Attempted copy of a deallocated "
428  << this->typeName()
429  << abort(FatalError);
430  }
431 
432  reset(p);
433 }
434 
435 
436 template<class T>
437 inline void Foam::refPtr<T>::operator=(std::nullptr_t) noexcept
438 {
439  reset(nullptr);
440 }
441 
442 
443 template<class T>
445 {
446  if (type_ == PTR)
447  {
448  return tmp<T>(ptr());
449  }
450  else
451  {
452  return tmp<T>(cref());
453  }
454 }
455 
456 
457 // ************************************************************************* //
Foam::refPtr::New
static refPtr< T > New(Args &&... args)
Construct refPtr of T with forwarding arguments.
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::refPtr::swap
void swap(refPtr< T > &other) noexcept
Swaps the managed object with other.
Definition: refPtrI.H:313
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::refPtr::clear
void clear() const noexcept
Definition: refPtrI.H:258
error.H
Foam::refPtr::cref
const T & cref() const
Definition: refPtrI.H:187
Foam::refPtr::constCast
T & constCast() const
Definition: refPtrI.H:228
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::refPtr::movable
bool movable() const noexcept
True if this is a non-null managed pointer.
Definition: refPtrI.H:180
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::refPtr::ptr
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: refPtrI.H:235
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
U
U
Definition: pEqn.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
clear
patchWriters clear()
Foam::refPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed temporary object and set to new given pointer.
Definition: refPtrI.H:269
Foam::refPtr::~refPtr
~refPtr()
Destructor: deletes managed pointer.
Definition: refPtrI.H:171
Foam::refPtr::refPtr
constexpr refPtr() noexcept
Default construct, no managed pointer.
Definition: refPtrI.H:60
Foam::refPtr::NewFrom
static refPtr< T > NewFrom(Args &&... args)
Construct refPtr from derived type with forwarding arguments.
Foam::refPtr::operator=
void operator=(const refPtr< T > &other)
Transfer ownership of the managed pointer.
Definition: refPtrI.H:371
Foam::refPtr::ref
T & ref() const
Definition: refPtrI.H:204
args
Foam::argList args(argc, argv)
Foam::refPtr::operator->
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: refPtrI.H:330
Foam::refPtr::typeName
static word typeName()
The type-name, constructed from type-name of T.
Definition: refPtrI.H:51
Foam::refPtr
A class for managing references or pointers (no reference counting)
Definition: PtrList.H:60