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-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
34template<class T>
36{
37 return "refPtr<" + word(typeid(T).name()) + '>';
38}
39
40
41template<class T>
42template<class... Args>
44{
45 return refPtr<T>(new T(std::forward<Args>(args)...));
46}
47
48
49template<class T>
50template<class U, class... Args>
52{
53 return refPtr<T>(new U(std::forward<Args>(args)...));
54}
55
56
57// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
58
59template<class T>
60inline constexpr Foam::refPtr<T>::refPtr() noexcept
61:
62 ptr_(nullptr),
63 type_(PTR)
64{}
65
66
67template<class T>
68inline constexpr Foam::refPtr<T>::refPtr(std::nullptr_t) noexcept
69:
70 ptr_(nullptr),
71 type_(PTR)
72{}
73
74
75template<class T>
77:
78 ptr_(p),
79 type_(PTR)
80{}
81
82
83template<class T>
85:
86 refPtr<T>(rhs.release())
87{}
88
89
90template<class T>
91inline Foam::refPtr<T>::refPtr(std::unique_ptr<T>&& rhs) noexcept
92:
93 refPtr<T>(rhs.release())
94{}
95
96
97template<class T>
98inline constexpr Foam::refPtr<T>::refPtr(const T& obj) noexcept
99:
100 ptr_(const_cast<T*>(&obj)),
101 type_(CREF)
102{}
103
104
105template<class T>
107:
108 ptr_(rhs.ptr_),
109 type_(rhs.type_)
110{
111 rhs.ptr_ = nullptr;
112 rhs.type_ = PTR;
113}
115
116template<class T>
118:
119 ptr_(rhs.ptr_),
120 type_(rhs.type_)
121{
122 if (type_ == PTR)
124 if (ptr_)
125 {
126 rhs.type_ = REF; // (shallow copy)
127 }
128 else
131 << "Attempted copy of a deallocated "
132 << this->typeName()
133 << abort(FatalError);
134 }
136}
137
139template<class T>
140inline 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_)
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// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
171
172template<class T>
174{
175 clear();
176}
178
179// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
180
181template<class T>
182inline bool Foam::refPtr<T>::movable() const noexcept
183{
184 return (type_ == PTR && ptr_);
185}
186
188template<class T>
189inline const T& Foam::refPtr<T>::cref() const
190{
191 if (type_ == PTR && !ptr_)
192 {
194 << this->typeName() << " deallocated"
195 << abort(FatalError);
196 }
197
198 return *ptr_; // const reference
200
201
202template<class T>
203inline T& Foam::refPtr<T>::ref() const
204{
205 if (is_const())
206 {
208 << "Attempted non-const reference to const object: "
209 << this->typeName()
210 << abort(FatalError);
212 else if (type_ == PTR && !ptr_)
213 {
215 << this->typeName() << " deallocated"
216 << abort(FatalError);
217 }
218
219 return *ptr_; // non-const reference
220}
221
222
223template<class T>
225{
226 return const_cast<T&>(cref());
228
229
230template<class T>
232{
233 refPtr<T> dup;
234
235 if (ptr_)
236 {
237 dup.ptr_ = ptr_;
238 dup.type_ = (is_const() ? CREF : REF);
240
241 return dup;
242}
244
245template<class T>
246inline T* Foam::refPtr<T>::release() noexcept
247{
248 if (type_ == PTR)
249 {
250 T* p = ptr_;
251 ptr_ = nullptr;
252 return p;
253 }
255 return nullptr;
256}
257
259template<class T>
260inline T* Foam::refPtr<T>::ptr() const
261{
262 if (!ptr_)
263 {
265 << this->typeName() << " deallocated"
266 << abort(FatalError);
267 }
268
269 if (type_ == PTR)
270 {
271 // Release pointer
272 T* p = ptr_;
273 ptr_ = nullptr;
274
275 return p;
276 }
277
278 return ptr_->clone().ptr();
279}
280
282template<class T>
283inline void Foam::refPtr<T>::clear() const noexcept
285 if (type_ == PTR && ptr_)
286 {
287 delete ptr_;
288 ptr_ = nullptr;
289 }
290}
292
293template<class T>
294inline void Foam::refPtr<T>::reset(T* p) noexcept
295{
296 clear();
297 ptr_ = p;
298 type_ = PTR;
299}
300
301
302template<class T>
303inline void Foam::refPtr<T>::reset(refPtr<T>&& other) noexcept
304{
305 if (&other == this)
306 {
307 return; // Self-assignment is a no-op
308 }
309
310 clear();
311 ptr_ = other.ptr_;
312 type_ = other.type_;
313
314 other.ptr_ = nullptr;
315 other.type_ = PTR;
316}
317
318
319template<class T>
320inline void Foam::refPtr<T>::cref(const refPtr<T>& other) noexcept
321{
322 if (&other == this)
323 {
324 return; // Self-assignment is a no-op
325 }
326
327 clear();
328 ptr_ = other.ptr_;
329 type_ = (ptr_ ? CREF : PTR);
330}
331
332
333template<class T>
334inline void Foam::refPtr<T>::cref(const T& obj) noexcept
335{
336 clear();
337 ptr_ = const_cast<T*>(&obj);
338 type_ = CREF;
339}
340
341
342template<class T>
343inline void Foam::refPtr<T>::cref(const T* p) noexcept
344{
345 clear();
346 ptr_ = const_cast<T*>(p);
347 type_ = (ptr_ ? CREF : PTR);
348}
349
350
351template<class T>
352inline void Foam::refPtr<T>::ref(T& obj) noexcept
353{
354 clear();
355 ptr_ = &obj;
356 type_ = REF;
357}
358
359
360template<class T>
361inline void Foam::refPtr<T>::ref(T* p) noexcept
362{
363 clear();
364 ptr_ = p;
365 type_ = (ptr_ ? REF : PTR);
366}
367
368
369template<class T>
370inline void Foam::refPtr<T>::swap(refPtr<T>& other) noexcept
371{
372 // Swap is just copy/assign for pointer and enum types
373 // Self-swap is effectively ignored
374 T* p = ptr_;
375 ptr_ = other.ptr_;
376 other.ptr_ = p;
377
378 refType t = type_;
379 type_ = other.type_;
380 other.type_ = t;
381}
382
383
384// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
385
386template<class T>
387inline const T& Foam::refPtr<T>::operator*() const
388{
389 if (!ptr_)
390 {
392 << this->typeName() << " deallocated"
393 << abort(FatalError);
394 }
395 return *ptr_;
396}
397
398
399template<class T>
401{
402 if (is_const())
403 {
405 << "Attempt to cast const object to non-const: "
406 << this->typeName()
407 << abort(FatalError);
408 }
409 else if (!ptr_)
410 {
412 << this->typeName() << " deallocated"
413 << abort(FatalError);
414 }
415
416 return *ptr_;
417}
418
419
420template<class T>
421inline const T* Foam::refPtr<T>::operator->() const
422{
423 if (!ptr_)
424 {
426 << this->typeName() << " deallocated"
427 << abort(FatalError);
428 }
429
430 return ptr_;
431}
432
433
434template<class T>
436{
437 if (is_const())
438 {
440 << "Attempt to cast const object to non-const: "
441 << this->typeName()
442 << abort(FatalError);
443 }
444 else if (!ptr_)
445 {
447 << this->typeName() << " deallocated"
448 << abort(FatalError);
449 }
450
451 return ptr_;
452}
453
454
455template<class T>
456inline void Foam::refPtr<T>::operator=(const refPtr<T>& other)
457{
458 if (&other == this)
459 {
460 return; // Self-assignment is a no-op
461 }
462
463 clear();
464
465 if (other.type_ == PTR)
466 {
467 ptr_ = other.ptr_;
468 type_ = PTR;
469 other.ptr_ = nullptr;
470
471 if (!ptr_)
472 {
474 << "Attempted assignment of a deallocated "
475 << this->typeName()
476 << abort(FatalError);
477 }
478 }
479 else
480 {
482 << "Attempted assignment of an object reference of type "
483 << typeid(T).name()
484 << abort(FatalError);
485 }
486}
487
488
489template<class T>
490inline void Foam::refPtr<T>::operator=(refPtr<T>&& other) noexcept
491{
492 if (&other == this)
493 {
494 return; // Self-assignment is a no-op
495 }
496
497 clear();
498 ptr_ = other.ptr_;
499 type_ = other.type_;
500
501 other.ptr_ = nullptr;
502 other.type_ = PTR;
503}
504
505
506template<class T>
508{
509 if (!p)
510 {
512 << "Attempted copy of a deallocated "
513 << this->typeName()
514 << abort(FatalError);
515 }
516
517 reset(p);
518}
519
520
521template<class T>
522inline void Foam::refPtr<T>::operator=(std::nullptr_t) noexcept
523{
524 reset(nullptr);
525}
526
527
528template<class T>
530{
531 if (type_ == PTR)
532 {
533 return tmp<T>(ptr());
534 }
535 else
536 {
537 return tmp<T>(cref());
538 }
539}
540
541
542// ************************************************************************* //
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void reset()
Reset to defaults.
A class for managing references or pointers (no reference counting)
Definition: refPtr.H:58
constexpr refPtr() noexcept
Construct with no managed pointer.
Definition: refPtrI.H:60
static word typeName()
The type-name, constructed from type-name of T.
Definition: refPtrI.H:35
const T & operator*() const
Return const reference to the object.
Definition: refPtrI.H:387
const T & cref() const
Definition: refPtrI.H:189
T & constCast() const
Definition: refPtrI.H:224
void swap(refPtr< T > &other) noexcept
Swaps the managed object with other.
Definition: refPtrI.H:370
T * release() noexcept
Definition: refPtrI.H:246
void clear() const noexcept
Definition: refPtrI.H:283
~refPtr()
Destructor: deletes managed pointer.
Definition: refPtrI.H:173
bool movable() const noexcept
True if this is a non-null managed pointer.
Definition: refPtrI.H:182
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: refPtrI.H:421
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: refPtrI.H:260
static refPtr< T > NewFrom(Args &&... args)
Construct refPtr from derived type with forwarding arguments.
refPtr< T > shallowClone() const noexcept
Definition: refPtrI.H:231
T & ref() const
Definition: refPtrI.H:203
void operator=(const refPtr< T > &other)
Transfer ownership of the managed pointer.
Definition: refPtrI.H:456
A class for managing temporary objects.
Definition: tmp.H:65
A class for handling words, derived from Foam::string.
Definition: word.H:68
U
Definition: pEqn.H:72
volScalarField & p
const volScalarField & T
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
errorManip< error > abort(error &err)
Definition: errorManip.H:144
const direction noexcept
Definition: Scalar.H:223
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::argList args(argc, argv)