/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation ------------------------------------------------------------------------------- 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); } } // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // template template inline Foam::tmp Foam::tmp::New(Args&&... args) { return tmp(new T(std::forward(args)...)); } template template inline Foam::tmp Foam::tmp::NewFrom(Args&&... args) { return tmp(new U(std::forward(args)...)); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template inline constexpr Foam::tmp::tmp() noexcept : ptr_(nullptr), type_(PTR) {} template inline constexpr Foam::tmp::tmp(std::nullptr_t) noexcept : ptr_(nullptr), type_(PTR) {} template inline Foam::tmp::tmp(T* p) : ptr_(p), type_(PTR) { if (p && !p->unique()) { FatalErrorInFunction << "Attempted construction of a " << typeName() << " from non-unique pointer" << abort(FatalError); } } template inline Foam::tmp::tmp(const T& obj) noexcept : ptr_(const_cast(&obj)), type_(CREF) {} template inline Foam::tmp::tmp(tmp&& t) noexcept : ptr_(t.ptr_), type_(t.type_) { t.ptr_ = nullptr; t.type_ = PTR; } template inline Foam::tmp::tmp(const tmp&& t) noexcept : ptr_(t.ptr_), type_(t.type_) { t.ptr_ = nullptr; t.type_ = PTR; } template inline Foam::tmp::tmp(const tmp& t) : ptr_(t.ptr_), type_(t.type_) { if (isTmp()) { if (ptr_) { operator++(); } else { FatalErrorInFunction << "Attempted copy of a deallocated " << typeName() << abort(FatalError); } } } template inline Foam::tmp::tmp(const tmp& t, bool reuse) : ptr_(t.ptr_), type_(t.type_) { if (isTmp()) { if (ptr_) { if (reuse) { t.ptr_ = nullptr; // t.type_ already set as PTR } 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 noexcept { return type_ == PTR; } template inline bool Foam::tmp::empty() const noexcept { return (!ptr_ && isTmp()); } template inline bool Foam::tmp::valid() const noexcept { return (ptr_ || type_ == CREF); } template inline bool Foam::tmp::movable() const noexcept { return (type_ == PTR && ptr_ && ptr_->unique()); } template inline Foam::word Foam::tmp::typeName() const { return "tmp<" + word(typeid(T).name()) + '>'; } template inline T* Foam::tmp::get() noexcept { return ptr_; // non-const pointer } template inline const T* Foam::tmp::get() const noexcept { return ptr_; // const pointer } template inline const T& Foam::tmp::cref() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } return *ptr_; // const reference } template inline T& Foam::tmp::ref() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } } else { FatalErrorInFunction << "Attempted non-const reference to const object from a " << typeName() << abort(FatalError); } return *ptr_; // non-const reference } template inline T& Foam::tmp::constCast() const { if (isTmp() && !ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } return const_cast(*ptr_); } template inline T* Foam::tmp::ptr() const { if (isTmp()) { if (!ptr_) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } else if (!ptr_->unique()) { FatalErrorInFunction << "Attempt to acquire pointer to object referred to" << " by multiple temporaries of type " << typeName() << abort(FatalError); } T* ptr = ptr_; ptr_ = nullptr; return ptr; } return ptr_->clone().ptr(); } template inline void Foam::tmp::clear() const noexcept { if (isTmp() && ptr_) { if (ptr_->unique()) { delete ptr_; } else { ptr_->operator--(); } ptr_ = nullptr; } } template inline void Foam::tmp::reset() noexcept { clear(); ptr_ = nullptr; type_ = PTR; } template inline void Foam::tmp::reset(T* p) noexcept { clear(); ptr_ = p; type_ = PTR; } template inline void Foam::tmp::cref(const T& obj) noexcept { clear(); ptr_ = const_cast(&obj); type_ = CREF; } template inline void Foam::tmp::swap(tmp& other) noexcept { // Copy/assign for pointer types T* p = ptr_; ptr_ = other.ptr_; other.ptr_ = p; refType t = type_; type_ = other.type_; other.type_ = t; } // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template inline const T& Foam::tmp::operator()() const { return cref(); } template inline Foam::tmp::operator const T&() const { return cref(); } template inline const T* Foam::tmp::operator->() const { if (!ptr_ && isTmp()) { FatalErrorInFunction << typeName() << " deallocated" << abort(FatalError); } return ptr_; } 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 void Foam::tmp::operator=(T* p) { clear(); if (!p) { FatalErrorInFunction << "Attempted copy of a deallocated " << typeName() << abort(FatalError); } else if (!p->unique()) { FatalErrorInFunction << "Attempted assignment of a " << typeName() << " to non-unique pointer" << abort(FatalError); } ptr_ = p; type_ = PTR; } template inline void Foam::tmp::operator=(const tmp& t) { clear(); if (t.isTmp()) { ptr_ = t.ptr_; type_ = PTR; t.ptr_ = nullptr; if (!ptr_) { FatalErrorInFunction << "Attempted assignment to a deallocated " << typeName() << abort(FatalError); } } else { FatalErrorInFunction << "Attempted assignment to a const reference to an object" << " of type " << typeid(T).name() << abort(FatalError); } } // ************************************************************************* //