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 | Copyright (C) 2011-2013 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 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
30 
31 template<class T>
32 inline Foam::tmp<T>::tmp(T* tPtr)
33 :
34  isTmp_(true),
35  ptr_(tPtr),
36  ref_(*tPtr)
37 {}
38 
39 
40 template<class T>
41 inline Foam::tmp<T>::tmp(const T& tRef)
42 :
43  isTmp_(false),
44  ptr_(0),
45  ref_(tRef)
46 {}
47 
48 
49 template<class T>
50 inline Foam::tmp<T>::tmp(const tmp<T>& t)
51 :
52  isTmp_(t.isTmp_),
53  ptr_(t.ptr_),
54  ref_(t.ref_)
55 {
56  if (isTmp_)
57  {
58  if (ptr_)
59  {
60  ptr_->operator++();
61  }
62  else
63  {
64  FatalErrorIn("Foam::tmp<T>::tmp(const tmp<T>&)")
65  << "attempted copy of a deallocated temporary"
66  << " of type " << typeid(T).name()
67  << abort(FatalError);
68  }
69  }
70 }
71 
72 
73 template<class T>
74 inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
75 :
76  isTmp_(t.isTmp_),
77  ptr_(t.ptr_),
78  ref_(t.ref_)
79 {
80  if (isTmp_)
81  {
82  if (allowTransfer)
83  {
84  const_cast<tmp<T>&>(t).ptr_ = 0;
85  }
86  else
87  {
88  if (ptr_)
89  {
90  ptr_->operator++();
91  }
92  else
93  {
95  (
96  "Foam::tmp<T>::tmp(const tmp<T>&, bool allowTransfer)"
97  ) << "attempted copy of a deallocated temporary"
98  << " of type " << typeid(T).name()
99  << abort(FatalError);
100  }
101  }
102  }
103 }
104 
105 
106 template<class T>
108 {
109  if (isTmp_ && ptr_)
110  {
111  if (ptr_->okToDelete())
112  {
113  delete ptr_;
114  ptr_ = 0;
115  }
116  else
117  {
118  ptr_->operator--();
119  }
120  }
121 }
122 
123 
124 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
125 
126 template<class T>
127 inline bool Foam::tmp<T>::isTmp() const
128 {
129  return isTmp_;
130 }
131 
132 
133 template<class T>
134 inline bool Foam::tmp<T>::empty() const
135 {
136  return (isTmp_ && !ptr_);
137 }
138 
139 
140 template<class T>
141 inline bool Foam::tmp<T>::valid() const
142 {
143  return (!isTmp_ || (isTmp_ && ptr_));
144 }
145 
146 
147 template<class T>
148 inline T* Foam::tmp<T>::ptr() const
149 {
150  if (isTmp_)
151  {
152  if (!ptr_)
153  {
154  FatalErrorIn("Foam::tmp<T>::ptr() const")
155  << "temporary of type " << typeid(T).name() << " deallocated"
156  << abort(FatalError);
157  }
158 
159  T* ptr = ptr_;
160  ptr_ = 0;
161 
162  ptr->resetRefCount();
163 
164  return ptr;
165  }
166  else
167  {
168  return new T(ref_);
169  }
170 }
171 
172 
173 template<class T>
174 inline void Foam::tmp<T>::clear() const
175 {
176  if (isTmp_ && ptr_) // skip this bit: && ptr_->okToDelete())
177  {
178  delete ptr_;
179  ptr_ = 0;
180  }
181 }
182 
183 
184 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
185 
186 template<class T>
188 {
189  if (isTmp_)
190  {
191  if (!ptr_)
192  {
193  FatalErrorIn("T& Foam::tmp<T>::operator()()")
194  << "temporary of type " << typeid(T).name() << " deallocated"
195  << abort(FatalError);
196  }
197 
198  return *ptr_;
199  }
200  else
201  {
202  // Note: const is cast away!
203  // Perhaps there should be two refs, one for const and one for non const
204  // and if the ref is actually const then you cannot return it here.
205  //
206  // Another possibility would be to store a const ref and a flag to say
207  // whether the tmp was constructed with a const or a non-const argument.
208  //
209  // eg, enum refType { POINTER = 0, REF = 1, CONSTREF = 2 };
210  return const_cast<T&>(ref_);
211  }
212 }
213 
214 
215 template<class T>
216 inline const T& Foam::tmp<T>::operator()() const
217 {
218  if (isTmp_)
219  {
220  if (!ptr_)
221  {
222  FatalErrorIn("const T& Foam::tmp<T>::operator()() const")
223  << "temporary of type " << typeid(T).name() << " deallocated"
224  << abort(FatalError);
225  }
226 
227  return *ptr_;
228  }
229  else
230  {
231  return ref_;
232  }
233 }
234 
235 
236 template<class T>
237 inline Foam::tmp<T>::operator const T&() const
238 {
239  return operator()();
240 }
241 
242 
243 template<class T>
245 {
246  if (isTmp_)
247  {
248  if (!ptr_)
249  {
250  FatalErrorIn("Foam::tmp<T>::operator->()")
251  << "temporary of type " << typeid(T).name() << " deallocated"
252  << abort(FatalError);
253  }
254 
255  return ptr_;
256  }
257  else
258  {
259  return &const_cast<T&>(ref_);
260  }
261 }
262 
263 
264 template<class T>
265 inline const T* Foam::tmp<T>::operator->() const
266 {
267  return const_cast<tmp<T>&>(*this).operator->();
268 }
269 
270 
271 template<class T>
272 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
273 {
274  if (isTmp_ && ptr_)
275  {
276  if (ptr_->okToDelete())
277  {
278  delete ptr_;
279  ptr_ = 0;
280  }
281  else
282  {
283  ptr_->operator--();
284  }
285  }
286 
287  if (t.isTmp_)
288  {
289  isTmp_ = true;
290  ptr_ = t.ptr_;
291 
292  if (ptr_)
293  {
294  ptr_->operator++();
295  }
296  else
297  {
298  FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)")
299  << "attempted copy of a deallocated temporary"
300  << " of type " << typeid(T).name()
301  << abort(FatalError);
302  }
303  }
304  else
305  {
306  FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)")
307  << "attempted to assign to a const reference to constant object"
308  << " of type " << typeid(T).name()
309  << abort(FatalError);
310  }
311 }
312 
313 
314 // ************************************************************************* //
~tmp()
Destructor, delete object when reference count == 0.
Definition: tmpI.H:107
T * ptr() const
Return tmp pointer for reuse.
Definition: tmpI.H:148
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
T & operator()()
Dereference operator.
Definition: tmpI.H:187
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
void clear() const
If object pointer points to valid object:
Definition: tmpI.H:174
bool isTmp() const
Return true if this is really a temporary object.
Definition: tmpI.H:127
bool valid() const
Is this temporary object valid,.
Definition: tmpI.H:141
const volScalarField & T
Definition: createFields.H:25
bool empty() const
Return true if this temporary object empty,.
Definition: tmpI.H:134
T * operator->()
Return object pointer.
Definition: tmpI.H:244
tmp(T *=0)
Store object pointer.
Definition: tmpI.H:32
void operator=(const tmp< T > &)
Assignment operator.
Definition: tmpI.H:272
errorManip< error > abort(error &err)
Definition: errorManip.H:131
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
error FatalError
A class for managing temporary objects.
Definition: PtrList.H:118