Loading...
Searching...
No Matches
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-2023 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\*---------------------------------------------------------------------------*/
29#include "error.H"
30#include <typeinfo>
31
32// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33
34template<class T>
36{
37 return Foam::word("refPtr<" + std::string(typeid(T).name()) + '>', false);
38}
39
40
41// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
42
43template<class T>
44inline constexpr Foam::refPtr<T>::refPtr() noexcept
46 ptr_(nullptr),
47 type_(PTR)
48{}
49
50
51template<class T>
52inline constexpr Foam::refPtr<T>::refPtr(std::nullptr_t) noexcept
54 ptr_(nullptr),
55 type_(PTR)
56{}
57
58
59template<class T>
60inline constexpr Foam::refPtr<T>::refPtr(T* p) noexcept
62 ptr_(p),
63 type_(PTR)
64{}
65
66
67template<class T>
68inline constexpr Foam::refPtr<T>::refPtr(const T& obj) noexcept
70 ptr_(const_cast<T*>(&obj)),
71 type_(CREF)
72{}
73
74
75template<class T>
77:
78 ptr_(rhs.ptr_),
79 type_(rhs.type_)
81 rhs.ptr_ = nullptr;
82 rhs.type_ = PTR;
83}
84
85
86template<class T>
88:
89 ptr_(rhs.ptr_),
90 type_(rhs.type_)
91{
92 if (is_pointer())
93 {
94 if (ptr_)
95 {
96 rhs.type_ = REF; // (shallow copy)
97 }
98 else
99 {
101 << "Attempted copy/move of a deallocated "
102 << this->typeName()
104 }
106}
107
108
109template<class T>
110inline Foam::refPtr<T>::refPtr(const refPtr<T>& rhs, bool reuse)
111:
112 ptr_(rhs.ptr_),
113 type_(rhs.type_)
114{
115 if (is_pointer())
116 {
117 if (ptr_)
118 {
119 if (reuse)
120 {
121 rhs.ptr_ = nullptr;
122 rhs.type_ = PTR;
123 }
124 else
125 {
126 rhs.type_ = REF; // (shallow copy)
127 }
128 }
129 else
130 {
132 << "Attempted copy/move of a deallocated "
133 << this->typeName()
135 }
136 }
137}
138
139
140template<class T>
141inline Foam::refPtr<T>::refPtr(std::unique_ptr<T>&& rhs) noexcept
142:
143 refPtr<T>(rhs.release())
144{}
145
146
147template<class T>
149:
150 refPtr<T>(rhs.release())
151{}
152
153
154template<class T>
155inline Foam::refPtr<T>::refPtr(const tmp<T>& rhs, bool reuse)
156:
158{
159 reset(const_cast<tmp<T>&>(rhs), reuse);
160}
161
162
163template<class T>
165:
167{
168 reset(const_cast<tmp<T>&>(rhs), false);
169}
170
171
172template<class T>
174:
175 refPtr<T>()
176{
177 reset(const_cast<tmp<T>&>(rhs), true);
178}
179
180
181// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
182
183template<class T>
185{
187}
188
189
190// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
191
192template<class T>
194{
195 return (type_ == CREF);
196}
197
198
199template<class T>
200inline bool Foam::refPtr<T>::is_pointer() const noexcept
202 //OR: return (type_ == PTR);
203 return (type_ < REF_Types);
204}
205
206
207template<class T>
208inline bool Foam::refPtr<T>::is_reference() const noexcept
210 //OR: return (type_ == CREF || type_ == REF);
211 return (type_ > REF_Types);
212}
214
215template<class T>
217{
218 return (ptr_ && is_pointer());
219}
220
221
222template<class T>
223inline const T& Foam::refPtr<T>::cref() const
224{
225 if (!ptr_ && is_pointer())
228 << this->typeName() << " deallocated"
229 << abort(FatalError);
232 return *ptr_; // const reference
233}
234
235
236template<class T>
237inline T& Foam::refPtr<T>::ref() const
238{
239 if (is_const())
240 {
242 << "Attempted non-const reference to const object: "
243 << this->typeName()
244 << abort(FatalError);
245 }
246 else if (!ptr_ && is_pointer())
247 {
249 << this->typeName() << " deallocated"
250 << abort(FatalError);
252
253 return *ptr_; // non-const reference
254}
255
256
257template<class T>
259{
260 refPtr<T> dup;
261
262 if (ptr_)
263 {
264 dup.ptr_ = ptr_;
265 dup.type_ = (is_const() ? CREF : REF);
267
268 return dup;
269}
271
272template<class T>
274{
275 if (is_pointer())
276 {
277 T* p = ptr_;
278 ptr_ = nullptr;
279 return p;
281
282 return nullptr;
283}
285
286template<class T>
287inline T* Foam::refPtr<T>::ptr() const
288{
289 if (!ptr_)
290 {
292 << this->typeName() << " deallocated"
293 << abort(FatalError);
294 }
296 if (is_pointer())
297 {
298 // Release pointer
299 T* p = ptr_;
300 ptr_ = nullptr;
301
302 return p;
304
305 return ptr_->clone().ptr();
306}
307
309template<class T>
310inline void Foam::refPtr<T>::clear() const noexcept
311{
312 if (is_pointer())
314 delete ptr_;
315 ptr_ = nullptr;
316 }
317}
318
319
320template<class T>
321inline void Foam::refPtr<T>::reset(T* p) noexcept
322{
324 ptr_ = p;
325 type_ = PTR;
326}
327
328
329template<class T>
330inline void Foam::refPtr<T>::reset(refPtr<T>&& other) noexcept
331{
332 // Could also make Fatal with FULLDEBUG
333 if (&other == this)
334 {
335 return; // No self-assignment
336 }
337
338 clear();
339 ptr_ = other.ptr_;
340 type_ = other.type_;
342 other.ptr_ = nullptr;
343 other.type_ = PTR;
344}
346
347template<class T>
348inline void Foam::refPtr<T>::reset(tmp<T>& other, bool reuse)
349{
350 if (other.get())
351 {
352 if (reuse && other.is_pointer())
353 {
354 // Acquire pointer.
355 // Fatal if pointer is not unique (avoids potential leaks)
356 reset(other.ptr());
357 }
358 else if (other.is_const())
359 {
360 cref(other.get());
361 }
362 else
363 {
364 ref(other.get());
365 }
366 }
367 else
368 {
370 }
371}
372
373
374template<class T>
375template<class... Args>
376inline T& Foam::refPtr<T>::emplace(Args&&... args)
377{
378 clear(); // delete old entry
379 ptr_ = new T(std::forward<Args>(args)...);
380 type_ = PTR;
381 return *ptr_;
382}
383
384
385template<class T>
386inline void Foam::refPtr<T>::cref(const refPtr<T>& other) noexcept
387{
388 // Could also make Fatal with FULLDEBUG
389 if (&other == this)
390 {
391 return; // No self-assignment
392 }
393
395 ptr_ = other.ptr_;
396 type_ = (ptr_ ? CREF : PTR);
397}
398
400template<class T>
401inline void Foam::refPtr<T>::cref(const T& obj) noexcept
402{
404 ptr_ = const_cast<T*>(&obj);
405 type_ = CREF;
406}
407
408
409template<class T>
410inline void Foam::refPtr<T>::cref(const T* p) noexcept
411{
413 ptr_ = const_cast<T*>(p);
414 type_ = (ptr_ ? CREF : PTR);
415}
416
417
418template<class T>
419inline void Foam::refPtr<T>::ref(T& obj) noexcept
420{
422 ptr_ = &obj;
423 type_ = REF;
424}
425
426
427template<class T>
428inline void Foam::refPtr<T>::ref(T* p) noexcept
429{
431 ptr_ = p;
432 type_ = (ptr_ ? REF : PTR);
433}
434
435
436template<class T>
437inline void Foam::refPtr<T>::swap(refPtr<T>& other) noexcept
438{
439 // Swap is just copy/assign for pointer and enum types
440 // Self-swap is effectively ignored
441 T* p = ptr_;
442 ptr_ = other.ptr_;
443 other.ptr_ = p;
444
445 refType t = type_;
446 type_ = other.type_;
447 other.type_ = t;
448}
449
450
451// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
452
453template<class T>
454inline const T& Foam::refPtr<T>::operator*() const
455{
456 if (!ptr_)
457 {
459 << this->typeName() << " deallocated"
461 }
462 return *ptr_;
463}
464
465
466template<class T>
468{
469 if (is_const())
470 {
472 << "Attempt to cast const object to non-const: "
473 << this->typeName()
474 << abort(FatalError);
475 }
476 else if (!ptr_)
477 {
479 << this->typeName() << " deallocated"
480 << abort(FatalError);
482
483 return *ptr_;
484}
485
486
487template<class T>
488inline const T* Foam::refPtr<T>::operator->() const
489{
490 if (!ptr_)
491 {
493 << this->typeName() << " deallocated"
494 << abort(FatalError);
496
497 return ptr_;
498}
499
500
501template<class T>
503{
504 if (is_const())
505 {
507 << "Attempt to cast const object to non-const: "
508 << this->typeName()
509 << abort(FatalError);
510 }
511 else if (!ptr_)
512 {
514 << this->typeName() << " deallocated"
515 << abort(FatalError);
517
518 return ptr_;
519}
520
521
522template<class T>
523inline void Foam::refPtr<T>::operator=(const refPtr<T>& other)
524{
525 // Could also make Fatal with FULLDEBUG
526 if (&other == this)
527 {
528 return; // No self-assignment
529 }
530
531 clear();
532
533 if (other.is_pointer())
534 {
535 ptr_ = other.ptr_;
536 type_ = PTR;
537
538 other.ptr_ = nullptr;
539 other.type_ = PTR;
540
541 if (!ptr_)
542 {
544 << "Attempted assignment of a deallocated "
545 << this->typeName()
546 << abort(FatalError);
547 }
548 }
549 else
550 {
552 << "Attempted assignment of an object reference of type "
553 << typeid(T).name()
554 << abort(FatalError);
555 }
556}
557
558
559template<class T>
561{
562 reset(other, true); // reuse
563}
564
565
566template<class T>
568{
569 if (is_pointer())
570 {
571 return tmp<T>(ptr());
572 }
573 else
574 {
575 return tmp<T>(cref());
576 }
577}
578
579
580// ************************************************************************* //
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A class for managing references or pointers (no reference counting).
Definition refPtr.H:54
constexpr refPtr() noexcept
Construct with no managed pointer.
Definition refPtrI.H:37
T & emplace(Args &&... args)
Reset with emplace construction. Return reference to the new content.
Definition refPtrI.H:369
bool is_reference() const noexcept
True if this is a reference (not a pointer).
Definition refPtrI.H:201
bool is_pointer() const noexcept
True if this is a managed pointer (not a reference).
Definition refPtrI.H:193
static word typeName()
The type-name, constructed from type-name of T.
Definition refPtrI.H:28
const T & operator*() const
Return const reference to the object.
Definition refPtrI.H:447
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
Definition refPtrI.H:216
void swap(refPtr< T > &other) noexcept
Swaps the managed object with other.
Definition refPtrI.H:430
T * release() noexcept
Release ownership and return the pointer. A no-op for reference objects (returns nullptr).
Definition refPtrI.H:266
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition refPtrI.H:303
~refPtr() noexcept
Destructor: deletes managed pointer.
Definition refPtrI.H:177
bool movable() const noexcept
True if this is a non-null managed pointer.
Definition refPtrI.H:209
void reset(T *p=nullptr) noexcept
Delete managed pointer and set to new given pointer.
Definition refPtrI.H:314
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition refPtrI.H:481
bool is_const() const noexcept
If the stored/referenced content is const.
Definition refPtrI.H:186
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition refPtrI.H:280
refPtr< T > shallowClone() const noexcept
Return a shallow copy as a wrapped reference, preserving the const/non-const status.
Definition refPtrI.H:251
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Definition refPtrI.H:230
void operator=(const refPtr< T > &other)
Transfer ownership of managed pointer.
Definition refPtrI.H:516
A class for managing temporary objects.
Definition tmp.H:75
bool is_pointer() const noexcept
True if this is a managed pointer (not a reference).
Definition tmpI.H:198
T * get() noexcept
Return pointer without nullptr checking.
Definition tmp.H:277
bool is_const() const noexcept
If the stored/referenced content is const.
Definition tmpI.H:191
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition tmpI.H:256
A class for handling words, derived from Foam::string.
Definition word.H:66
volScalarField & p
const volScalarField & T
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
rDeltaT ref()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
surface1 clear()
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
errorManip< error > abort(error &err)
Definition errorManip.H:139
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
const direction noexcept
Definition scalarImpl.H:265
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Foam::argList args(argc, argv)