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-2022 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 Functions * * * * * * * * * * * //
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 the same"
43  " object of type tmp<" << typeid(T).name() << '>'
44  << abort(FatalError);
45  }
46 }
47 
48 
49 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
50 
51 template<class T>
53 {
54  return Foam::word("tmp<" + std::string(typeid(T).name()) + '>', false);
55 }
56 
57 
58 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
59 
60 template<class T>
61 inline constexpr Foam::tmp<T>::tmp() noexcept
62 :
63  ptr_(nullptr),
64  type_(PTR)
65 {}
66 
67 
68 template<class T>
69 inline constexpr Foam::tmp<T>::tmp(std::nullptr_t) noexcept
70 :
71  ptr_(nullptr),
72  type_(PTR)
73 {}
74 
75 
76 template<class T>
77 inline Foam::tmp<T>::tmp(T* p)
78 :
79  ptr_(p),
80  type_(PTR)
81 {
82  if (ptr_ && !ptr_->unique())
83  {
85  << "Attempted construction of a "
86  << this->typeName()
87  << " from non-unique pointer"
88  << abort(FatalError);
89  }
90 }
91 
92 
93 template<class T>
94 inline constexpr Foam::tmp<T>::tmp(const T& obj) noexcept
95 :
96  ptr_(const_cast<T*>(&obj)),
97  type_(CREF)
98 {}
99 
100 
101 template<class T>
102 inline Foam::tmp<T>::tmp(tmp<T>&& rhs) noexcept
103 :
104  ptr_(rhs.ptr_),
105  type_(rhs.type_)
106 {
107  rhs.ptr_ = nullptr;
108  rhs.type_ = PTR;
109 }
110 
111 
112 template<class T>
113 inline Foam::tmp<T>::tmp(const tmp<T>&& rhs) noexcept
114 :
115  ptr_(rhs.ptr_),
116  type_(rhs.type_)
117 {
118  rhs.ptr_ = nullptr;
119  rhs.type_ = PTR;
120 }
121 
122 
123 template<class T>
124 inline 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  this->incrCount();
134  }
135  else
136  {
138  << "Attempted copy/move of a deallocated "
139  << this->typeName()
141  }
142  }
143 }
144 
145 
146 template<class T>
147 inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
148 :
149  ptr_(rhs.ptr_),
150  type_(rhs.type_)
151 {
152  if (is_pointer())
153  {
154  if (ptr_)
155  {
156  if (reuse)
157  {
158  rhs.ptr_ = nullptr;
159  rhs.type_ = PTR;
160  }
161  else
162  {
163  this->incrCount();
164  }
165  }
166  else
167  {
169  << "Attempted copy/move of a deallocated "
170  << this->typeName()
172  }
173  }
174 }
175 
176 
177 template<class T>
178 inline Foam::tmp<T>::tmp(autoPtr<T>&& rhs) noexcept
179 :
180  tmp<T>(rhs.release())
181 {}
182 
183 
184 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
185 
186 template<class T>
188 {
189  clear();
190 }
191 
192 
193 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
194 
195 template<class T>
196 inline bool Foam::tmp<T>::movable() const noexcept
197 {
198  return (is_pointer() && ptr_ && ptr_->unique());
199 }
200 
201 
202 template<class T>
203 inline const T& Foam::tmp<T>::cref() const
204 {
205  if (is_pointer() && !ptr_)
206  {
208  << this->typeName() << " deallocated"
209  << abort(FatalError);
210  }
211 
212  return *ptr_; // const reference
213 }
214 
215 
216 template<class T>
217 inline T& Foam::tmp<T>::ref() const
218 {
219  if (is_const())
220  {
222  << "Attempted non-const reference to const object: "
223  << this->typeName()
224  << abort(FatalError);
225  }
226  else if (is_pointer() && !ptr_)
227  {
229  << this->typeName() << " deallocated"
230  << abort(FatalError);
231  }
232 
233  return *ptr_; // non-const reference
234 }
235 
236 
237 template<class T>
238 inline T* Foam::tmp<T>::ptr() const
239 {
240  if (!ptr_)
241  {
243  << this->typeName() << " deallocated"
244  << abort(FatalError);
245  }
246 
247  if (is_pointer())
248  {
249  if (!ptr_->unique())
250  {
252  << "Attempt to acquire pointer to object referred to"
253  << " by multiple temporaries of type "
254  << this->typeName()
255  << abort(FatalError);
256  }
257 
258  // Release pointer
259  T* p = ptr_;
260  ptr_ = nullptr;
261 
262  return p;
263  }
264 
265  return ptr_->clone().ptr();
266 }
267 
268 
269 template<class T>
270 inline void Foam::tmp<T>::clear() const noexcept
271 {
272  if (is_pointer() && ptr_)
273  {
274  if (ptr_->unique())
275  {
276  delete ptr_;
277  }
278  else
279  {
280  ptr_->operator--();
281  }
282  ptr_ = nullptr;
283  }
284 }
285 
286 
287 template<class T>
288 inline void Foam::tmp<T>::reset(T* p) noexcept
289 {
290  clear();
291  ptr_ = p;
292  type_ = PTR;
293 }
294 
295 
296 template<class T>
297 inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
298 {
299  // Could also make Fatal with FULLDEBUG
300  if (&other == this)
301  {
302  return; // No self-assignment
303  }
304 
305  clear();
306  ptr_ = other.ptr_;
307  type_ = other.type_;
309  other.ptr_ = nullptr;
310  other.type_ = PTR;
311 }
312 
313 
314 template<class T>
315 inline void Foam::tmp<T>::cref(const tmp<T>& other) noexcept
316 {
317  // Could also make Fatal with FULLDEBUG
318  if (&other == this)
319  {
320  return; // No self-assignment
321  }
322 
323  clear();
324  ptr_ = other.ptr_;
325  type_ = (ptr_ ? CREF : PTR);
326 }
327 
328 
329 template<class T>
330 inline void Foam::tmp<T>::cref(const T& obj) noexcept
331 {
332  clear();
333  ptr_ = const_cast<T*>(&obj);
334  type_ = CREF;
335 }
336 
337 
338 template<class T>
339 inline void Foam::tmp<T>::cref(const T* p) noexcept
340 {
341  clear();
342  ptr_ = const_cast<T*>(p);
343  type_ = (ptr_ ? CREF : PTR);
344 }
345 
346 
347 template<class T>
348 inline void Foam::tmp<T>::ref(T& obj) noexcept
349 {
350  clear();
351  ptr_ = &obj;
352  type_ = REF;
353 }
354 
355 
356 template<class T>
357 inline void Foam::tmp<T>::ref(T* p) noexcept
358 {
359  clear();
360  ptr_ = p;
361  type_ = (ptr_ ? REF : PTR);
362 }
363 
364 
365 template<class T>
366 inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
367 {
368  // Swap is just copy/assign for pointer and enum types
369  // Self-swap is effectively ignored
370  T* p = ptr_;
371  ptr_ = other.ptr_;
372  other.ptr_ = p;
373 
374  refType t = type_;
375  type_ = other.type_;
376  other.type_ = t;
377 }
378 
379 
380 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
381 
382 template<class T>
383 inline const T* Foam::tmp<T>::operator->() const
384 {
385  if (is_pointer() && !ptr_)
386  {
388  << this->typeName() << " deallocated"
389  << abort(FatalError);
390  }
391 
392  return ptr_;
393 }
394 
395 
396 template<class T>
397 inline T* Foam::tmp<T>::operator->()
398 {
399  if (is_const())
400  {
402  << "Attempt to cast const object to non-const: "
403  << this->typeName()
404  << abort(FatalError);
405  }
406  else if (is_pointer() && !ptr_)
407  {
409  << this->typeName() << " deallocated"
410  << abort(FatalError);
411  }
412 
413  return ptr_;
414 }
415 
416 
417 template<class T>
418 inline void Foam::tmp<T>::operator=(const tmp<T>& other)
419 {
420  // Could also make Fatal with FULLDEBUG
421  if (&other == this)
422  {
423  return; // No self-assignment
424  }
425 
426  clear();
427 
428  if (other.is_pointer())
429  {
430  ptr_ = other.ptr_;
431  type_ = PTR;
432 
433  other.ptr_ = nullptr;
434  other.type_ = PTR;
435 
436  if (!ptr_)
437  {
439  << "Attempted assignment of a deallocated "
440  << this->typeName()
441  << abort(FatalError);
442  }
443  }
444  else
445  {
447  << "Attempted assignment of an object reference of type "
448  << typeid(T).name()
449  << abort(FatalError);
450  }
451 }
452 
453 
454 template<class T>
455 inline void Foam::tmp<T>::operator=(tmp<T>&& other) noexcept
456 {
457  // Could also make Fatal with FULLDEBUG
458  if (&other == this)
459  {
460  return; // No self-assignment
461  }
462 
463  clear();
464  ptr_ = other.ptr_;
465  type_ = other.type_;
467  other.ptr_ = nullptr;
468  other.type_ = PTR;
469 }
470 
471 
472 template<class T>
473 inline void Foam::tmp<T>::operator=(T* p)
474 {
475  if (!p)
476  {
478  << "Attempted copy of a deallocated "
479  << this->typeName()
480  << abort(FatalError);
481  }
482  else if (!p->unique())
483  {
485  << "Attempted assignment of a "
486  << this->typeName()
487  << " to non-unique pointer"
488  << abort(FatalError);
489  }
490 
491  reset(p);
492 }
493 
494 
495 // ************************************************************************* //
static word typeName()
The type-name, constructed from type-name of T.
Definition: tmpI.H:45
constexpr tmp() noexcept
Construct with no managed pointer.
Definition: tmpI.H:54
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
bool movable() const noexcept
True if this is a non-null managed pointer with a unique ref-count.
Definition: tmpI.H:189
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Definition: tmpI.H:210
~tmp() noexcept
Destructor: deletes managed pointer when the ref-count is 0.
Definition: tmpI.H:180
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
Definition: tmpI.H:196
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
A class for handling words, derived from Foam::string.
Definition: word.H:63
patchWriters clear()
errorManip< error > abort(error &err)
Definition: errorManip.H:139
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: tmpI.H:376
void swap(tmp< T > &other) noexcept
Swaps the managed object with other.
Definition: tmpI.H:359
const direction noexcept
Definition: Scalar.H:258
const volScalarField & T
void operator=(const tmp< T > &other)
Transfer ownership of the managed pointer.
Definition: tmpI.H:411
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition: tmpI.H:263
T * ptr() const
Return managed pointer for reuse, or clone() the object reference.
Definition: tmpI.H:231
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
void reset(tmp< T > &&other) noexcept
Clear existing and transfer ownership.
Definition: tmpI.H:290