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