OpenFOAM logo
Open Source CFD Toolkit

tmpI.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2005 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software; you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by the
00013     Free Software Foundation; either version 2 of the License, or (at your
00014     option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM; if not, write to the Free Software Foundation,
00023     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00024 
00025 \*---------------------------------------------------------------------------*/
00026 
00027 #include "error.H"
00028 
00029 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00030 
00031 namespace Foam
00032 {
00033 
00034 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00035 
00036 // Store object pointer
00037 template<class T>
00038 inline tmp<T>::tmp(T* tPtr)
00039 :
00040     isTmp_(true),
00041     ptr_(tPtr),
00042     ref_(*tPtr)
00043 {}
00044 
00045 
00046 // Store object const reference
00047 template<class T>
00048 inline tmp<T>::tmp(const T& tRef)
00049 :
00050     isTmp_(false),
00051     ptr_(NULL),
00052     ref_(tRef)
00053 {}
00054 
00055 
00056 // Construct copy (increment reference count if object is temporary)
00057 template<class T>
00058 inline tmp<T>::tmp(const tmp<T>& t)
00059 :
00060     isTmp_(t.isTmp_),
00061     ptr_(t.ptr_),
00062     ref_(t.ref_)
00063 {
00064     if (isTmp_)
00065     {
00066         if (ptr_)
00067         {
00068             ptr_->operator++();
00069         }
00070         else
00071         {
00072             FatalErrorIn("tmp<T>::tmp(const tmp<T>&)")
00073                 << "attempted copy of a deallocated temporary"
00074                 << abort(FatalError);
00075         }
00076     }
00077 }
00078 
00079 
00080 // Delete object
00081 template<class T>
00082 inline tmp<T>::~tmp()
00083 {
00084     if (isTmp_ && ptr_)
00085     {
00086         if (ptr_->okToDelete())
00087         {
00088             delete ptr_;
00089             ptr_ = NULL;
00090         }
00091         else
00092         {
00093             ptr_->operator--();
00094         }
00095     }
00096 }
00097 
00098 
00099 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00100 
00101 template<class T>
00102 inline bool tmp<T>::isTmp() const
00103 {
00104     return isTmp_;
00105 }
00106 
00107 
00108 template<class T>
00109 inline bool tmp<T>::valid() const
00110 {
00111     return (!isTmp_ || (isTmp_ && ptr_));
00112 }
00113 
00114 
00115 // Return tmp pointer for reuse
00116 template<class T>
00117 inline T* tmp<T>::ptr() const
00118 {
00119     if (isTmp_)
00120     {
00121          if (!ptr_)
00122          {
00123              FatalErrorIn("tmp<T>::ptr() const")
00124                  << "temporary deallocated"
00125                  << abort(FatalError);
00126          }
00127 
00128          T* ptr = ptr_;
00129          ptr_ = NULL;
00130 
00131          ptr->resetRefCount();
00132 
00133          return ptr;
00134     }
00135     else
00136     {
00137         return new T(ref_);
00138     }
00139 }
00140 
00141 
00142 // If object pointer points to valid object:
00143 // delete object and set pointer to NULL
00144 
00145 template<class T>
00146 inline void tmp<T>::clear()
00147 {
00148     if (isTmp_ && ptr_) // && ptr_->okToDelete())
00149     {
00150         delete ptr_;
00151         ptr_ = NULL;
00152     }
00153 }
00154 
00155 
00156 template<class T>
00157 inline void tmp<T>::clear() const
00158 {
00159     const_cast<tmp<T>&>(*this).clear();
00160 }
00161 
00162 
00163 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00164 
00165 template<class T>
00166 inline T& tmp<T>::operator()()
00167 {
00168     if (isTmp_)
00169     {
00170         if (!ptr_)
00171         {
00172             FatalErrorIn("T& tmp<T>::operator()()")
00173                 << "temporary deallocated"
00174                 << abort(FatalError);
00175         }
00176 
00177         return *ptr_;
00178     }
00179     else
00180     {
00181         // Note: const is cast away!
00182         // Perhaps there should be two refs, one for const and one for non const
00183         // and if the ref is actually const then you cannot return it here.
00184         // Another possibility would be to store a const ref and a flag to say
00185         // wether the tmp was constructed with a const or a non-const argument.
00186         return const_cast<T&>(ref_);
00187     }
00188 }
00189 
00190 
00191 template<class T>
00192 inline const T& tmp<T>::operator()() const
00193 {
00194     if (isTmp_)
00195     {
00196         if (!ptr_)
00197         {
00198             FatalErrorIn("const T& tmp<T>::operator()() const")
00199                 << "temporary deallocated"
00200                 << abort(FatalError);
00201         }
00202 
00203         return *ptr_;
00204     }
00205     else
00206     {
00207         return ref_;
00208     }
00209 }
00210 
00211 
00212 template<class T>
00213 inline tmp<T>::operator const T&() const
00214 {
00215     return operator()();
00216 }
00217 
00218 
00219 // Return object pointer
00220 template<class T>
00221 inline T* tmp<T>::operator->()
00222 {
00223     if (isTmp_)
00224     {
00225          if (!ptr_)
00226          {
00227              FatalErrorIn("tmp<T>::operator->()")
00228                  << "temporary deallocated"
00229                  << abort(FatalError);
00230          }
00231 
00232          return ptr_;
00233     }
00234     else
00235     {
00236         return &const_cast<T&>(ref_);
00237     }
00238 }
00239 
00240 
00241 // Return object pointer
00242 template<class T>
00243 inline const T* tmp<T>::operator->() const
00244 {
00245     return const_cast<tmp<T>&>(*this).operator->();
00246 }
00247 
00248 
00249 template<class T>
00250 inline void tmp<T>::operator=(const tmp<T>& t)
00251 {
00252     clear();
00253 
00254     if (t.isTmp_)
00255     {
00256         isTmp_ = true;
00257         ptr_ = t.ptr_;
00258 
00259         if (ptr_)
00260         {
00261             ptr_->operator++();
00262         }
00263         else
00264         {
00265             FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
00266                 << "attempted copy of a deallocated temporary"
00267                 << abort(FatalError);
00268         }
00269     }
00270     else
00271     {
00272         FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
00273             << "attempted to assign to a const reference to constant object"
00274             << abort(FatalError);
00275     }
00276 }
00277 
00278 
00279 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00280 
00281 } // End namespace Foam
00282 
00283 // ************************************************************************* //
For further information go to www.openfoam.org