initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / memory / tmp / tmpI.H
blob39bc90fa9b8dedd38922ec142b126090cf2b2396
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
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.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "error.H"
29 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
31 template<class T>
32 inline Foam::tmp<T>::tmp(T* tPtr)
34     isTmp_(true),
35     ptr_(tPtr),
36     ref_(*tPtr)
40 template<class T>
41 inline Foam::tmp<T>::tmp(const T& tRef)
43     isTmp_(false),
44     ptr_(0),
45     ref_(tRef)
49 template<class T>
50 inline Foam::tmp<T>::tmp(const tmp<T>& t)
52     isTmp_(t.isTmp_),
53     ptr_(t.ptr_),
54     ref_(t.ref_)
56     if (isTmp_)
57     {
58         if (ptr_)
59         {
60             ptr_->operator++();
61         }
62         else
63         {
64             FatalErrorIn("tmp<T>::tmp(const tmp<T>&)")
65                 << "attempted copy of a deallocated temporary"
66                 << abort(FatalError);
67         }
68     }
72 template<class T>
73 inline Foam::tmp<T>::~tmp()
75     if (isTmp_ && ptr_)
76     {
77         if (ptr_->okToDelete())
78         {
79             delete ptr_;
80             ptr_ = 0;
81         }
82         else
83         {
84             ptr_->operator--();
85         }
86     }
90 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
92 template<class T>
93 inline bool Foam::tmp<T>::isTmp() const
95     return isTmp_;
99 template<class T>
100 inline bool Foam::tmp<T>::empty() const
102     return (isTmp_ && !ptr_);
106 template<class T>
107 inline bool Foam::tmp<T>::valid() const
109     return (!isTmp_ || (isTmp_ && ptr_));
113 template<class T>
114 inline T* Foam::tmp<T>::ptr() const
116     if (isTmp_)
117     {
118          if (!ptr_)
119          {
120              FatalErrorIn("tmp<T>::ptr() const")
121                  << "temporary deallocated"
122                  << abort(FatalError);
123          }
125          T* ptr = ptr_;
126          ptr_ = 0;
128          ptr->resetRefCount();
130          return ptr;
131     }
132     else
133     {
134         return new T(ref_);
135     }
139 template<class T>
140 inline void Foam::tmp<T>::clear() const
142     if (isTmp_ && ptr_)  // skip this bit:  && ptr_->okToDelete())
143     {
144         delete ptr_;
145         ptr_ = 0;
146     }
150 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
152 template<class T>
153 inline T& Foam::tmp<T>::operator()()
155     if (isTmp_)
156     {
157         if (!ptr_)
158         {
159             FatalErrorIn("T& tmp<T>::operator()()")
160                 << "temporary deallocated"
161                 << abort(FatalError);
162         }
164         return *ptr_;
165     }
166     else
167     {
168         // Note: const is cast away!
169         // Perhaps there should be two refs, one for const and one for non const
170         // and if the ref is actually const then you cannot return it here.
171         //
172         // Another possibility would be to store a const ref and a flag to say
173         // whether the tmp was constructed with a const or a non-const argument.
174         //
175         // eg, enum refType { POINTER = 0, REF = 1, CONSTREF = 2 };
176         return const_cast<T&>(ref_);
177     }
181 template<class T>
182 inline const T& Foam::tmp<T>::operator()() const
184     if (isTmp_)
185     {
186         if (!ptr_)
187         {
188             FatalErrorIn("const T& tmp<T>::operator()() const")
189                 << "temporary deallocated"
190                 << abort(FatalError);
191         }
193         return *ptr_;
194     }
195     else
196     {
197         return ref_;
198     }
202 template<class T>
203 inline Foam::tmp<T>::operator const T&() const
205     return operator()();
209 template<class T>
210 inline T* Foam::tmp<T>::operator->()
212     if (isTmp_)
213     {
214          if (!ptr_)
215          {
216              FatalErrorIn("tmp<T>::operator->()")
217                  << "temporary deallocated"
218                  << abort(FatalError);
219          }
221          return ptr_;
222     }
223     else
224     {
225         return &const_cast<T&>(ref_);
226     }
230 template<class T>
231 inline const T* Foam::tmp<T>::operator->() const
233     return const_cast<tmp<T>&>(*this).operator->();
237 template<class T>
238 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
240     if (isTmp_ && ptr_)
241     {
242         if (ptr_->okToDelete())
243         {
244             delete ptr_;
245             ptr_ = 0;
246         }
247         else
248         {
249             ptr_->operator--();
250         }
251     }
253     if (t.isTmp_)
254     {
255         isTmp_ = true;
256         ptr_ = t.ptr_;
258         if (ptr_)
259         {
260             ptr_->operator++();
261         }
262         else
263         {
264             FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
265                 << "attempted copy of a deallocated temporary"
266                 << abort(FatalError);
267         }
268     }
269     else
270     {
271         FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
272             << "attempted to assign to a const reference to constant object"
273             << abort(FatalError);
274     }
278 // ************************************************************************* //