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 -------------------------------------------------------------------------------
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 // * * * * * * * * * * * * * Private Member Operators * * * * * * * * * * * //
33 
34 template<class T>
35 inline 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 
52 template<class T>
53 template<class... Args>
55 {
56  return tmp<T>(new T(std::forward<Args>(args)...));
57 }
58 
59 
60 template<class T>
61 template<class U, class... Args>
63 {
64  return tmp<T>(new U(std::forward<Args>(args)...));
65 }
66 
67 
68 template<class T>
70 {
71  return "tmp<" + word(typeid(T).name()) + '>';
72 }
73 
74 
75 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
76 
77 template<class T>
78 inline constexpr Foam::tmp<T>::tmp() noexcept
79 :
80  ptr_(nullptr),
81  type_(PTR)
82 {}
83 
84 
85 template<class T>
86 inline constexpr Foam::tmp<T>::tmp(std::nullptr_t) noexcept
87 :
88  ptr_(nullptr),
89  type_(PTR)
90 {}
91 
92 
93 template<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 
110 template<class T>
111 inline constexpr Foam::tmp<T>::tmp(const T& obj) noexcept
112 :
113  ptr_(const_cast<T*>(&obj)),
114  type_(CREF)
115 {}
116 
117 
118 template<class T>
119 inline Foam::tmp<T>::tmp(tmp<T>&& rhs) noexcept
120 :
121  ptr_(rhs.ptr_),
122  type_(rhs.type_)
123 {
124  rhs.ptr_ = nullptr;
125  rhs.type_ = PTR;
126 }
127 
128 
129 template<class T>
130 inline Foam::tmp<T>::tmp(const tmp<T>&& rhs) noexcept
131 :
132  ptr_(rhs.ptr_),
133  type_(rhs.type_)
134 {
135  rhs.ptr_ = nullptr;
136  rhs.type_ = PTR;
137 }
138 
139 
140 template<class T>
141 inline 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
153  {
155  << "Attempted copy of a deallocated "
156  << this->typeName()
157  << abort(FatalError);
158  }
159  }
160 }
161 
162 
163 template<class T>
164 inline 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 }
192 
193 
194 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
195 
196 template<class T>
198 {
199  clear();
200 }
201 
202 
203 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
204 
205 template<class T>
206 inline bool Foam::tmp<T>::movable() const noexcept
207 {
208  return (type_ == PTR && ptr_ && ptr_->unique());
209 }
210 
211 
212 template<class T>
213 inline const T& Foam::tmp<T>::cref() const
214 {
215  if (type_ == PTR && !ptr_)
216  {
218  << this->typeName() << " deallocated"
219  << abort(FatalError);
220  }
221 
222  return *ptr_; // const reference
223 }
224 
225 
226 template<class T>
227 inline T& Foam::tmp<T>::ref() const
228 {
229  if (is_const())
230  {
232  << "Attempted non-const reference to const object: "
233  << this->typeName()
234  << abort(FatalError);
235  }
236  else if (type_ == PTR && !ptr_)
237  {
239  << this->typeName() << " deallocated"
240  << abort(FatalError);
241  }
242 
243  return *ptr_; // non-const reference
244 }
245 
246 
247 template<class T>
248 inline T& Foam::tmp<T>::constCast() const
249 {
250  return const_cast<T&>(cref());
251 }
252 
253 
254 template<class T>
255 inline 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();
283 }
284 
285 
286 template<class T>
287 inline 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 
304 template<class T>
305 inline void Foam::tmp<T>::reset(T* p) noexcept
306 {
307  clear();
308  ptr_ = p;
309  type_ = PTR;
310 }
311 
312 
313 template<class T>
314 inline 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 
330 template<class T>
331 inline 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 
344 template<class T>
345 inline void Foam::tmp<T>::cref(const T& obj) noexcept
346 {
347  clear();
348  ptr_ = const_cast<T*>(&obj);
349  type_ = CREF;
350 }
351 
352 
353 template<class T>
354 inline 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 
362 template<class T>
363 inline void Foam::tmp<T>::ref(T& obj) noexcept
364 {
365  clear();
366  ptr_ = &obj;
367  type_ = REF;
368 }
369 
370 
371 template<class T>
372 inline void Foam::tmp<T>::ref(T* p) noexcept
373 {
374  clear();
375  ptr_ = p;
376  type_ = (ptr_ ? REF : PTR);
377 }
378 
379 
380 template<class T>
381 inline 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 
397 template<class T>
398 inline 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 
411 template<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 
432 template<class T>
433 inline 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 
466 template<class T>
467 inline 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 
483 template<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 
506 template<class T>
507 inline void Foam::tmp<T>::operator=(std::nullptr_t) noexcept
508 {
509  reset(nullptr);
510 }
511 
512 
513 // ************************************************************************* //
Foam::tmp::operator=
void operator=(const tmp< T > &other)
Transfer ownership of the managed pointer.
Definition: tmpI.H:433
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::tmp::constCast
T & constCast() const
Definition: tmpI.H:248
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::tmp::clear
void clear() const noexcept
Definition: tmpI.H:287
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::tmp::NewFrom
static tmp< T > NewFrom(Args &&... args)
Construct tmp from derived type with forwarding arguments.
Foam::tmp::typeName
static word typeName()
The type-name, constructed from type-name of T.
Definition: tmpI.H:69
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:227
Foam::tmp::operator->
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: tmpI.H:398
error.H
Foam::FatalError
error FatalError
Foam::tmp::ptr
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: tmpI.H:255
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
T
const volScalarField & T
Definition: createFieldRefs.H:2
reset
meshPtr reset(new Foam::fvMesh(Foam::IOobject(regionName, runTime.timeName(), runTime, Foam::IOobject::MUST_READ), false))
U
U
Definition: pEqn.H:72
Foam::tmp::reset
void reset(tmp< T > &&other) noexcept
Clear existing and transfer ownership.
Definition: tmpI.H:314
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
clear
patchWriters clear()
Foam::tmp::swap
void swap(tmp< T > &other) noexcept
Swaps the managed object with other.
Definition: tmpI.H:381
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::tmp::tmp
constexpr tmp() noexcept
Construct with no managed pointer.
Definition: tmpI.H:78
args
Foam::argList args(argc, argv)
Foam::tmp::~tmp
~tmp()
Destructor: deletes managed pointer when the ref-count is 0.
Definition: tmpI.H:197
Foam::tmp::cref
const T & cref() const
Definition: tmpI.H:213
Foam::tmp::movable
bool movable() const noexcept
True if this is a non-null managed pointer with a unique ref-count.
Definition: tmpI.H:206