FreeFOAM The Cross-Platform CFD Toolkit
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) 1991-2010 OpenCFD Ltd.
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 <OpenFOAM/error.H>
27 
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 
30 template<class T>
31 inline Foam::tmp<T>::tmp(T* tPtr)
32 :
33  isTmp_(true),
34  ptr_(tPtr),
35  ref_(*tPtr)
36 {}
37 
38 
39 template<class T>
40 inline Foam::tmp<T>::tmp(const T& tRef)
41 :
42  isTmp_(false),
43  ptr_(0),
44  ref_(tRef)
45 {}
46 
47 
48 template<class T>
49 inline Foam::tmp<T>::tmp(const tmp<T>& t)
50 :
51  isTmp_(t.isTmp_),
52  ptr_(t.ptr_),
53  ref_(t.ref_)
54 {
55  if (isTmp_)
56  {
57  if (ptr_)
58  {
59  ptr_->operator++();
60  }
61  else
62  {
63  FatalErrorIn("tmp<T>::tmp(const tmp<T>&)")
64  << "attempted copy of a deallocated temporary"
65  << abort(FatalError);
66  }
67  }
68 }
69 
70 
71 template<class T>
73 {
74  if (isTmp_ && ptr_)
75  {
76  if (ptr_->okToDelete())
77  {
78  delete ptr_;
79  ptr_ = 0;
80  }
81  else
82  {
83  ptr_->operator--();
84  }
85  }
86 }
87 
88 
89 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
90 
91 template<class T>
92 inline bool Foam::tmp<T>::isTmp() const
93 {
94  return isTmp_;
95 }
96 
97 
98 template<class T>
99 inline bool Foam::tmp<T>::empty() const
100 {
101  return (isTmp_ && !ptr_);
102 }
103 
104 
105 template<class T>
106 inline bool Foam::tmp<T>::valid() const
107 {
108  return (!isTmp_ || (isTmp_ && ptr_));
109 }
110 
111 
112 template<class T>
113 inline T* Foam::tmp<T>::ptr() const
114 {
115  if (isTmp_)
116  {
117  if (!ptr_)
118  {
119  FatalErrorIn("tmp<T>::ptr() const")
120  << "temporary deallocated"
121  << abort(FatalError);
122  }
123 
124  T* ptr = ptr_;
125  ptr_ = 0;
126 
127  ptr->resetRefCount();
128 
129  return ptr;
130  }
131  else
132  {
133  return new T(ref_);
134  }
135 }
136 
137 
138 template<class T>
139 inline void Foam::tmp<T>::clear() const
140 {
141  if (isTmp_ && ptr_) // skip this bit: && ptr_->okToDelete())
142  {
143  delete ptr_;
144  ptr_ = 0;
145  }
146 }
147 
148 
149 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
150 
151 template<class T>
153 {
154  if (isTmp_)
155  {
156  if (!ptr_)
157  {
158  FatalErrorIn("T& tmp<T>::operator()()")
159  << "temporary deallocated"
160  << abort(FatalError);
161  }
162 
163  return *ptr_;
164  }
165  else
166  {
167  // Note: const is cast away!
168  // Perhaps there should be two refs, one for const and one for non const
169  // and if the ref is actually const then you cannot return it here.
170  //
171  // Another possibility would be to store a const ref and a flag to say
172  // whether the tmp was constructed with a const or a non-const argument.
173  //
174  // eg, enum refType { POINTER = 0, REF = 1, CONSTREF = 2 };
175  return const_cast<T&>(ref_);
176  }
177 }
178 
179 
180 template<class T>
181 inline const T& Foam::tmp<T>::operator()() const
182 {
183  if (isTmp_)
184  {
185  if (!ptr_)
186  {
187  FatalErrorIn("const T& tmp<T>::operator()() const")
188  << "temporary deallocated"
189  << abort(FatalError);
190  }
191 
192  return *ptr_;
193  }
194  else
195  {
196  return ref_;
197  }
198 }
199 
200 
201 template<class T>
202 inline Foam::tmp<T>::operator const T&() const
203 {
204  return operator()();
205 }
206 
207 
208 template<class T>
210 {
211  if (isTmp_)
212  {
213  if (!ptr_)
214  {
215  FatalErrorIn("tmp<T>::operator->()")
216  << "temporary deallocated"
217  << abort(FatalError);
218  }
219 
220  return ptr_;
221  }
222  else
223  {
224  return &const_cast<T&>(ref_);
225  }
226 }
227 
228 
229 template<class T>
230 inline const T* Foam::tmp<T>::operator->() const
231 {
232  return const_cast<tmp<T>&>(*this).operator->();
233 }
234 
235 
236 template<class T>
237 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
238 {
239  if (isTmp_ && ptr_)
240  {
241  if (ptr_->okToDelete())
242  {
243  delete ptr_;
244  ptr_ = 0;
245  }
246  else
247  {
248  ptr_->operator--();
249  }
250  }
251 
252  if (t.isTmp_)
253  {
254  isTmp_ = true;
255  ptr_ = t.ptr_;
256 
257  if (ptr_)
258  {
259  ptr_->operator++();
260  }
261  else
262  {
263  FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
264  << "attempted copy of a deallocated temporary"
265  << abort(FatalError);
266  }
267  }
268  else
269  {
270  FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
271  << "attempted to assign to a const reference to constant object"
272  << abort(FatalError);
273  }
274 }
275 
276 
277 // ************************ vim: set sw=4 sts=4 et: ************************ //