FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

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-2010 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
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your 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, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include <OpenFOAM/error.H>
00027 
00028 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00029 
00030 template<class T>
00031 inline Foam::tmp<T>::tmp(T* tPtr)
00032 :
00033     isTmp_(true),
00034     ptr_(tPtr),
00035     ref_(*tPtr)
00036 {}
00037 
00038 
00039 template<class T>
00040 inline Foam::tmp<T>::tmp(const T& tRef)
00041 :
00042     isTmp_(false),
00043     ptr_(0),
00044     ref_(tRef)
00045 {}
00046 
00047 
00048 template<class T>
00049 inline Foam::tmp<T>::tmp(const tmp<T>& t)
00050 :
00051     isTmp_(t.isTmp_),
00052     ptr_(t.ptr_),
00053     ref_(t.ref_)
00054 {
00055     if (isTmp_)
00056     {
00057         if (ptr_)
00058         {
00059             ptr_->operator++();
00060         }
00061         else
00062         {
00063             FatalErrorIn("tmp<T>::tmp(const tmp<T>&)")
00064                 << "attempted copy of a deallocated temporary"
00065                 << abort(FatalError);
00066         }
00067     }
00068 }
00069 
00070 
00071 template<class T>
00072 inline Foam::tmp<T>::~tmp()
00073 {
00074     if (isTmp_ && ptr_)
00075     {
00076         if (ptr_->okToDelete())
00077         {
00078             delete ptr_;
00079             ptr_ = 0;
00080         }
00081         else
00082         {
00083             ptr_->operator--();
00084         }
00085     }
00086 }
00087 
00088 
00089 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00090 
00091 template<class T>
00092 inline bool Foam::tmp<T>::isTmp() const
00093 {
00094     return isTmp_;
00095 }
00096 
00097 
00098 template<class T>
00099 inline bool Foam::tmp<T>::empty() const
00100 {
00101     return (isTmp_ && !ptr_);
00102 }
00103 
00104 
00105 template<class T>
00106 inline bool Foam::tmp<T>::valid() const
00107 {
00108     return (!isTmp_ || (isTmp_ && ptr_));
00109 }
00110 
00111 
00112 template<class T>
00113 inline T* Foam::tmp<T>::ptr() const
00114 {
00115     if (isTmp_)
00116     {
00117          if (!ptr_)
00118          {
00119              FatalErrorIn("tmp<T>::ptr() const")
00120                  << "temporary deallocated"
00121                  << abort(FatalError);
00122          }
00123 
00124          T* ptr = ptr_;
00125          ptr_ = 0;
00126 
00127          ptr->resetRefCount();
00128 
00129          return ptr;
00130     }
00131     else
00132     {
00133         return new T(ref_);
00134     }
00135 }
00136 
00137 
00138 template<class T>
00139 inline void Foam::tmp<T>::clear() const
00140 {
00141     if (isTmp_ && ptr_)  // skip this bit:  && ptr_->okToDelete())
00142     {
00143         delete ptr_;
00144         ptr_ = 0;
00145     }
00146 }
00147 
00148 
00149 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00150 
00151 template<class T>
00152 inline T& Foam::tmp<T>::operator()()
00153 {
00154     if (isTmp_)
00155     {
00156         if (!ptr_)
00157         {
00158             FatalErrorIn("T& tmp<T>::operator()()")
00159                 << "temporary deallocated"
00160                 << abort(FatalError);
00161         }
00162 
00163         return *ptr_;
00164     }
00165     else
00166     {
00167         // Note: const is cast away!
00168         // Perhaps there should be two refs, one for const and one for non const
00169         // and if the ref is actually const then you cannot return it here.
00170         //
00171         // Another possibility would be to store a const ref and a flag to say
00172         // whether the tmp was constructed with a const or a non-const argument.
00173         //
00174         // eg, enum refType { POINTER = 0, REF = 1, CONSTREF = 2 };
00175         return const_cast<T&>(ref_);
00176     }
00177 }
00178 
00179 
00180 template<class T>
00181 inline const T& Foam::tmp<T>::operator()() const
00182 {
00183     if (isTmp_)
00184     {
00185         if (!ptr_)
00186         {
00187             FatalErrorIn("const T& tmp<T>::operator()() const")
00188                 << "temporary deallocated"
00189                 << abort(FatalError);
00190         }
00191 
00192         return *ptr_;
00193     }
00194     else
00195     {
00196         return ref_;
00197     }
00198 }
00199 
00200 
00201 template<class T>
00202 inline Foam::tmp<T>::operator const T&() const
00203 {
00204     return operator()();
00205 }
00206 
00207 
00208 template<class T>
00209 inline T* Foam::tmp<T>::operator->()
00210 {
00211     if (isTmp_)
00212     {
00213          if (!ptr_)
00214          {
00215              FatalErrorIn("tmp<T>::operator->()")
00216                  << "temporary deallocated"
00217                  << abort(FatalError);
00218          }
00219 
00220          return ptr_;
00221     }
00222     else
00223     {
00224         return &const_cast<T&>(ref_);
00225     }
00226 }
00227 
00228 
00229 template<class T>
00230 inline const T* Foam::tmp<T>::operator->() const
00231 {
00232     return const_cast<tmp<T>&>(*this).operator->();
00233 }
00234 
00235 
00236 template<class T>
00237 inline void Foam::tmp<T>::operator=(const tmp<T>& t)
00238 {
00239     if (isTmp_ && ptr_)
00240     {
00241         if (ptr_->okToDelete())
00242         {
00243             delete ptr_;
00244             ptr_ = 0;
00245         }
00246         else
00247         {
00248             ptr_->operator--();
00249         }
00250     }
00251 
00252     if (t.isTmp_)
00253     {
00254         isTmp_ = true;
00255         ptr_ = t.ptr_;
00256 
00257         if (ptr_)
00258         {
00259             ptr_->operator++();
00260         }
00261         else
00262         {
00263             FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
00264                 << "attempted copy of a deallocated temporary"
00265                 << abort(FatalError);
00266         }
00267     }
00268     else
00269     {
00270         FatalErrorIn("tmp<T>::operator=(const tmp<T>& t)")
00271             << "attempted to assign to a const reference to constant object"
00272             << abort(FatalError);
00273     }
00274 }
00275 
00276 
00277 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines