mirror of
https://github.com/Z3Prover/z3
synced 2025-05-08 00:05:46 +00:00
166 lines
3.2 KiB
C++
166 lines
3.2 KiB
C++
/*++
|
|
Copyright (c) 2006 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
optional.h
|
|
|
|
Abstract:
|
|
|
|
Discriminated union of a type T.
|
|
It defines the notion of initialized/uninitialized objects.
|
|
|
|
Author:
|
|
|
|
Leonardo de Moura (leonardo) 2006-09-29.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
template<class T>
|
|
class optional {
|
|
T* m_obj;
|
|
char m_initialized;
|
|
|
|
void construct(const T & val) {
|
|
m_initialized = 1;
|
|
m_obj = alloc(T, val);
|
|
}
|
|
|
|
void destroy() {
|
|
if (m_initialized == 1) {
|
|
dealloc(m_obj);
|
|
m_obj = nullptr;
|
|
}
|
|
m_initialized = 0;
|
|
}
|
|
|
|
public:
|
|
optional():
|
|
m_obj(nullptr), m_initialized(0) {}
|
|
|
|
explicit optional(const T & val) {
|
|
construct(val);
|
|
}
|
|
|
|
optional(T && val) noexcept : m_obj(nullptr), m_initialized(0) {
|
|
std::swap(m_obj, val.m_obj);
|
|
std::swap(m_initialized, val.m_initialized);
|
|
}
|
|
|
|
optional(const optional<T> & val):
|
|
m_initialized(0) {
|
|
if (val.m_initialized == 1) {
|
|
construct(*val);
|
|
}
|
|
}
|
|
|
|
~optional() {
|
|
destroy();
|
|
}
|
|
|
|
static optional const & undef() { static optional u; return u; }
|
|
|
|
bool initialized() const { return m_initialized == 1; }
|
|
operator bool() const { return m_initialized == 1; }
|
|
bool operator!() const { return m_initialized == 0; }
|
|
|
|
T * get() const {
|
|
if (m_initialized == 1) {
|
|
return m_obj;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void set_invalid() {
|
|
if (m_initialized == 1) {
|
|
destroy();
|
|
}
|
|
}
|
|
|
|
T * operator->() {
|
|
SASSERT(m_initialized==1);
|
|
return m_obj;
|
|
}
|
|
|
|
T const * operator->() const {
|
|
SASSERT(m_initialized==1);
|
|
return m_obj;
|
|
}
|
|
|
|
const T & operator*() const {
|
|
SASSERT(m_initialized==1);
|
|
return *m_obj;
|
|
}
|
|
|
|
T & operator*() {
|
|
SASSERT(m_initialized==1);
|
|
return *m_obj;
|
|
}
|
|
|
|
optional & operator=(const T & val) {
|
|
destroy();
|
|
construct(val);
|
|
return * this;
|
|
}
|
|
|
|
optional & operator=(const optional & val) {
|
|
if (&val != this) {
|
|
destroy();
|
|
if (val.m_initialized) {
|
|
construct(*val);
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
|
|
/**
|
|
\brief Template specialization for pointers. NULL represents uninitialized pointers.
|
|
*/
|
|
template<typename T>
|
|
class optional<T*> {
|
|
T * m_ptr;
|
|
|
|
static optional m_undef;
|
|
|
|
public:
|
|
|
|
optional():m_ptr(nullptr) {}
|
|
|
|
explicit optional(T * val):m_ptr(val) {}
|
|
|
|
optional(const optional & val):m_ptr(val.m_ptr) {}
|
|
|
|
static optional const & undef() { return m_undef; }
|
|
|
|
bool initialized() const { return m_ptr != 0 ; }
|
|
|
|
operator bool() const { return m_ptr != 0; }
|
|
|
|
bool operator!() const { return m_ptr == nullptr; }
|
|
|
|
void reset() { m_ptr = 0; }
|
|
|
|
optional & operator=(T * val) {
|
|
m_ptr = val;
|
|
return *this;
|
|
}
|
|
|
|
optional & operator=(const optional & val) {
|
|
m_ptr = val.m_ptr;
|
|
return *this;
|
|
}
|
|
|
|
T ** operator->() { return &m_ptr; }
|
|
|
|
T * operator*() const { return m_ptr; }
|
|
|
|
T * & operator*() { return m_ptr; }
|
|
};
|