/******************************************************************************** * * * A u t o m a t i c P o i n t e r * * * ********************************************************************************* * Copyright (C) 2007,2024 by Jeroen van der Zijp. All Rights Reserved. * ********************************************************************************* * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This library 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 Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see * ********************************************************************************/ #ifndef FXAUTOPTR_H #define FXAUTOPTR_H namespace FX { /// Implicitly used FXAutoPtrRef to hand FXAutoPtr through implicitly called /// constructors and conversion operators. Probably not used directly. template struct FXAutoPtrRef { EType* ptr; explicit FXAutoPtrRef(EType* src):ptr(src){ } }; /// Automatic pointer template class FXAutoPtr { private: EType* ptr; public: /// Construct from optional pointer explicit FXAutoPtr(EType* src=nullptr):ptr(src){ } /// Construct from another automatic pointer FXAutoPtr(FXAutoPtr& src):ptr(src.release()){ } /// Construct from FXAutoPtrRef FXAutoPtr(FXAutoPtrRef src):ptr(src.ptr){ } /// Construct from another automatic pointer of compatible type template explicit FXAutoPtr(FXAutoPtr& src):ptr(src.release()){ } /// Assign from pointer FXAutoPtr& operator=(EType *src){ return reset(src); } /// Assign from an another automatic pointer FXAutoPtr& operator=(FXAutoPtr& src){ return reset(src.release()); } /// Assign from FXAutoPtrRef FXAutoPtr& operator=(FXAutoPtrRef src){ if(src.ptr!=ptr){ delete ptr; ptr=src.ptr; } return *this; } /// Assign from an automatic pointer with compatible type template FXAutoPtr& operator=(FXAutoPtr& src){ return reset(src.release()); } /// Conversion operators operator EType*() const { return ptr; } /// Conversion to FXAutoPtr of another type T template operator FXAutoPtr() throw() { return FXAutoPtr(this->release()); } /// Conversion to FXAutoPtrRef of another type T template operator FXAutoPtrRef() throw() { return FXAutoPtrRef(this->release()); } /// Dereference operator EType& operator*() const { return *ptr; } /// Follow pointer operator EType* operator->() const { return ptr; } /// Array indexing EType& operator[](FXival i) const { return ptr[i]; } /// Release hold on the pointer EType* release(){ EType* tmp=ptr; ptr=nullptr; return tmp; } /// Delete old object, replace by new, if any FXAutoPtr& reset(EType* p=nullptr){ if(p!=ptr){ delete ptr; ptr=p; } return *this; } /// Destruction deletes pointer ~FXAutoPtr(){ delete ptr; } }; /// Serialize of automatic pointer template FXStream& operator<<(FXStream& store,const FXAutoPtr& obj){ EType *temp=obj; store << temp; return store; } /// Deserialize of automatic pointer template FXStream& operator>>(FXStream& store,FXAutoPtr& obj){ EType *temp; store >> temp; obj=temp; return store; } } #endif