/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see . \*---------------------------------------------------------------------------*/ #include "error.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline Foam::tmp::tmp(T* tPtr) : isTmp_(true), ptr_(tPtr), ref_(*tPtr) {} template inline Foam::tmp::tmp(const T& tRef) : isTmp_(false), ptr_(0), ref_(tRef) {} template inline Foam::tmp::tmp(const tmp& t) : isTmp_(t.isTmp_), ptr_(t.ptr_), ref_(t.ref_) { if (isTmp_) { if (ptr_) { ptr_->operator++(); } else { FatalErrorIn("Foam::tmp::tmp(const tmp&)") << "attempted copy of a deallocated temporary" << abort(FatalError); } } } template inline Foam::tmp::tmp(const tmp& t, bool allowTransfer) : isTmp_(t.isTmp_), ptr_(t.ptr_), ref_(t.ref_) { if (isTmp_) { if (allowTransfer) { const_cast&>(t).ptr_ = 0; } else { if (ptr_) { ptr_->operator++(); } else { FatalErrorIn ( "Foam::tmp::tmp(const tmp&, bool allowTransfer)" ) << "attempted copy of a deallocated temporary" << abort(FatalError); } } } } template inline Foam::tmp::~tmp() { if (isTmp_ && ptr_) { if (ptr_->okToDelete()) { delete ptr_; ptr_ = 0; } else { ptr_->operator--(); } } } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template inline bool Foam::tmp::isTmp() const { return isTmp_; } template inline bool Foam::tmp::empty() const { return (isTmp_ && !ptr_); } template inline bool Foam::tmp::valid() const { return (!isTmp_ || (isTmp_ && ptr_)); } template inline T* Foam::tmp::ptr() const { if (isTmp_) { if (!ptr_) { FatalErrorIn("Foam::tmp::ptr() const") << "temporary deallocated" << abort(FatalError); } T* ptr = ptr_; ptr_ = 0; ptr->resetRefCount(); return ptr; } else { return new T(ref_); } } template inline void Foam::tmp::clear() const { if (isTmp_ && ptr_) // skip this bit: && ptr_->okToDelete()) { delete ptr_; ptr_ = 0; } } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template inline T& Foam::tmp::operator()() { if (isTmp_) { if (!ptr_) { FatalErrorIn("T& Foam::tmp::operator()()") << "temporary deallocated" << abort(FatalError); } return *ptr_; } else { // Note: const is cast away! // Perhaps there should be two refs, one for const and one for non const // and if the ref is actually const then you cannot return it here. // // Another possibility would be to store a const ref and a flag to say // whether the tmp was constructed with a const or a non-const argument. // // eg, enum refType { POINTER = 0, REF = 1, CONSTREF = 2 }; return const_cast(ref_); } } template inline const T& Foam::tmp::operator()() const { if (isTmp_) { if (!ptr_) { FatalErrorIn("const T& Foam::tmp::operator()() const") << "temporary deallocated" << abort(FatalError); } return *ptr_; } else { return ref_; } } template inline Foam::tmp::operator const T&() const { return operator()(); } template inline T* Foam::tmp::operator->() { if (isTmp_) { if (!ptr_) { FatalErrorIn("Foam::tmp::operator->()") << "temporary deallocated" << abort(FatalError); } return ptr_; } else { return &const_cast(ref_); } } template inline const T* Foam::tmp::operator->() const { return const_cast&>(*this).operator->(); } template inline void Foam::tmp::operator=(const tmp& t) { if (isTmp_ && ptr_) { if (ptr_->okToDelete()) { delete ptr_; ptr_ = 0; } else { ptr_->operator--(); } } if (t.isTmp_) { isTmp_ = true; ptr_ = t.ptr_; if (ptr_) { ptr_->operator++(); } else { FatalErrorIn("Foam::tmp::operator=(const tmp&)") << "attempted copy of a deallocated temporary" << abort(FatalError); } } else { FatalErrorIn("Foam::tmp::operator=(const tmp&)") << "attempted to assign to a const reference to constant object" << abort(FatalError); } } // ************************************************************************* //