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-2019 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>::operator++()
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 " << typeName()
44  << abort(FatalError);
45  }
46 }
47 
48 
49 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
50 
51 template<class T>
52 template<class... Args>
54 {
55  return tmp<T>(new T(std::forward<Args>(args)...));
56 }
57 
58 
59 template<class T>
60 template<class U, class... Args>
62 {
63  return tmp<T>(new U(std::forward<Args>(args)...));
64 }
65 
66 
67 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
68 
69 template<class T>
70 inline constexpr Foam::tmp<T>::tmp() noexcept
71 :
72  ptr_(nullptr),
73  type_(PTR)
74 {}
75 
76 
77 template<class T>
78 inline constexpr Foam::tmp<T>::tmp(std::nullptr_t) noexcept
79 :
80  ptr_(nullptr),
81  type_(PTR)
82 {}
83 
84 
85 template<class T>
87 :
88  ptr_(p),
89  type_(PTR)
90 {
91  if (p && !p->unique())
92  {
94  << "Attempted construction of a " << typeName()
95  << " from non-unique pointer"
96  << abort(FatalError);
97  }
98 }
99 
100 
101 template<class T>
102 inline Foam::tmp<T>::tmp(const T& obj) noexcept
103 :
104  ptr_(const_cast<T*>(&obj)),
105  type_(CREF)
106 {}
107 
108 
109 template<class T>
110 inline Foam::tmp<T>::tmp(tmp<T>&& t) noexcept
111 :
112  ptr_(t.ptr_),
113  type_(t.type_)
114 {
115  t.ptr_ = nullptr;
116  t.type_ = PTR;
117 }
118 
119 
120 template<class T>
121 inline Foam::tmp<T>::tmp(const tmp<T>&& t) noexcept
122 :
123  ptr_(t.ptr_),
124  type_(t.type_)
125 {
126  t.ptr_ = nullptr;
127  t.type_ = PTR;
128 }
129 
130 
131 template<class T>
132 inline Foam::tmp<T>::tmp(const tmp<T>& t)
133 :
134  ptr_(t.ptr_),
135  type_(t.type_)
136 {
137  if (isTmp())
138  {
139  if (ptr_)
140  {
141  operator++();
142  }
143  else
144  {
146  << "Attempted copy of a deallocated " << typeName()
147  << abort(FatalError);
148  }
149  }
150 }
151 
152 
153 template<class T>
154 inline Foam::tmp<T>::tmp(const tmp<T>& t, bool reuse)
155 :
156  ptr_(t.ptr_),
157  type_(t.type_)
158 {
159  if (isTmp())
160  {
161  if (ptr_)
162  {
163  if (reuse)
164  {
165  t.ptr_ = nullptr; // t.type_ already set as PTR
166  }
167  else
168  {
169  operator++();
170  }
171  }
172  else
173  {
175  << "Attempted copy of a deallocated " << typeName()
176  << abort(FatalError);
177  }
178  }
179 }
180 
181 
182 template<class T>
184 {
185  clear();
186 }
187 
188 
189 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
190 
191 template<class T>
192 inline bool Foam::tmp<T>::isTmp() const noexcept
193 {
194  return type_ == PTR;
195 }
196 
197 
198 template<class T>
199 inline bool Foam::tmp<T>::empty() const noexcept
200 {
201  return (!ptr_ && isTmp());
202 }
203 
204 
205 template<class T>
206 inline bool Foam::tmp<T>::valid() const noexcept
207 {
208  return (ptr_ || type_ == CREF);
209 }
210 
211 
212 template<class T>
213 inline bool Foam::tmp<T>::movable() const noexcept
214 {
215  return (type_ == PTR && ptr_ && ptr_->unique());
216 }
217 
218 
219 template<class T>
221 {
222  return "tmp<" + word(typeid(T).name()) + '>';
223 }
224 
225 
226 template<class T>
227 inline T* Foam::tmp<T>::get() noexcept
228 {
229  return ptr_; // non-const pointer
230 }
231 
232 
233 template<class T>
234 inline const T* Foam::tmp<T>::get() const noexcept
235 {
236  return ptr_; // const pointer
237 }
238 
239 
240 template<class T>
241 inline const T& Foam::tmp<T>::cref() const
242 {
243  if (isTmp())
244  {
245  if (!ptr_)
246  {
248  << typeName() << " deallocated"
249  << abort(FatalError);
250  }
251  }
252 
253  return *ptr_; // const reference
254 }
255 
256 
257 template<class T>
258 inline T& Foam::tmp<T>::ref() const
259 {
260  if (isTmp())
261  {
262  if (!ptr_)
263  {
265  << typeName() << " deallocated"
266  << abort(FatalError);
267  }
268  }
269  else
270  {
272  << "Attempted non-const reference to const object from a "
273  << typeName()
274  << abort(FatalError);
275  }
276 
277  return *ptr_; // non-const reference
278 }
279 
280 
281 template<class T>
282 inline T& Foam::tmp<T>::constCast() const
283 {
284  if (isTmp() && !ptr_)
285  {
287  << typeName() << " deallocated"
288  << abort(FatalError);
289  }
290 
291  return const_cast<T&>(*ptr_);
292 }
293 
294 
295 template<class T>
296 inline T* Foam::tmp<T>::ptr() const
297 {
298  if (isTmp())
299  {
300  if (!ptr_)
301  {
303  << typeName() << " deallocated"
304  << abort(FatalError);
305  }
306  else if (!ptr_->unique())
307  {
309  << "Attempt to acquire pointer to object referred to"
310  << " by multiple temporaries of type " << typeName()
311  << abort(FatalError);
312  }
313 
314  T* ptr = ptr_;
315  ptr_ = nullptr;
316 
317  return ptr;
318  }
319 
320  return ptr_->clone().ptr();
321 }
322 
323 
324 template<class T>
325 inline void Foam::tmp<T>::clear() const noexcept
326 {
327  if (isTmp() && ptr_)
328  {
329  if (ptr_->unique())
330  {
331  delete ptr_;
332  }
333  else
334  {
335  ptr_->operator--();
336  }
337  ptr_ = nullptr;
338  }
339 }
340 
341 
342 template<class T>
343 inline void Foam::tmp<T>::reset() noexcept
344 {
345  clear();
346  ptr_ = nullptr;
347  type_ = PTR;
348 }
349 
350 
351 template<class T>
352 inline void Foam::tmp<T>::reset(T* p) noexcept
353 {
354  clear();
355  ptr_ = p;
356  type_ = PTR;
357 }
358 
359 
360 template<class T>
361 inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
362 {
363  if (&other == this)
364  {
365  return; // Self-assignment is a no-op
366  }
367 
368  clear();
369  ptr_ = other.ptr_;
370  type_ = other.type_;
371 
372  other.ptr_ = nullptr;
373  other.type_ = PTR;
374 }
375 
376 
377 template<class T>
378 inline void Foam::tmp<T>::cref(const T& obj) noexcept
379 {
380  clear();
381  ptr_ = const_cast<T*>(&obj);
382  type_ = CREF;
383 }
384 
385 
386 template<class T>
387 inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
388 {
389  if (&other == this)
390  {
391  return; // Self-swap is a no-op
392  }
393 
394  // Copy/assign for pointer types
395  T* p = ptr_;
396  ptr_ = other.ptr_;
397  other.ptr_ = p;
398 
399  refType t = type_;
400  type_ = other.type_;
401  other.type_ = t;
402 }
403 
404 
405 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
406 
407 template<class T>
408 inline const T& Foam::tmp<T>::operator()() const
409 {
410  return cref();
411 }
412 
413 
414 template<class T>
415 inline Foam::tmp<T>::operator const T&() const
416 {
417  return cref();
418 }
419 
420 
421 template<class T>
422 inline const T* Foam::tmp<T>::operator->() const
423 {
424  if (!ptr_ && isTmp())
425  {
427  << typeName() << " deallocated"
428  << abort(FatalError);
429  }
430 
431  return ptr_;
432 }
433 
434 
435 template<class T>
437 {
438  if (isTmp())
439  {
440  if (!ptr_)
441  {
443  << typeName() << " deallocated"
444  << abort(FatalError);
445  }
446  }
447  else
448  {
450  << "Attempt to cast const object to non-const for a " << typeName()
451  << abort(FatalError);
452  }
453 
454  return ptr_;
455 }
456 
457 
458 template<class T>
459 inline Foam::tmp<T>::operator bool() const noexcept
460 {
461  return (ptr_ || type_ == CREF);
462 }
463 
464 
465 template<class T>
467 {
468  clear();
469 
470  if (!p)
471  {
473  << "Attempted copy of a deallocated " << typeName()
474  << abort(FatalError);
475  }
476  else if (!p->unique())
477  {
479  << "Attempted assignment of a " << typeName()
480  << " to non-unique pointer"
481  << abort(FatalError);
482  }
483 
484  ptr_ = p;
485  type_ = PTR;
486 }
487 
488 
489 template<class T>
490 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
491 {
492  if (&t == this)
493  {
494  return; // Self-assignment is a no-op
495  }
496 
497  clear();
498 
499  if (t.isTmp())
500  {
501  ptr_ = t.ptr_;
502  type_ = PTR;
503  t.ptr_ = nullptr;
504 
505  if (!ptr_)
506  {
508  << "Attempted assignment to a deallocated " << typeName()
509  << abort(FatalError);
510  }
511  }
512  else
513  {
515  << "Attempted assignment to a const reference to an object"
516  << " of type " << typeid(T).name()
517  << abort(FatalError);
518  }
519 }
520 
521 
522 template<class T>
523 inline void Foam::tmp<T>::operator=(tmp<T>&& other) noexcept
524 {
525  if (&other == this)
526  {
527  return; // Self-assignment is a no-op
528  }
529 
530  clear();
531  ptr_ = other.ptr_;
532  type_ = other.type_;
533 
534  other.ptr_ = nullptr;
535  other.type_ = PTR;
536 }
537 
538 
539 // ************************************************************************* //
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::tmp::constCast
T & constCast() const
Non-const dereference, even if the object is const.
Definition: tmpI.H:282
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::tmp::clear
void clear() const noexcept
Definition: tmpI.H:325
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::tmp::empty
bool empty() const noexcept
True if this is a non-null managed pointer.
Definition: tmpI.H:199
Foam::tmp::isTmp
bool isTmp() const noexcept
True if this is a managed pointer (not a const reference)
Definition: tmpI.H:192
Foam::tmp::operator()
const T & operator()() const
Return const reference to the object.
Definition: tmpI.H:408
Foam::tmp::NewFrom
static tmp< T > NewFrom(Args &&... args)
Construct tmp from derived type with forwarding arguments.
Foam::tmp::reset
void reset() noexcept
Release ownership of managed temporary object.
Definition: tmpI.H:343
Foam::tmp::operator=
void operator=(T *p)
Take ownership of the pointer.
Definition: tmpI.H:466
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:258
Foam::tmp::operator->
const T * operator->() const
Dereferences (const) pointer to the managed object.
Definition: tmpI.H:422
error.H
Foam::tmp::get
T * get() noexcept
Return pointer without nullptr checking.
Definition: tmpI.H:227
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::FatalError
error FatalError
Foam::tmp::typeName
word typeName() const
Return type-name of the tmp, constructed from type-name of T.
Definition: tmpI.H:220
Foam::tmp::ptr
T * ptr() const
Definition: tmpI.H:296
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
T
const volScalarField & T
Definition: createFieldRefs.H:2
U
U
Definition: pEqn.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
clear
patchWriters clear()
Foam::tmp::swap
void swap(tmp< T > &other) noexcept
Swaps the managed object with other.
Definition: tmpI.H:387
Foam::tmp::New
static tmp< T > New(Args &&... args)
Construct tmp of T with forwarding arguments.
bool
bool
Definition: EEqn.H:20
Foam::tmp::tmp
constexpr tmp() noexcept
Construct with no managed pointer.
Definition: tmpI.H:70
Foam::tmp::valid
bool valid() const noexcept
Definition: tmpI.H:206
args
Foam::argList args(argc, argv)
Foam::tmp::~tmp
~tmp()
Destructor: deletes managed pointer when the ref-count is 0.
Definition: tmpI.H:183
Foam::tmp::cref
const T & cref() const
Definition: tmpI.H:241
Foam::tmp::movable
bool movable() const noexcept
True if this is a non-null managed pointer with a unique ref-count.
Definition: tmpI.H:213