tmpI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2025 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "tmp.H"
27 #include "error.H"
28 #include <typeinfo>
29 
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 
32 template<class T>
33 inline bool Foam::tmp<T>::isAnyTmp() const
34 {
35  return type_ == REUSABLE_TMP || type_ == NON_RESUSABLE_TMP;
36 }
37 
38 
39 // * * * * * * * * * * * * * Private Member Operators * * * * * * * * * * * //
40 
41 template<class T>
42 inline void Foam::tmp<T>::operator++()
43 {
44  ptr_->operator++();
45 
46  if (ptr_->count() > 1)
47  {
49  << "Attempt to create more than 2 tmp's referring to"
50  " the same object of type " << typeName()
51  << abort(FatalError);
52  }
53 }
54 
55 
56 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
57 
58 template<class T>
59 inline Foam::tmp<T>::tmp(T* tPtr, bool nonReusable)
60 :
61  type_(nonReusable ? NON_RESUSABLE_TMP : REUSABLE_TMP),
62  ptr_(tPtr)
63 {
64  if (tPtr && !tPtr->unique())
65  {
67  << "Attempted construction of a " << typeName()
68  << " from non-unique pointer"
69  << abort(FatalError);
70  }
71 }
72 
73 
74 template<class T>
75 inline Foam::tmp<T>::tmp(const T& tRef)
76 :
77  type_(CONST_REF),
78  ptr_(const_cast<T*>(&tRef))
79 {}
80 
81 
82 template<class T>
83 inline Foam::tmp<T>::tmp(const tmp<T>& t)
84 :
85  type_(t.type_),
86  ptr_(t.ptr_)
87 {
88  if (isAnyTmp())
89  {
90  if (ptr_)
91  {
92  operator++();
93  }
94  else
95  {
97  << "Attempted copy of a deallocated " << typeName()
98  << abort(FatalError);
99  }
100  }
101 }
102 
103 
104 template<class T>
106 :
107  type_(t.type_),
108  ptr_(t.ptr_)
109 {
110  if (isAnyTmp())
111  {
112  t.ptr_ = 0;
113  }
114 }
115 
116 
117 template<class T>
118 inline Foam::tmp<T>::tmp(const tmp<T>&& t)
119 :
120  type_(t.type_),
121  ptr_(t.ptr_)
122 {
123  if (isAnyTmp())
124  {
125  t.ptr_ = 0;
126  }
127 }
128 
129 
130 template<class T>
131 inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
132 :
133  type_(t.type_),
134  ptr_(t.ptr_)
135 {
136  if (isAnyTmp())
137  {
138  if (ptr_)
139  {
140  if (allowTransfer && type_ == REUSABLE_TMP)
141  {
142  t.ptr_ = 0;
143  }
144  else
145  {
146  operator++();
147  }
148  }
149  else
150  {
152  << "Attempted copy of a deallocated " << typeName()
154  }
155  }
156 }
157 
158 
159 template<class T>
161 {
162  clear();
163 }
164 
165 
166 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
167 
168 template<class T>
169 inline bool Foam::tmp<T>::isTmp() const
170 {
171  return type_ == REUSABLE_TMP;
172 }
173 
174 
175 template<class T>
176 inline bool Foam::tmp<T>::empty() const
177 {
178  return (isAnyTmp() && !ptr_);
179 }
180 
181 
182 template<class T>
183 inline bool Foam::tmp<T>::valid() const
184 {
185  return (!isAnyTmp() || (isAnyTmp() && ptr_));
186 }
187 
188 
189 template<class T>
191 {
192  return "tmp<" + word(typeid(T).name()) + '>';
193 }
194 
195 
196 template<class T>
197 inline T& Foam::tmp<T>::ref() const
198 {
199  if (isAnyTmp())
200  {
201  if (!ptr_)
202  {
204  << typeName() << " deallocated"
205  << abort(FatalError);
206  }
207  }
208  else
209  {
211  << "Attempt to acquire non-const reference to const object"
212  << " from a " << typeName()
213  << abort(FatalError);
214  }
215 
216  return *ptr_;
217 }
218 
219 
220 template<class T>
221 inline T* Foam::tmp<T>::ptr() const
222 {
223  if (isTmp())
224  {
225  if (!ptr_)
226  {
228  << typeName() << " deallocated"
229  << abort(FatalError);
230  }
231 
232  if (!ptr_->unique())
233  {
235  << "Attempt to acquire pointer to object referred to"
236  << " by multiple temporaries of type " << typeName()
237  << abort(FatalError);
238  }
239 
240  T* ptr = ptr_;
241  ptr_ = 0;
242 
243  return ptr;
244  }
245  else
246  {
247  return ptr_->clone().ptr();
248  }
249 }
250 
251 
252 template<class T>
253 inline void Foam::tmp<T>::clear() const
254 {
255  if (isAnyTmp() && ptr_)
256  {
257  if (ptr_->unique())
258  {
259  delete ptr_;
260  ptr_ = 0;
261  }
262  else
263  {
264  ptr_->operator--();
265  ptr_ = 0;
266  }
267  }
268 }
269 
270 
271 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
272 
273 #ifdef NON_CONST_TMP
274 template<class T>
275 inline T& Foam::tmp<T>::operator()()
276 {
277  if (isAnyTmp())
278  {
279  if (!ptr_)
280  {
282  << typeName() << " deallocated"
283  << abort(FatalError);
284  }
285  }
286 
287  // Const-ness is automatically cast-away which is why this operator is
288  // deprecated. Use ref() where non-const access is required.
289  return *ptr_;
290 }
291 #endif
292 
293 
294 template<class T>
295 inline const T& Foam::tmp<T>::operator()() const
296 {
297  if (isAnyTmp())
298  {
299  if (!ptr_)
300  {
302  << typeName() << " deallocated"
303  << abort(FatalError);
304  }
305  }
306 
307  // Return const reference
308  return *ptr_;
309 }
310 
311 
312 template<class T>
313 inline Foam::tmp<T>::operator const T&() const
314 {
315  return operator()();
316 }
317 
318 
319 template<class T>
321 {
322  if (isAnyTmp())
323  {
324  if (!ptr_)
325  {
327  << typeName() << " deallocated"
328  << abort(FatalError);
329  }
330  }
331  else
332  {
334  << "Attempt to cast const object to non-const for a " << typeName()
335  << abort(FatalError);
336  }
337 
338  return ptr_;
339 }
340 
341 
342 template<class T>
343 inline const T* Foam::tmp<T>::operator->() const
344 {
345  if (isAnyTmp() && !ptr_)
346  {
348  << typeName() << " deallocated"
349  << abort(FatalError);
350  }
351 
352  return ptr_;
353 }
354 
355 
356 template<class T>
357 inline void Foam::tmp<T>::operator=(T* tPtr)
358 {
359  clear();
360 
361  if (!tPtr)
362  {
364  << "Attempted copy of a deallocated " << typeName()
365  << abort(FatalError);
366  }
367 
368  if (tPtr && !tPtr->unique())
369  {
371  << "Attempted assignment of a " << typeName()
372  << " to non-unique pointer"
373  << abort(FatalError);
374  }
375 
376  type_ = REUSABLE_TMP;
377  ptr_ = tPtr;
378 }
379 
380 
381 template<class T>
382 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
383 {
384  clear();
385 
386  if (t.isAnyTmp())
387  {
388  if (!t.ptr_)
389  {
391  << "Attempted assignment to a deallocated " << typeName()
392  << abort(FatalError);
393  }
394 
395  type_ = t.type_;
396  ptr_ = t.ptr_;
397 
398  t.ptr_ = 0;
399  }
400  else
401  {
403  << "Attempted assignment to a const reference to an object"
404  << " of type " << typeid(T).name()
405  << abort(FatalError);
406  }
407 }
408 
409 
410 template<class T>
412 {
413  clear();
414 
415  type_ = t.type_;
416  ptr_ = t.ptr_;
417 
418  if (isAnyTmp())
419  {
420  t.ptr_ = 0;
421  }
422 }
423 
424 
425 template<class T>
426 inline void Foam::tmp<T>::operator=(const tmp<T>&& t)
427 {
428  clear();
429 
430  type_ = t.type_;
431  ptr_ = t.ptr_;
432 
433  if (isAnyTmp())
434  {
435  t.ptr_ = 0;
436  }
437 }
438 
439 
440 // ************************************************************************* //
A class for managing temporary objects.
Definition: tmp.H:55
void operator=(T *)
Assignment to pointer changing this tmp to a temporary T.
Definition: tmpI.H:357
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:183
T * operator->()
Return object pointer.
Definition: tmpI.H:320
word typeName() const
Return the type name of the tmp.
Definition: tmpI.H:190
bool empty() const
Return true if this temporary object empty,.
Definition: tmpI.H:176
bool isTmp() const
Return true if this is really a temporary object.
Definition: tmpI.H:169
tmp(T *=0, bool nonReusable=false)
Store object pointer of a non-reusable or reusable temporary object.
Definition: tmpI.H:59
~tmp()
Destructor. Deletes temporary object when the reference count is 0.
Definition: tmpI.H:160
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:221
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:253
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
const T & operator()() const
Const dereference operator.
Definition: tmpI.H:295
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
tUEqn clear()
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void T(LagrangianPatchField< Type > &f, const LagrangianPatchField< Type > &f1)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError