Program Listing for File object.h¶
↰ Return to documentation for file (nanogui/object.h
)
/*
nanogui/object.h -- Object base class with support for reference counting
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
The widget drawing code is based on the NanoVG demo application
by Mikko Mononen.
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE.txt file.
*/
#pragma once
#include <nanogui/common.h>
#include <atomic>
NAMESPACE_BEGIN(nanogui)
class NANOGUI_EXPORT Object {
public:
Object() { }
Object(const Object &) : m_refCount(0) {}
int getRefCount() const { return m_refCount; };
void incRef() const { ++m_refCount; }
void decRef(bool dealloc = true) const noexcept;
protected:
virtual ~Object();
private:
mutable std::atomic<int> m_refCount { 0 };
};
template <typename T> class ref {
public:
ref() { }
ref(T *ptr) : m_ptr(ptr) {
if (m_ptr)
((Object *) m_ptr)->incRef();
}
ref(const ref &r) : m_ptr(r.m_ptr) {
if (m_ptr)
((Object *) m_ptr)->incRef();
}
ref(ref &&r) noexcept : m_ptr(r.m_ptr) {
r.m_ptr = nullptr;
}
~ref() {
if (m_ptr)
((Object *) m_ptr)->decRef();
}
ref& operator=(ref&& r) noexcept {
if (&r != this) {
if (m_ptr)
((Object *) m_ptr)->decRef();
m_ptr = r.m_ptr;
r.m_ptr = nullptr;
}
return *this;
}
ref& operator=(const ref& r) noexcept {
if (m_ptr != r.m_ptr) {
if (r.m_ptr)
((Object *) r.m_ptr)->incRef();
if (m_ptr)
((Object *) m_ptr)->decRef();
m_ptr = r.m_ptr;
}
return *this;
}
ref& operator=(T *ptr) noexcept {
if (m_ptr != ptr) {
if (ptr)
((Object *) ptr)->incRef();
if (m_ptr)
((Object *) m_ptr)->decRef();
m_ptr = ptr;
}
return *this;
}
bool operator==(const ref &r) const { return m_ptr == r.m_ptr; }
bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; }
bool operator==(const T* ptr) const { return m_ptr == ptr; }
bool operator!=(const T* ptr) const { return m_ptr != ptr; }
T* operator->() { return m_ptr; }
const T* operator->() const { return m_ptr; }
T& operator*() { return *m_ptr; }
const T& operator*() const { return *m_ptr; }
operator T* () { return m_ptr; }
T* get() { return m_ptr; }
const T* get() const { return m_ptr; }
operator bool() const { return m_ptr != nullptr; }
private:
T *m_ptr = nullptr;
};
NAMESPACE_END(nanogui)