z3-z3-4.13.0.src.util.obj_ref.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
obj_ref.h
Abstract:
Smart pointer.
Author:
Leonardo de Moura (leonardo) 2008-01-03.
Revision History:
--*/
#pragma once
/**
Smart pointer for T objects.
TManager must provide the functions:
- void dec_ref(T * obj)
- void inc_ref(T * obj)
*/
template
class obj_ref {
T * m_obj;
TManager & m_manager;
void dec_ref() { if (m_obj) m_manager.dec_ref(m_obj); }
void inc_ref() { if (m_obj) m_manager.inc_ref(m_obj); }
public:
typedef TManager manager;
obj_ref(T * n, TManager & m):
m_obj(n),
m_manager(m) {
inc_ref();
}
explicit obj_ref(TManager & m):
m_obj(nullptr),
m_manager(m) {
}
obj_ref(obj_ref const & n):
m_obj(n.m_obj),
m_manager(n.m_manager) {
inc_ref();
}
obj_ref(obj_ref && other) noexcept : m_obj(nullptr), m_manager(other.m_manager) {
std::swap(m_obj, other.m_obj);
}
~obj_ref() { dec_ref(); }
TManager & get_manager() const { return m_manager; }
TManager & m() const { return m_manager; }
T * operator->() const { return m_obj; }
T * get() const { return m_obj; }
operator bool() const { return m_obj != nullptr; }
bool operator!() const { return m_obj == nullptr; }
operator T*() const { return m_obj; }
T const & operator*() const { return *m_obj; }
obj_ref & operator=(T * n) {
if (n) {
m_manager.inc_ref(n);
}
dec_ref();
m_obj = n;
return *this;
}
obj_ref & operator=(const obj_ref & n) {
SASSERT(&m_manager == &n.m_manager);
if (m_obj != n.m_obj) {
dec_ref();
m_obj = n.m_obj;
inc_ref();
}
return *this;
}
obj_ref & operator=(obj_ref && n) noexcept {
SASSERT(&m_manager == &n.m_manager);
std::swap(m_obj, n.m_obj);
n.reset();
return *this;
}
void reset() {
dec_ref();
m_obj = nullptr;
}
void swap(obj_ref & n) noexcept {
std::swap(m_obj, n.m_obj);
}
/**
\brief Steal ownership without decrementing the reference counter.
*/
T * steal() {
T * r = m_obj;
m_obj = nullptr;
return r;
}
};
template
inline bool operator==(obj_ref const & n1, obj_ref const & n2) {
return n1.get() == n2.get();
}
template
inline bool operator==(obj_ref const & n1, obj_ref const & n2) {
return n1.get() == n2.get();
}
template
inline bool operator!=(obj_ref const & n1, obj_ref const & n2) {
return n1.get() != n2.get();
}
template
inline bool operator!=(obj_ref const & n1, obj_ref const & n2) {
return n1.get() != n2.get();
}
template
inline void dec_range_ref(IT const & begin, IT const & end, TManager & m) {
for (IT it = begin; it != end; ++it) {
if (*it) {
m.dec_ref(*it);
}
}
}