Skip to content

Instantly share code, notes, and snippets.

@6502
Created October 23, 2016 21:09
Show Gist options
  • Save 6502/4edd488cc29a0ace920db8501e85e2c6 to your computer and use it in GitHub Desktop.
Save 6502/4edd488cc29a0ace920db8501e85e2c6 to your computer and use it in GitHub Desktop.
A simple intrusive reference counter approach (referenced instances must have a `refcount` integer but don't need to derive from `RefCounted`)
#if !defined(REFCOUNT_H_INCLUDED)
#define REFCOUNT_H_INCLUDED
#include <atomic>
#include <algorithm>
struct RefCounted {
std::atomic_int refcount;
RefCounted() : refcount(0) {}
};
template<typename T>
struct Ref {
T *p;
template<typename U>
Ref(U *p) : p(p) {
if (p) p->refcount++;
}
template<typename U>
Ref(const Ref<U>& other) : p(other.p) {
if (p) p->refcount++;
}
void swap(Ref& other) {
std::swap(p, other.p);
}
template<typename U>
Ref& operator=(const Ref<U>& other) {
swap(Ref(other.p));
return *this;
}
template<typename U>
Ref& operator=(U *u) {
swap(Ref(u));
return *this;
}
Ref(const Ref& other) : p(other.p) {
if (p) p->refcount++;
}
Ref& operator=(const Ref& other) {
swap(Ref(other.p));
return *this;
}
Ref& operator=(std::nullptr_t) {
if (p && --p->refcount==0) delete p;
p = nullptr;
return *this;
}
~Ref() {
if (p && --p->refcount==0) delete p;
}
T* operator->() {
return p;
}
const T* operator->() const {
return p;
}
T& operator*() {
return *p;
}
const T& operator*() const {
return *p;
}
operator bool() const {
return p;
}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment