3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-01-20 01:03:20 +00:00

Replace custom util/optional with std::optional (#8162)

* Initial plan

* Replace optional with std::optional in source files

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Fix array_map contains() and remove optional_benchmark test

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Address code review feedback - simplify array_map and test

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
Copilot 2026-01-11 19:47:39 -08:00 committed by GitHub
parent 40250bfcb8
commit 4d188f07e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 34 additions and 592 deletions

View file

@ -19,7 +19,7 @@ Revision History:
#pragma once
#include "util/vector.h"
#include "util/optional.h"
#include <optional>
/**
\brief Implements a mapping from Key to Data.
@ -43,29 +43,30 @@ class array_map {
unsigned m_garbage = 0;
unsigned m_non_garbage = 0;
static const unsigned m_gc_threshold = 10000;
vector<optional<entry>, CallDestructors > m_map;
vector<std::optional<entry>, CallDestructors > m_map;
Plugin m_plugin;
bool is_current(optional<entry> const& e) const {
bool is_current(std::optional<entry> const& e) const {
return e->m_timestamp == m_timestamp;
}
optional<entry> const & get_core(Key const & k) const {
std::optional<entry> const & get_core(Key const & k) const {
unsigned id = m_plugin.to_int(k);
if (id < m_map.size()) {
optional<entry> const & e = m_map[id];
std::optional<entry> const & e = m_map[id];
if (e && is_current(e)) {
return e;
}
}
return optional<entry>::undef();
static const std::optional<entry> s_undef;
return s_undef;
}
void really_flush() {
for (optional<entry> & e : m_map) {
for (std::optional<entry> & e : m_map) {
if (e) {
m_plugin.del_eh(e->m_key, e->m_data);
e.set_invalid();
e.reset();
}
}
m_garbage = 0;
@ -81,11 +82,11 @@ public:
~array_map() { really_flush(); }
bool contains(Key const & k) const {
return get_core(k);
return get_core(k).has_value();
}
Data const & get(Key const & k) const {
optional<entry> const & e = get_core(k);
std::optional<entry> const & e = get_core(k);
SASSERT(e);
return e->m_data;
}
@ -103,11 +104,11 @@ public:
void insert(Key const & k, Data const & d) {
unsigned id = m_plugin.to_int(k);
if (id >= m_map.size()) {
m_map.resize(id + 1, optional<entry>::undef());
m_map.resize(id + 1, std::nullopt);
}
m_plugin.ins_eh(k, d);
optional<entry> & e = m_map[id];
std::optional<entry> & e = m_map[id];
if (e) {
if (!is_current(e)) {
--m_garbage;
@ -124,7 +125,7 @@ public:
void erase(Key const & k) {
unsigned id = m_plugin.to_int(k);
if (id < m_map.size()) {
optional<entry> & e = m_map[id];
std::optional<entry> & e = m_map[id];
if (e) {
m_plugin.del_eh(e->m_key, e->m_data);
if (is_current(e)) {
@ -135,7 +136,7 @@ public:
SASSERT(m_garbage > 0);
--m_garbage;
}
e.set_invalid();
e.reset();
}
}
}

View file

@ -1,154 +0,0 @@
/*++
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 = nullptr;
void destroy() {
dealloc(m_obj);
m_obj = nullptr;
}
public:
optional() = default;
explicit optional(const T & val) {
m_obj = alloc(T, val);
}
explicit optional(T && val) {
m_obj = alloc(T, std::move(val));
}
optional(optional<T> && val) noexcept {
std::swap(m_obj, val.m_obj);
}
optional(const optional<T> & val) {
if (val.m_obj) {
m_obj = alloc(T, *val);
}
}
~optional() {
destroy();
}
static optional const & undef() { static optional u; return u; }
bool initialized() const { return m_obj; }
operator bool() const { return m_obj; }
bool operator!() const { return !m_obj; }
T * get() const {
return m_obj;
}
void set_invalid() {
destroy();
}
T * operator->() {
SASSERT(m_obj);
return m_obj;
}
T const * operator->() const {
SASSERT(m_obj);
return m_obj;
}
const T & operator*() const {
SASSERT(m_obj);
return *m_obj;
}
T & operator*() {
SASSERT(m_obj);
return *m_obj;
}
optional & operator=(const T & val) {
destroy();
m_obj = alloc(T, val);
return * this;
}
optional & operator=(optional && val) noexcept {
std::swap(m_obj, val.m_obj);
return *this;
}
optional & operator=(const optional & val) {
if (&val != this) {
destroy();
if (val.m_obj) {
m_obj = alloc(T, *val);
}
}
return *this;
}
};
/**
\brief Template specialization for pointers. NULL represents uninitialized pointers.
*/
template<typename T>
class optional<T*> {
T * m_ptr = nullptr;
static optional m_undef;
public:
optional() = default;
explicit optional(T * val):m_ptr(val) {}
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; }
};