3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 02:15:19 +00:00
z3/src/util/ref.h
Jakob Rath 46f8b15c14
ref/ref_vector minor convenience changes (#5322)
* Add ref_vector_core::push_back(ref<T>&&)

* Make operator bool() explicit
2021-05-31 10:27:46 -07:00

145 lines
2.4 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
ref.h
Abstract:
Simple smart pointer class
Author:
Leonardo de Moura (leonardo) 2007-08-14.
Revision History:
--*/
#pragma once
#include <utility>
template<typename T>
class ref {
T * m_ptr;
void inc_ref() {
if (m_ptr) {
m_ptr->inc_ref();
}
}
void dec_ref() {
if (m_ptr) {
m_ptr->dec_ref();
}
}
public:
ref():
m_ptr(nullptr) {
}
ref(T * ptr):
m_ptr(ptr) {
inc_ref();
}
ref(const ref & r):
m_ptr(r.m_ptr) {
inc_ref();
}
ref (ref && r) noexcept : m_ptr(nullptr) {
std::swap(m_ptr, r.m_ptr);
}
~ref() {
dec_ref();
}
T * operator->() const {
return m_ptr;
}
T * get() const {
return m_ptr;
}
explicit operator bool() const {
return m_ptr != nullptr;
}
bool operator!() const {
return m_ptr == nullptr;
}
const T & operator*() const {
return *m_ptr;
}
T & operator*() {
return *m_ptr;
}
ref & operator=(T * ptr) {
if (ptr)
ptr->inc_ref();
dec_ref();
m_ptr = ptr;
return *this;
}
ref & operator=(ref & r) {
r.inc_ref();
dec_ref();
m_ptr = r.m_ptr;
return *this;
}
ref & operator=(ref &&r) {
if (this != &r) {
dec_ref ();
m_ptr = r.detach ();
}
return *this;
}
void reset() {
dec_ref();
m_ptr = nullptr;
}
T* detach() {
T* tmp = m_ptr;
m_ptr = nullptr;
return tmp;
}
friend bool operator==(const ref & r1, const ref & r2) {
return r1.m_ptr == r2.m_ptr;
}
friend bool operator!=(const ref & r1, const ref & r2) {
return r1.m_ptr != r2.m_ptr;
}
friend void swap (ref &r1, ref &r2) {
T* tmp = r1.m_ptr;
r1.m_ptr = r2.m_ptr;
r2.m_ptr = tmp;
}
};
/**
\brief Manager for references that are not managed.
This class is used for allowing us to create instantiations of the ref_vector and ref_buffer
templates for unmanaged objects.
*/
template<typename T>
class unmanged_ref_manager {
static void inc_ref(T * o) { o->inc_ref(); }
static void dec_ref(T * o) { o->dec_ref(); }
};