BooObject: Make SObjToken interface noexcept where applicable

Now that decrement() doesn't lock a mutex every time its executed, we
can mark it as noexcept. This allows us to make most of the interface
noexcept. In particular, the move constructor and move assignment
operator can now be noexcept. This allows all Boo objects to play nicely
with interfaces that may make use of std::move_if_noexcept, like some of
the standard library facilities, without always taking the copy
constructor/copy assignment.
This commit is contained in:
Lioncash 2019-08-17 13:44:46 -04:00
parent 84f62a0f2c
commit 37670dca2c
1 changed files with 16 additions and 16 deletions

View File

@ -11,8 +11,8 @@ protected:
virtual ~IObj() = default;
public:
void increment() { m_refCount.fetch_add(1, std::memory_order_relaxed); }
void decrement() {
void increment() noexcept { m_refCount.fetch_add(1, std::memory_order_relaxed); }
void decrement() noexcept {
if (m_refCount.fetch_sub(1, std::memory_order_release) == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
delete this;
@ -25,17 +25,17 @@ class ObjToken {
SubCls* m_obj = nullptr;
public:
ObjToken() = default;
ObjToken(SubCls* obj) : m_obj(obj) {
ObjToken() noexcept = default;
ObjToken(SubCls* obj) noexcept : m_obj(obj) {
if (m_obj)
m_obj->increment();
}
ObjToken(const ObjToken& other) : m_obj(other.m_obj) {
ObjToken(const ObjToken& other) noexcept : m_obj(other.m_obj) {
if (m_obj)
m_obj->increment();
}
ObjToken(ObjToken&& other) : m_obj(other.m_obj) { other.m_obj = nullptr; }
ObjToken& operator=(SubCls* obj) {
ObjToken(ObjToken&& other) noexcept : m_obj(other.m_obj) { other.m_obj = nullptr; }
ObjToken& operator=(SubCls* obj) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = obj;
@ -43,7 +43,7 @@ public:
m_obj->increment();
return *this;
}
ObjToken& operator=(const ObjToken& other) {
ObjToken& operator=(const ObjToken& other) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = other.m_obj;
@ -51,26 +51,26 @@ public:
m_obj->increment();
return *this;
}
ObjToken& operator=(ObjToken&& other) {
ObjToken& operator=(ObjToken&& other) noexcept {
if (m_obj)
m_obj->decrement();
m_obj = other.m_obj;
other.m_obj = nullptr;
return *this;
}
~ObjToken() {
~ObjToken() noexcept {
if (m_obj)
m_obj->decrement();
}
SubCls* get() const { return m_obj; }
SubCls* operator->() const { return m_obj; }
SubCls& operator*() const { return *m_obj; }
SubCls* get() const noexcept { return m_obj; }
SubCls* operator->() const noexcept { return m_obj; }
SubCls& operator*() const noexcept { return *m_obj; }
template <class T>
T* cast() const {
T* cast() const noexcept {
return static_cast<T*>(m_obj);
}
operator bool() const { return m_obj != nullptr; }
void reset() {
operator bool() const noexcept { return m_obj != nullptr; }
void reset() noexcept {
if (m_obj)
m_obj->decrement();
m_obj = nullptr;