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-2021 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 "error.H"
27 #include <typeinfo>
28 
29 // * * * * * * * * * * * * * Private Member Operators * * * * * * * * * * * //
30 
31 template<class T>
32 inline void Foam::tmp<T>::operator++()
33 {
34  ptr_->operator++();
35 
36  if (ptr_->count() > 1)
37  {
39  << "Attempt to create more than 2 tmp's referring to"
40  " the same object of type " << typeName()
41  << abort(FatalError);
42  }
43 }
44 
45 
46 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
47 
48 template<class T>
49 inline Foam::tmp<T>::tmp(T* tPtr, bool nonReusable)
50 :
51  type_(nonReusable ? NON_RESUSABLE_TMP : REUSABLE_TMP),
52  ptr_(tPtr)
53 {
54  if (tPtr && !tPtr->unique())
55  {
57  << "Attempted construction of a " << typeName()
58  << " from non-unique pointer"
59  << abort(FatalError);
60  }
61 }
62 
63 
64 template<class T>
65 inline Foam::tmp<T>::tmp(const T& tRef)
66 :
67  type_(CONST_REF),
68  ptr_(const_cast<T*>(&tRef))
69 {}
70 
71 
72 template<class T>
73 inline Foam::tmp<T>::tmp(const tmp<T>& t)
74 :
75  type_(t.type_),
76  ptr_(t.ptr_)
77 {
78  if (isAnyTmp())
79  {
80  if (ptr_)
81  {
82  operator++();
83  }
84  else
85  {
87  << "Attempted copy of a deallocated " << typeName()
88  << abort(FatalError);
89  }
90  }
91 }
92 
93 
94 template<class T>
95 inline Foam::tmp<T>::tmp(const tmp<T>&& t)
96 :
97  type_(t.type_),
98  ptr_(t.ptr_)
99 {
100  if (isAnyTmp())
101  {
102  t.ptr_ = 0;
103  }
104 }
105 
106 
107 template<class T>
108 inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
109 :
110  type_(t.type_),
111  ptr_(t.ptr_)
112 {
113  if (isAnyTmp())
114  {
115  if (ptr_)
116  {
117  if (allowTransfer && type_ == REUSABLE_TMP)
118  {
119  t.ptr_ = 0;
120  }
121  else
122  {
123  operator++();
124  }
125  }
126  else
127  {
129  << "Attempted copy of a deallocated " << typeName()
130  << abort(FatalError);
131  }
132  }
133 }
134 
135 
136 template<class T>
138 {
139  clear();
140 }
141 
142 
143 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
144 
145 template<class T>
146 inline bool Foam::tmp<T>::isAnyTmp() const
147 {
148  return type_ == REUSABLE_TMP || type_ == NON_RESUSABLE_TMP;
149 }
150 
151 
152 template<class T>
153 inline bool Foam::tmp<T>::isTmp() const
154 {
155  return type_ == REUSABLE_TMP;
156 }
157 
158 
159 template<class T>
160 inline bool Foam::tmp<T>::empty() const
161 {
162  return (isAnyTmp() && !ptr_);
163 }
164 
165 
166 template<class T>
167 inline bool Foam::tmp<T>::valid() const
168 {
169  return (!isAnyTmp() || (isAnyTmp() && ptr_));
170 }
171 
172 
173 template<class T>
175 {
176  return "tmp<" + word(typeid(T).name()) + '>';
177 }
178 
179 
180 template<class T>
181 inline T& Foam::tmp<T>::ref() const
182 {
183  if (isAnyTmp())
184  {
185  if (!ptr_)
186  {
188  << typeName() << " deallocated"
189  << abort(FatalError);
190  }
191  }
192  else
193  {
195  << "Attempt to acquire non-const reference to const object"
196  << " from a " << typeName()
197  << abort(FatalError);
198  }
199 
200  return *ptr_;
201 }
202 
203 
204 template<class T>
205 inline T* Foam::tmp<T>::ptr() const
206 {
207  if (isTmp())
208  {
209  if (!ptr_)
210  {
212  << typeName() << " deallocated"
213  << abort(FatalError);
214  }
215 
216  if (!ptr_->unique())
217  {
219  << "Attempt to acquire pointer to object referred to"
220  << " by multiple temporaries of type " << typeName()
221  << abort(FatalError);
222  }
223 
224  T* ptr = ptr_;
225  ptr_ = 0;
226 
227  return ptr;
228  }
229  else
230  {
231  return ptr_->clone().ptr();
232  }
233 }
234 
235 
236 template<class T>
237 inline void Foam::tmp<T>::clear() const
238 {
239  if (isAnyTmp() && ptr_)
240  {
241  if (ptr_->unique())
242  {
243  delete ptr_;
244  ptr_ = 0;
245  }
246  else
247  {
248  ptr_->operator--();
249  ptr_ = 0;
250  }
251  }
252 }
253 
254 
255 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
256 
257 #ifdef NON_CONST_TMP
258 template<class T>
259 inline T& Foam::tmp<T>::operator()()
260 {
261  if (isAnyTmp())
262  {
263  if (!ptr_)
264  {
266  << typeName() << " deallocated"
267  << abort(FatalError);
268  }
269  }
270 
271  // Const-ness is automatically cast-away which is why this operator is
272  // deprecated. Use ref() where non-const access is required.
273  return *ptr_;
274 }
275 #endif
276 
277 
278 template<class T>
279 inline const T& Foam::tmp<T>::operator()() const
280 {
281  if (isAnyTmp())
282  {
283  if (!ptr_)
284  {
286  << typeName() << " deallocated"
287  << abort(FatalError);
288  }
289  }
290 
291  // Return const reference
292  return *ptr_;
293 }
294 
295 
296 template<class T>
297 inline Foam::tmp<T>::operator const T&() const
298 {
299  return operator()();
300 }
301 
302 
303 template<class T>
305 {
306  if (isAnyTmp())
307  {
308  if (!ptr_)
309  {
311  << typeName() << " deallocated"
312  << abort(FatalError);
313  }
314  }
315  else
316  {
318  << "Attempt to cast const object to non-const for a " << typeName()
319  << abort(FatalError);
320  }
321 
322  return ptr_;
323 }
324 
325 
326 template<class T>
327 inline const T* Foam::tmp<T>::operator->() const
328 {
329  if (isAnyTmp() && !ptr_)
330  {
332  << typeName() << " deallocated"
333  << abort(FatalError);
334  }
335 
336  return ptr_;
337 }
338 
339 
340 template<class T>
341 inline void Foam::tmp<T>::operator=(T* tPtr)
342 {
343  clear();
344 
345  if (!tPtr)
346  {
348  << "Attempted copy of a deallocated " << typeName()
349  << abort(FatalError);
350  }
351 
352  if (tPtr && !tPtr->unique())
353  {
355  << "Attempted assignment of a " << typeName()
356  << " to non-unique pointer"
357  << abort(FatalError);
358  }
359 
360  type_ = REUSABLE_TMP;
361  ptr_ = tPtr;
362 }
363 
364 
365 template<class T>
366 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
367 {
368  clear();
369 
370  if (t.isAnyTmp())
371  {
372  // if (!t.ptr_)
373  // {
374  // FatalErrorInFunction
375  // << "Attempted assignment to a deallocated " << typeName()
376  // << abort(FatalError);
377  // }
378 
379  type_ = t.type_;
380  ptr_ = t.ptr_;
381 
382  t.ptr_ = 0;
383  }
384  else
385  {
387  << "Attempted assignment to a const reference to an object"
388  << " of type " << typeid(T).name()
389  << abort(FatalError);
390  }
391 }
392 
393 
394 template<class T>
395 inline void Foam::tmp<T>::operator=(const tmp<T>&& t)
396 {
397  clear();
398 
399  type_ = t.type_;
400  ptr_ = t.ptr_;
401 
402  if (isAnyTmp())
403  {
404  t.ptr_ = 0;
405  }
406 }
407 
408 
409 // ************************************************************************* //
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:341
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:167
T * operator->()
Return object pointer.
Definition: tmpI.H:304
word typeName() const
Return the type name of the tmp.
Definition: tmpI.H:174
bool empty() const
Return true if this temporary object empty,.
Definition: tmpI.H:160
bool isTmp() const
Return true if this is really a temporary object.
Definition: tmpI.H:153
tmp(T *=0, bool nonReusable=false)
Store object pointer of a non-reusable or reusable temporary object.
Definition: tmpI.H:49
~tmp()
Destructor: deletes temporary object when the reference count is 0.
Definition: tmpI.H:137
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:205
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:237
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
const T & operator()() const
Const dereference operator.
Definition: tmpI.H:279
A class for handling words, derived from string.
Definition: word.H:62
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
tUEqn clear()
errorManip< error > abort(error &err)
Definition: errorManip.H:131
error FatalError
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)