Loading...
Searching...
No Matches
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-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("tmp<" + std::string(typeid(T).name()) + '>', false);
38}
39
40
41// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
42
43template<class T>
44inline void Foam::tmp<T>::checkUseCount() const
45{
46 if (ptr_ && ptr_->refCount::use_count() > 1)
47 {
49 << "Attempt to create more than "
50 << (ptr_->refCount::use_count() + 1)
51 << " tmp's referring to the same object of type tmp<"
52 << typeid(T).name() << '>'
53 << abort(FatalError);
54 }
55}
56
57
58// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
59
60template<class T>
61inline constexpr Foam::tmp<T>::tmp() noexcept
63 ptr_(nullptr),
64 type_(PTR)
65{}
66
67
68template<class T>
69inline constexpr Foam::tmp<T>::tmp(std::nullptr_t) noexcept
71 ptr_(nullptr),
72 type_(PTR)
73{}
74
75
76template<class T>
77inline Foam::tmp<T>::tmp(T* p)
78:
79 ptr_(p),
80 type_(PTR)
81{
82 if (ptr_ && !ptr_->refCount::unique())
83 {
84 FatalErrorInFunction
85 << "Attempted construction of a "
86 << this->typeName()
87 << " from non-unique pointer"
88 << abort(FatalError);
89 }
90}
91
92
93template<class T>
94inline constexpr Foam::tmp<T>::tmp(const T& obj) noexcept
96 ptr_(const_cast<T*>(&obj)),
97 type_(CREF)
98{}
99
100
101template<class T>
103:
104 ptr_(rhs.ptr_),
105 type_(rhs.type_)
107 rhs.ptr_ = nullptr;
108 rhs.type_ = PTR;
109}
110
111
112template<class T>
113inline Foam::tmp<T>::tmp(const tmp<T>&& rhs) noexcept
114:
115 ptr_(rhs.ptr_),
116 type_(rhs.type_)
118 rhs.ptr_ = nullptr;
119 rhs.type_ = PTR;
120}
121
122
123template<class T>
124inline Foam::tmp<T>::tmp(const tmp<T>& rhs)
125:
126 ptr_(rhs.ptr_),
127 type_(rhs.type_)
128{
129 if (is_pointer())
130 {
131 if (ptr_)
132 {
133 ptr_->refCount::operator++();
134 //this->checkUseCount();
136 else
137 {
139 << "Attempted copy/move of a deallocated "
140 << this->typeName()
142 }
143 }
144}
145
146
147template<class T>
148inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
149:
150 ptr_(rhs.ptr_),
151 type_(rhs.type_)
152{
153 if (is_pointer())
154 {
155 if (ptr_)
156 {
157 if (reuse)
158 {
159 rhs.ptr_ = nullptr;
160 rhs.type_ = PTR;
161 }
162 else
163 {
164 ptr_->refCount::operator++();
165 //this->checkUseCount();
166 }
167 }
168 else
169 {
171 << "Attempted copy/move of a deallocated "
172 << this->typeName()
174 }
175 }
176}
177
178
179template<class T>
181:
182 tmp<T>(rhs.release())
183{}
184
185
186// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
187
188template<class T>
190{
192}
193
194
195// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
196
197template<class T>
199{
200 return (type_ == CREF);
201}
202
203
204template<class T>
205inline bool Foam::tmp<T>::is_pointer() const noexcept
207 //OR: return (type_ == PTR || type_ == CACHE_PTR);
208 return (type_ < REF_Types);
209}
210
211
212template<class T>
213inline bool Foam::tmp<T>::is_reference() const noexcept
215 //OR: return (type_ == CREF || type_ == REF);
216 return (type_ > REF_Types);
217}
218
219
220template<class T>
222{
223 return (ptr_ && type_ == PTR && ptr_->refCount::unique());
224}
225
226
227template<class T>
228inline const T& Foam::tmp<T>::cref() const
229{
230 if (!ptr_ && is_pointer())
231 {
233 << this->typeName() << " deallocated"
234 << abort(FatalError);
236
237 return *ptr_; // const reference
238}
239
240
241template<class T>
242inline T& Foam::tmp<T>::ref() const
243{
244 if (is_const())
245 {
247 << "Attempted non-const reference to const object: "
248 << this->typeName()
249 << abort(FatalError);
250 }
251 else if (!ptr_ && is_pointer())
252 {
254 << this->typeName() << " deallocated"
255 << abort(FatalError);
257
258 return *ptr_; // non-const reference
260
261
262template<class T>
263inline T* Foam::tmp<T>::ptr() const
265 if (!ptr_)
266 {
268 << this->typeName() << " deallocated"
270 }
271
272 if (type_ == PTR)
273 {
274 if (!ptr_->refCount::unique())
275 {
277 << "Attempt to acquire pointer to object referred to"
278 << " by multiple temporaries of type "
279 << this->typeName()
280 << abort(FatalError);
281 }
282
283 // Release pointer
284 T* p = ptr_;
285 ptr_ = nullptr;
286
287 return p;
288 }
290 // CACHE_PTR (immovable) is cloned, as per a reference
291 return ptr_->clone().ptr();
292}
293
294
295template<class T>
296inline void Foam::tmp<T>::clear() const noexcept
297{
298 if (ptr_ && is_pointer())
299 {
300 if (ptr_->refCount::unique())
301 {
302 delete ptr_;
303 }
304 else
305 {
306 ptr_->refCount::operator--();
308 ptr_ = nullptr;
309 }
310}
311
312
313template<class T>
314inline void Foam::tmp<T>::protect(bool on) noexcept
315{
316 if (on)
317 {
318 // ON: from PTR -> CACHE_PTR, but not nullptr
319 if (ptr_ && type_ == PTR)
321 type_ = CACHE_PTR;
322 }
323 }
324 else
325 {
326 // OFF: from CACHE_PTR -> PTR
327 if (type_ == CACHE_PTR)
328 {
329 type_ = PTR;
330 }
332}
333
334
335template<class T>
336inline void Foam::tmp<T>::reset(T* p) noexcept
337{
339 ptr_ = p;
340 type_ = PTR;
341}
342
343
344template<class T>
345inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
346{
347 // Could also make Fatal with FULLDEBUG
348 if (&other == this)
349 {
350 return; // No self-assignment
351 }
352
354 ptr_ = other.ptr_;
355 type_ = other.type_;
356
357 other.ptr_ = nullptr;
358 other.type_ = PTR;
359}
360
361
362template<class T>
363template<class... Args>
364inline T& Foam::tmp<T>::emplace(Args&&... args)
365{
366 clear(); // delete old entry
367 ptr_ = new T(std::forward<Args>(args)...);
368 type_ = PTR;
369 return *ptr_;
370}
371
372
373template<class T>
374inline void Foam::tmp<T>::cref(const tmp<T>& other) noexcept
375{
376 // Could also make Fatal with FULLDEBUG
377 if (&other == this)
378 {
379 return; // No self-assignment
380 }
381
383 ptr_ = other.ptr_;
384 type_ = (ptr_ ? CREF : PTR);
385}
386
387
388template<class T>
389inline void Foam::tmp<T>::cref(const T& obj) noexcept
390{
392 ptr_ = const_cast<T*>(&obj);
393 type_ = CREF;
394}
395
396
397template<class T>
398inline void Foam::tmp<T>::cref(const T* p) noexcept
399{
401 ptr_ = const_cast<T*>(p);
402 type_ = (ptr_ ? CREF : PTR);
403}
404
405
406template<class T>
407inline void Foam::tmp<T>::ref(T& obj) noexcept
408{
410 ptr_ = &obj;
411 type_ = REF;
412}
413
414
415template<class T>
416inline void Foam::tmp<T>::ref(T* p) noexcept
417{
419 ptr_ = p;
420 type_ = (ptr_ ? REF : PTR);
422
423
424template<class T>
425inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
426{
427 // Swap is just copy/assign for pointer and enum types
428 // Self-swap is effectively ignored
429 T* p = ptr_;
430 ptr_ = other.ptr_;
431 other.ptr_ = p;
432
433 refType t = type_;
434 type_ = other.type_;
435 other.type_ = t;
436}
437
438
439// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
440
441template<class T>
442inline const T* Foam::tmp<T>::operator->() const
443{
444 if (!ptr_ && is_pointer())
445 {
447 << this->typeName() << " deallocated"
448 << abort(FatalError);
450
451 return ptr_;
452}
453
454
455template<class T>
457{
458 if (is_const())
459 {
461 << "Attempt to cast const object to non-const: "
462 << this->typeName()
463 << abort(FatalError);
464 }
465 else if (!ptr_ && is_pointer())
466 {
468 << this->typeName() << " deallocated"
469 << abort(FatalError);
471
472 return ptr_;
473}
474
475
476template<class T>
477inline void Foam::tmp<T>::operator=(const tmp<T>& other)
478{
479 // Could also make Fatal with FULLDEBUG
480 if (&other == this)
481 {
482 return; // No self-assignment
483 }
484
485 clear();
486
487 if (other.is_pointer())
488 {
489 ptr_ = other.ptr_;
490 type_ = other.type_;
491
492 other.ptr_ = nullptr;
493 other.type_ = PTR;
494
495 if (!ptr_)
496 {
498 << "Attempted assignment of a deallocated "
499 << this->typeName()
500 << abort(FatalError);
501 }
502 }
503 else
504 {
506 << "Attempted assignment of an object reference of type "
507 << typeid(T).name()
508 << abort(FatalError);
509 }
510}
511
512
513template<class T>
514inline void Foam::tmp<T>::operator=(tmp<T>&& other) noexcept
515{
516 // Could also make Fatal with FULLDEBUG
517 if (&other == this)
518 {
519 return; // No self-assignment
520 }
521
522 clear();
523 ptr_ = other.ptr_;
524 type_ = other.type_;
526 other.ptr_ = nullptr;
527 other.type_ = PTR;
528}
529
530
531template<class T>
532inline void Foam::tmp<T>::operator=(T* p)
533{
534 if (!p)
535 {
537 << "Attempted copy of a deallocated "
538 << this->typeName()
539 << abort(FatalError);
540 }
541 else if (!p->refCount::unique())
542 {
544 << "Attempted assignment of a "
545 << this->typeName()
546 << " to non-unique pointer"
547 << abort(FatalError);
548 }
549
550 reset(p);
551}
552
553
554// ************************************************************************* //
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A class for managing temporary objects.
Definition tmp.H:75
T & emplace(Args &&... args)
Reset with emplace construction. Return reference to the new content.
Definition tmpI.H:357
void swap(tmp< T > &other) noexcept
Swaps the managed object with other.
Definition tmpI.H:418
bool is_reference() const noexcept
True if this is a reference (not a pointer).
Definition tmpI.H:206
bool is_pointer() const noexcept
True if this is a managed pointer (not a reference).
Definition tmpI.H:198
static word typeName()
The type-name, constructed from type-name of T.
Definition tmpI.H:28
void protect(bool on) noexcept
Use specified protection against moving for the managed pointer. No-op for references.
Definition tmpI.H:307
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
Definition tmpI.H:221
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition tmpI.H:289
bool movable() const noexcept
True if this is a non-null managed pointer with a unique ref-count.
Definition tmpI.H:214
void operator=(const tmp< T > &other)
Transfer ownership of the managed pointer.
Definition tmpI.H:470
void reset(tmp< T > &&other) noexcept
Clear existing and transfer ownership.
Definition tmpI.H:338
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition tmpI.H:435
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
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Definition tmpI.H:235
~tmp() noexcept
Destructor: deletes managed pointer when the ref-count is 0.
Definition tmpI.H:182
constexpr tmp() noexcept
Construct with no managed pointer.
Definition tmpI.H:54
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))
#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)