Skip to content

Instantly share code, notes, and snippets.

@rightfold
Last active August 29, 2015 14:15
Show Gist options
  • Save rightfold/7babd30f92fc950b53df to your computer and use it in GitHub Desktop.
Save rightfold/7babd30f92fc950b53df to your computer and use it in GitHub Desktop.
class GCPtr {
public:
explicit GCPtr(GC& gc, std::nullptr_t = nullptr) noexcept
: object(nullptr), gc(&gc) { }
GCPtr(GC& gc, Object* object) noexcept
: object(object), gc(&gc) {
assert(gc->ownsObject(newObject));
gc->discoverGCPtr(*this);
}
GCPtr(GCPtr&& other) noexcept
: object(other.object), gc(other.gc) {
gc->discoverGCPtr(*this);
other.reset();
}
GCPtr(GCPtr const& other) noexcept
: object(other.object), gc(other.gc) {
gc->discoverGCPtr(*this);
}
~GCPtr() {
gc->forgetGCPtr(*this);
}
GCPtr& operator=(GCPtr&& other) noexcept {
swap(other);
other.reset();
}
GCPtr& operator=(GCPtr other) noexcept {
swap(other);
}
GCPtr& operator=(std::nullptr_t) noexcept {
gc->forgetGCPtr(*this);
reset();
}
Object* release() noexcept {
gc->forgetGCPtr(*this);
auto result = object;
reset();
return result;
}
void reset(Object* newObject) noexcept {
assert(gc->ownsObject(newObject));
object = newObject;
}
void reset(std::nullptr_t = nullptr) noexcept {
gc->forgetGCPtr(*this);
object = nullptr;
}
void swap(GCPtr& other) noexcept {
gc->forgetGCPtr(*this);
gc->forgetGCPtr(other);
std::swap(object, other.object);
std::swap(gc, other.gc);
gc->discoverGCPtr(*this);
gc->discoverGCPtr(other);
}
Object* get() const noexcept {
return object;
}
explicit operator bool() const noexcept {
return object;
}
typename Object& operator*() const noexcept {
return *object;
}
Object* operator->() const noexcept {
return object;
}
private:
Object* object;
GC* gc;
friend class GC;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment