tmpI.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) 2011-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// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33
34template<class T>
35inline void Foam::tmp<T>::incrCount()
36{
37 ptr_->operator++();
38
39 if (ptr_->count() > 1)
40 {
42 << "Attempt to create more than 2 tmp's referring to"
43 " the same object of type "
44 << tmp<T>::typeName()
45 << abort(FatalError);
46 }
47}
48
49
50// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
51
52template<class T>
54{
55 return "tmp<" + word(typeid(T).name()) + '>';
56}
57
58
59template<class T>
60template<class... Args>
62{
63 return tmp<T>(new T(std::forward<Args>(args)...));
64}
65
66
67template<class T>
68template<class U, class... Args>
70{
71 return tmp<T>(new U(std::forward<Args>(args)...));
72}
73
74
75// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
76
77template<class T>
78inline constexpr Foam::tmp<T>::tmp() noexcept
79:
80 ptr_(nullptr),
81 type_(PTR)
82{}
83
84
85template<class T>
86inline constexpr Foam::tmp<T>::tmp(std::nullptr_t) noexcept
87:
88 ptr_(nullptr),
89 type_(PTR)
90{}
91
92
93template<class T>
95:
96 ptr_(p),
97 type_(PTR)
98{
99 if (p && !p->unique())
100 {
102 << "Attempted construction of a "
103 << this->typeName()
104 << " from non-unique pointer"
105 << abort(FatalError);
106 }
107}
108
109
110template<class T>
111inline constexpr Foam::tmp<T>::tmp(const T& obj) noexcept
112:
113 ptr_(const_cast<T*>(&obj)),
114 type_(CREF)
115{}
116
117
118template<class T>
120:
121 ptr_(rhs.ptr_),
122 type_(rhs.type_)
123{
124 rhs.ptr_ = nullptr;
125 rhs.type_ = PTR;
126}
127
129template<class T>
132 ptr_(rhs.ptr_),
133 type_(rhs.type_)
135 rhs.ptr_ = nullptr;
136 rhs.type_ = PTR;
138
139
140template<class T>
141inline Foam::tmp<T>::tmp(const tmp<T>& rhs)
142:
143 ptr_(rhs.ptr_),
144 type_(rhs.type_)
145{
146 if (type_ == PTR)
147 {
148 if (ptr_)
149 {
150 this->incrCount();
151 }
152 else
155 << "Attempted copy of a deallocated "
156 << this->typeName()
158 }
159 }
160}
161
162
163template<class T>
164inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
165:
166 ptr_(rhs.ptr_),
167 type_(rhs.type_)
168{
169 if (type_ == PTR)
170 {
171 if (ptr_)
172 {
173 if (reuse)
174 {
175 rhs.ptr_ = nullptr;
176 // Note: rhs.type_ already set as PTR
177 }
178 else
179 {
180 this->incrCount();
181 }
182 }
183 else
184 {
186 << "Attempted copy of a deallocated "
187 << this->typeName()
188 << abort(FatalError);
189 }
190 }
191}
193
194// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
195
196template<class T>
198{
199 clear();
200}
201
203// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
204
205template<class T>
207{
208 return (type_ == PTR && ptr_ && ptr_->unique());
209}
210
211
212template<class T>
213inline const T& Foam::tmp<T>::cref() const
214{
215 if (type_ == PTR && !ptr_)
218 << this->typeName() << " deallocated"
220 }
221
222 return *ptr_; // const reference
224
225
226template<class T>
227inline T& Foam::tmp<T>::ref() const
228{
229 if (is_const())
232 << "Attempted non-const reference to const object: "
233 << this->typeName()
235 }
236 else if (type_ == PTR && !ptr_)
237 {
239 << this->typeName() << " deallocated"
240 << abort(FatalError);
241 }
243 return *ptr_; // non-const reference
244}
245
246
247template<class T>
249{
250 return const_cast<T&>(cref());
251}
252
254template<class T>
255inline T* Foam::tmp<T>::ptr() const
256{
257 if (!ptr_)
258 {
260 << this->typeName() << " deallocated"
261 << abort(FatalError);
262 }
263
264 if (type_ == PTR)
265 {
266 if (!ptr_->unique())
267 {
269 << "Attempt to acquire pointer to object referred to"
270 << " by multiple temporaries of type "
271 << this->typeName()
272 << abort(FatalError);
273 }
274
275 // Release pointer
276 T* p = ptr_;
277 ptr_ = nullptr;
278
279 return p;
280 }
281
282 return ptr_->clone().ptr();
284
285
286template<class T>
287inline void Foam::tmp<T>::clear() const noexcept
288{
289 if (type_ == PTR && ptr_)
290 {
291 if (ptr_->unique())
292 {
293 delete ptr_;
294 }
295 else
296 {
297 ptr_->operator--();
298 }
299 ptr_ = nullptr;
300 }
301}
302
303
304template<class T>
305inline void Foam::tmp<T>::reset(T* p) noexcept
306{
307 clear();
308 ptr_ = p;
309 type_ = PTR;
310}
311
312
313template<class T>
314inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
315{
316 if (&other == this)
317 {
318 return; // Self-assignment is a no-op
319 }
320
321 clear();
322 ptr_ = other.ptr_;
323 type_ = other.type_;
324
325 other.ptr_ = nullptr;
326 other.type_ = PTR;
327}
328
329
330template<class T>
331inline void Foam::tmp<T>::cref(const tmp<T>& other) noexcept
332{
333 if (&other == this)
334 {
335 return; // Self-assignment is a no-op
336 }
337
338 clear();
339 ptr_ = other.ptr_;
340 type_ = (ptr_ ? CREF : PTR);
341}
342
343
344template<class T>
345inline void Foam::tmp<T>::cref(const T& obj) noexcept
346{
347 clear();
348 ptr_ = const_cast<T*>(&obj);
349 type_ = CREF;
350}
351
352
353template<class T>
354inline void Foam::tmp<T>::cref(const T* p) noexcept
355{
356 clear();
357 ptr_ = const_cast<T*>(p);
358 type_ = (ptr_ ? CREF : PTR);
359}
360
361
362template<class T>
363inline void Foam::tmp<T>::ref(T& obj) noexcept
364{
365 clear();
366 ptr_ = &obj;
367 type_ = REF;
368}
369
370
371template<class T>
372inline void Foam::tmp<T>::ref(T* p) noexcept
373{
374 clear();
375 ptr_ = p;
376 type_ = (ptr_ ? REF : PTR);
377}
378
379
380template<class T>
381inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
382{
383 // Swap is just copy/assign for pointer and enum types
384 // Self-swap is effectively ignored
385 T* p = ptr_;
386 ptr_ = other.ptr_;
387 other.ptr_ = p;
388
389 refType t = type_;
390 type_ = other.type_;
391 other.type_ = t;
392}
393
394
395// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
396
397template<class T>
398inline const T* Foam::tmp<T>::operator->() const
399{
400 if (type_ == PTR && !ptr_)
401 {
403 << this->typeName() << " deallocated"
404 << abort(FatalError);
405 }
406
407 return ptr_;
408}
409
410
411template<class T>
413{
414 if (is_const())
415 {
417 << "Attempt to cast const object to non-const: "
418 << this->typeName()
419 << abort(FatalError);
420 }
421 else if (type_ == PTR && !ptr_)
422 {
424 << this->typeName() << " deallocated"
425 << abort(FatalError);
426 }
427
428 return ptr_;
429}
430
431
432template<class T>
433inline void Foam::tmp<T>::operator=(const tmp<T>& other)
434{
435 if (&other == this)
436 {
437 return; // Self-assignment is a no-op
438 }
439
440 clear();
441
442 if (other.type_ == PTR)
443 {
444 ptr_ = other.ptr_;
445 type_ = PTR;
446 other.ptr_ = nullptr;
447
448 if (!ptr_)
449 {
451 << "Attempted assignment of a deallocated "
452 << this->typeName()
453 << abort(FatalError);
454 }
455 }
456 else
457 {
459 << "Attempted assignment of an object reference of type "
460 << typeid(T).name()
461 << abort(FatalError);
462 }
463}
464
465
466template<class T>
467inline void Foam::tmp<T>::operator=(tmp<T>&& other) noexcept
468{
469 if (&other == this)
470 {
471 return; // Self-assignment is a no-op
472 }
473
474 clear();
475 ptr_ = other.ptr_;
476 type_ = other.type_;
477
478 other.ptr_ = nullptr;
479 other.type_ = PTR;
480}
481
482
483template<class T>
485{
486 if (!p)
487 {
489 << "Attempted copy of a deallocated "
490 << this->typeName()
491 << abort(FatalError);
492 }
493 else if (!p->unique())
494 {
496 << "Attempted assignment of a "
497 << this->typeName()
498 << " to non-unique pointer"
499 << abort(FatalError);
500 }
501
502 reset(p);
503}
504
505
506template<class T>
507inline void Foam::tmp<T>::operator=(std::nullptr_t) noexcept
508{
509 reset(nullptr);
510}
511
512
513// ************************************************************************* //
tmp< GeometricField< Type, PatchField, GeoMesh > > clone() const
Clone.
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
void reset()
Reset to defaults.
bool unique() const noexcept
Return true if the reference count is zero.
Definition: refCount.H:80
A class for managing temporary objects.
Definition: tmp.H:65
void swap(tmp< T > &other) noexcept
Swaps the managed object with other.
Definition: tmpI.H:381
static word typeName()
The type-name, constructed from type-name of T.
Definition: tmpI.H:53
const T & cref() const
Definition: tmpI.H:213
T & constCast() const
Definition: tmpI.H:248
void clear() const noexcept
Definition: tmpI.H:287
bool movable() const noexcept
True if this is a non-null managed pointer with a unique ref-count.
Definition: tmpI.H:206
void operator=(const tmp< T > &other)
Transfer ownership of the managed pointer.
Definition: tmpI.H:433
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: tmpI.H:398
~tmp()
Destructor: deletes managed pointer when the ref-count is 0.
Definition: tmpI.H:197
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: tmpI.H:255
static tmp< T > NewFrom(Args &&... args)
Construct tmp from derived type with forwarding arguments.
T & ref() const
Definition: tmpI.H:227
constexpr tmp() noexcept
Construct with no managed pointer.
Definition: tmpI.H:78
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)