/********************************************************************************
* *
* 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