/*--------------------------------------------------------------------r-------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 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" #include // * * * * * * * * * * * * * Private Member Operators * * * * * * * * * * * // template inline void Foam::tmp::operator++() { ptr_->operator++(); if (ptr_->count() > 1) { FatalErrorInFunction << "Attempt to create more than 2 tmp's referring to" " the same object of type " << typeName() << abort(FatalError); } } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline Foam::tmp::tmp(T* tPtr) : type_(TMP), ptr_(tPtr) { if (tPtr && !tPtr->unique()) { FatalErrorInFunction << "Attempted construction of a " << typeName() << " from non-unique pointer" << abort(FatalError); } } template inline Foam::tmp::tmp(const T& tRef) : type_(CONST_REF), ptr_(const_cast(&tRef)) {} template inline Foam::tmp::tmp(const tmp& t) : type_(t.type_), ptr_(t.ptr_) { if (isTmp()) { if (ptr_) { operator++(); } else { FatalErrorInFunction << "Attempted copy of a deallocated " << typeName() << abort(FatalError); } } } template inline Foam::tmp::tmp(const tmp&& t) : type_(t.type_), ptr_(t.ptr_) { if (isTmp()) { t.ptr_ = 0; } } template inline Foam::tmp::tmp(const tmp& t, bool allowTransfer) : type_(t.type_), ptr_(t.ptr_) { if (isTmp()) { if (ptr_) { if (allowTransfer) { t.ptr_ = 0; } else { operator++(); } } else { FatalErrorInFunction << "Attempted copy of a deallocated " << typeName() << abort(FatalError); } } } template inline Foam::tmp::~tmp() { clear(); } // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template inline bool Foam::tmp::isTmp() const { return type_ == TMP; } template inline bool Foam::tmp::empty() const { return (isTmp() && !ptr_); } template inline bool Foam::tmp::valid() const { return (!isTmp() || (isTmp() && ptr_)); } template inline Foam::word Foam::tmp::typeName() const { return "tmp<" + word(typeid(T).name()) + '>'; } template inline T& Foam::tmp::ref() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } else { FatalErrorInFunction << "Attempt to acquire non-const reference to const object" << " from a " << typeName() << abort(FatalError); } return *ptr_; } template inline T* Foam::tmp::ptr() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } if (!ptr_->unique()) { FatalErrorInFunction << "Attempt to acquire pointer to object referred to" << " by multiple temporaries of type " << typeName() << abort(FatalError); } T* ptr = ptr_; ptr_ = 0; return ptr; } else { return new T(*ptr_); } } template inline void Foam::tmp::clear() const { if (isTmp() && ptr_) { if (ptr_->unique()) { delete ptr_; ptr_ = 0; } else { ptr_->operator--(); ptr_ = 0; } } } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // #ifdef NON_CONST_TMP template inline T& Foam::tmp::operator()() { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } // Const-ness is automatically cast-away which is why this operator is // deprecated. Use ref() where non-const access is required. return *ptr_; } #endif template inline const T& Foam::tmp::operator()() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } // Return const reference return *ptr_; } template inline Foam::tmp::operator const T&() const { return operator()(); } template inline T* Foam::tmp::operator->() { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } else { FatalErrorInFunction << "Attempt to cast const object to non-const for a " << typeName() << abort(FatalError); } return ptr_; } template inline const T* Foam::tmp::operator->() const { if (isTmp() && !ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } return ptr_; } template inline void Foam::tmp::operator=(T* tPtr) { clear(); if (!tPtr) { FatalErrorInFunction << "Attempted copy of a deallocated " << typeName() << abort(FatalError); } if (tPtr && !tPtr->unique()) { FatalErrorInFunction << "Attempted assignment of a " << typeName() << " to non-unique pointer" << abort(FatalError); } type_ = TMP; ptr_ = tPtr; } template inline void Foam::tmp::operator=(const tmp& t) { clear(); if (t.isTmp()) { type_ = TMP; if (!t.ptr_) { FatalErrorInFunction << "Attempted assignment to a deallocated " << typeName() << abort(FatalError); } ptr_ = t.ptr_; t.ptr_ = 0; } else { FatalErrorInFunction << "Attempted assignment to a const reference to an object" << " of type " << typeid(T).name() << abort(FatalError); } } //- Return the const reference of the non-const reference argument template inline const T& Const(T& t) { return t; } //- Return the const reference of the non-const rvalue reference argument template inline const T& Const(T&& t) { return t; } // ************************************************************************* //