/********************************************************************************
* *
* R e f e r e n c e C o u n t e d O b j e c t P o i n t e r *
* *
*********************************************************************************
* Copyright (C) 2004,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 FXREFPTR_H
#define FXREFPTR_H
namespace FX {
/// Pointer to shared object
template
class FXRefPtr {
private:
EType* ptr;
public:
/// Default constructor
FXRefPtr():ptr(nullptr){
}
/// Construct and init
FXRefPtr(EType* p):ptr(p){
if(ptr) ptr->ref();
}
/// Copy constructor
FXRefPtr(const FXRefPtr& org):ptr(org.ptr){
if(ptr) ptr->ref();
}
/// Copy constructor from shared pointer of compatible type
template FXRefPtr(FXRefPtr& org):ptr(org.ptr){
if(ptr) ptr->ref();
}
/// Swap this and other, pain-free
FXRefPtr& swap(FXRefPtr& other){
other.ptr=atomicSet(&ptr,other.ptr);
return *this;
}
/// Assignment
FXRefPtr& operator=(EType* src){
FXRefPtr tmp(src);
swap(tmp);
return *this;
}
/// Assignment
FXRefPtr& operator=(const FXRefPtr& src){
FXRefPtr tmp(src);
swap(tmp);
return *this;
}
/// Assignment from shared pointer of compatible type
template FXRefPtr& operator=(FXRefPtr& src){
FXRefPtr tmp(src);
swap(tmp);
return *this;
}
/// Conversion operators
operator EType*() const { return ptr; }
/// Dereference operator
EType& operator*() const { return *ptr; }
/// Follow pointer operator
EType* operator->() const { return ptr; }
/// Test for non-null
operator FXbool() const { return !!ptr; }
/// Test for NULL
FXbool operator!() const { return !ptr; }
/// Comparison operator.
FXbool operator==(EType *p) const { return ptr==p; }
/// Comparison operator.
FXbool operator!=(EType *p) const { return ptr!=p; }
/// Return pointer value
EType* get() const { return ptr; }
/// Clear pointer
void clear(){
FXRefPtr tmp;
swap(tmp);
}
/// Destructor
~FXRefPtr(){
if(ptr) ptr->unref();
}
};
/// Serialize of reference counted pointer
template FXStream& operator<<(FXStream& store,const FXRefPtr& obj){
EType *temp=obj; store << temp; return store;
}
/// Deserialize of reference counted pointer
template FXStream& operator>>(FXStream& store,FXRefPtr& obj){
EType *temp; store >> temp; obj=temp; return store;
}
}
#endif