All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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-2018 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)
50 :
51  type_(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 (isTmp())
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 (isTmp())
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 (isTmp())
114  {
115  if (ptr_)
116  {
117  if (allowTransfer)
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>::isTmp() const
147 {
148  return type_ == TMP;
149 }
150 
151 
152 template<class T>
153 inline bool Foam::tmp<T>::empty() const
154 {
155  return (isTmp() && !ptr_);
156 }
157 
158 
159 template<class T>
160 inline bool Foam::tmp<T>::valid() const
161 {
162  return (!isTmp() || (isTmp() && ptr_));
163 }
164 
165 
166 template<class T>
168 {
169  return "tmp<" + word(typeid(T).name()) + '>';
170 }
171 
172 
173 template<class T>
174 inline T& Foam::tmp<T>::ref() const
175 {
176  if (isTmp())
177  {
178  if (!ptr_)
179  {
181  << typeName() << " deallocated"
182  << abort(FatalError);
183  }
184  }
185  else
186  {
188  << "Attempt to acquire non-const reference to const object"
189  << " from a " << typeName()
190  << abort(FatalError);
191  }
192 
193  return *ptr_;
194 }
195 
196 
197 template<class T>
198 inline T* Foam::tmp<T>::ptr() const
199 {
200  if (isTmp())
201  {
202  if (!ptr_)
203  {
205  << typeName() << " deallocated"
206  << abort(FatalError);
207  }
208 
209  if (!ptr_->unique())
210  {
212  << "Attempt to acquire pointer to object referred to"
213  << " by multiple temporaries of type " << typeName()
214  << abort(FatalError);
215  }
216 
217  T* ptr = ptr_;
218  ptr_ = 0;
219 
220  return ptr;
221  }
222  else
223  {
224  return ptr_->clone().ptr();
225  }
226 }
227 
228 
229 template<class T>
230 inline void Foam::tmp<T>::clear() const
231 {
232  if (isTmp() && ptr_)
233  {
234  if (ptr_->unique())
235  {
236  delete ptr_;
237  ptr_ = 0;
238  }
239  else
240  {
241  ptr_->operator--();
242  ptr_ = 0;
243  }
244  }
245 }
246 
247 
248 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
249 
250 #ifdef NON_CONST_TMP
251 template<class T>
252 inline T& Foam::tmp<T>::operator()()
253 {
254  if (isTmp())
255  {
256  if (!ptr_)
257  {
259  << typeName() << " deallocated"
260  << abort(FatalError);
261  }
262  }
263 
264  // Const-ness is automatically cast-away which is why this operator is
265  // deprecated. Use ref() where non-const access is required.
266  return *ptr_;
267 }
268 #endif
269 
270 
271 template<class T>
272 inline const T& Foam::tmp<T>::operator()() const
273 {
274  if (isTmp())
275  {
276  if (!ptr_)
277  {
279  << typeName() << " deallocated"
280  << abort(FatalError);
281  }
282  }
283 
284  // Return const reference
285  return *ptr_;
286 }
287 
288 
289 template<class T>
290 inline Foam::tmp<T>::operator const T&() const
291 {
292  return operator()();
293 }
294 
295 
296 template<class T>
298 {
299  if (isTmp())
300  {
301  if (!ptr_)
302  {
304  << typeName() << " deallocated"
305  << abort(FatalError);
306  }
307  }
308  else
309  {
311  << "Attempt to cast const object to non-const for a " << typeName()
312  << abort(FatalError);
313  }
314 
315  return ptr_;
316 }
317 
318 
319 template<class T>
320 inline const T* Foam::tmp<T>::operator->() const
321 {
322  if (isTmp() && !ptr_)
323  {
325  << typeName() << " deallocated"
326  << abort(FatalError);
327  }
328 
329  return ptr_;
330 }
331 
332 
333 template<class T>
334 inline void Foam::tmp<T>::operator=(T* tPtr)
335 {
336  clear();
337 
338  if (!tPtr)
339  {
341  << "Attempted copy of a deallocated " << typeName()
342  << abort(FatalError);
343  }
344 
345  if (tPtr && !tPtr->unique())
346  {
348  << "Attempted assignment of a " << typeName()
349  << " to non-unique pointer"
350  << abort(FatalError);
351  }
352 
353  type_ = TMP;
354  ptr_ = tPtr;
355 }
356 
357 
358 template<class T>
359 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
360 {
361  clear();
362 
363  if (t.isTmp())
364  {
365  type_ = TMP;
366 
367  if (!t.ptr_)
368  {
370  << "Attempted assignment to a deallocated " << typeName()
371  << abort(FatalError);
372  }
373 
374  ptr_ = t.ptr_;
375  t.ptr_ = 0;
376  }
377  else
378  {
380  << "Attempted assignment to a const reference to an object"
381  << " of type " << typeid(T).name()
382  << abort(FatalError);
383  }
384 }
385 
386 
387 // ************************************************************************* //
tUEqn clear()
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:230
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
const T & operator()() const
Const dereference operator.
Definition: tmpI.H:272
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:174
bool isTmp() const
Return true if this is really a temporary object.
Definition: tmpI.H:146
T * operator->()
Return object pointer.
Definition: tmpI.H:297
word typeName() const
Return the type name of the tmp.
Definition: tmpI.H:167
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:160
void operator=(T *)
Assignment to pointer changing this tmp to a temporary T.
Definition: tmpI.H:334
A class for handling words, derived from string.
Definition: word.H:59
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const volScalarField & T
~tmp()
Destructor: deletes temporary object when the reference count is 0.
Definition: tmpI.H:137
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
bool empty() const
Return true if this temporary object empty,.
Definition: tmpI.H:153
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:198
A class for managing temporary objects.
Definition: PtrList.H:53
tmp(T *=0)
Store object pointer.
Definition: tmpI.H:49