mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
Merge branch 'master' of https://github.com/z3prover/z3 into polysat
This commit is contained in:
commit
57df45dc16
162 changed files with 2885 additions and 1941 deletions
|
@ -164,7 +164,7 @@ typedef approx_set_tpl<unsigned, u2u> u_approx_set;
|
|||
|
||||
class approx_set : public u_approx_set {
|
||||
public:
|
||||
approx_set():u_approx_set() {}
|
||||
approx_set() = default;
|
||||
approx_set(unsigned e):u_approx_set(e) {}
|
||||
|
||||
class iterator {
|
||||
|
|
|
@ -33,7 +33,6 @@ public:
|
|||
bound m_lower;
|
||||
bound m_upper;
|
||||
public:
|
||||
interval() {}
|
||||
bound const & lower() const { return m_lower; }
|
||||
bound const & upper() const { return m_upper; }
|
||||
bound & lower() { return m_lower; }
|
||||
|
|
|
@ -27,11 +27,11 @@ Revision History:
|
|||
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
|
||||
class buffer {
|
||||
protected:
|
||||
T * m_buffer;
|
||||
unsigned m_pos;
|
||||
unsigned m_capacity;
|
||||
char m_initial_buffer[INITIAL_SIZE * sizeof(T)];
|
||||
|
||||
T * m_buffer = reinterpret_cast<T*>(m_initial_buffer);
|
||||
unsigned m_pos = 0;
|
||||
unsigned m_capacity = INITIAL_SIZE;
|
||||
typename std::aligned_storage<sizeof(T), alignof(T)>::type m_initial_buffer[INITIAL_SIZE];
|
||||
|
||||
void free_memory() {
|
||||
if (m_buffer != reinterpret_cast<T*>(m_initial_buffer)) {
|
||||
dealloc_svect(m_buffer);
|
||||
|
@ -39,7 +39,7 @@ protected:
|
|||
}
|
||||
|
||||
void expand() {
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value, "");
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value);
|
||||
unsigned new_capacity = m_capacity << 1;
|
||||
T * new_buffer = reinterpret_cast<T*>(memory::allocate(sizeof(T) * new_capacity));
|
||||
for (unsigned i = 0; i < m_pos; ++i) {
|
||||
|
@ -73,26 +73,30 @@ public:
|
|||
typedef T * iterator;
|
||||
typedef const T * const_iterator;
|
||||
|
||||
buffer():
|
||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||
m_pos(0),
|
||||
m_capacity(INITIAL_SIZE) {
|
||||
}
|
||||
buffer() = default;
|
||||
|
||||
buffer(const buffer & source):
|
||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||
m_pos(0),
|
||||
m_capacity(INITIAL_SIZE) {
|
||||
unsigned sz = source.size();
|
||||
for(unsigned i = 0; i < sz; i++) {
|
||||
buffer(const buffer & source) {
|
||||
for (unsigned i = 0, sz = source.size(); i < sz; ++i) {
|
||||
push_back(source.m_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
buffer(unsigned sz, const T & elem):
|
||||
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
|
||||
m_pos(0),
|
||||
m_capacity(INITIAL_SIZE) {
|
||||
|
||||
buffer(buffer && source) noexcept {
|
||||
if (source.m_buffer == reinterpret_cast<T*>(source.m_initial_buffer)) {
|
||||
for (unsigned i = 0, sz = source.size(); i < sz; ++i) {
|
||||
push_back(std::move(source.m_buffer[i]));
|
||||
}
|
||||
} else {
|
||||
m_buffer = source.m_buffer;
|
||||
m_pos = source.m_pos;
|
||||
m_capacity = source.m_capacity;
|
||||
source.m_buffer = reinterpret_cast<T*>(source.m_initial_buffer);
|
||||
source.m_pos = 0;
|
||||
source.m_capacity = INITIAL_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
buffer(unsigned sz, const T & elem) {
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
push_back(elem);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,4 @@ Notes:
|
|||
#include "util/symbol.h"
|
||||
|
||||
template<typename T>
|
||||
class dictionary : public map<symbol, T, symbol_hash_proc, symbol_eq_proc> {
|
||||
public:
|
||||
dictionary() {}
|
||||
};
|
||||
|
||||
using dictionary = map<symbol, T, symbol_hash_proc, symbol_eq_proc>;
|
||||
|
|
|
@ -44,11 +44,10 @@ typedef enum { HT_FREE,
|
|||
template<typename T>
|
||||
class default_hash_entry {
|
||||
unsigned m_hash{ 0 }; //!< cached hash code
|
||||
hash_entry_state m_state;
|
||||
hash_entry_state m_state = HT_FREE;
|
||||
T m_data;
|
||||
public:
|
||||
typedef T data;
|
||||
default_hash_entry():m_state(HT_FREE), m_data() {}
|
||||
unsigned get_hash() const { return m_hash; }
|
||||
bool is_free() const { return m_state == HT_FREE; }
|
||||
bool is_deleted() const { return m_state == HT_DELETED; }
|
||||
|
@ -67,10 +66,9 @@ public:
|
|||
template<int Free, int Deleted>
|
||||
class int_hash_entry {
|
||||
unsigned m_hash; //!< cached hash code
|
||||
int m_data;
|
||||
int m_data = Free;
|
||||
public:
|
||||
typedef int data;
|
||||
int_hash_entry():m_data(Free) {}
|
||||
unsigned get_hash() const { return m_hash; }
|
||||
bool is_free() const { return m_data == Free; }
|
||||
bool is_deleted() const { return m_data == Deleted; }
|
||||
|
@ -89,10 +87,9 @@ public:
|
|||
template<typename T>
|
||||
class ptr_hash_entry {
|
||||
unsigned m_hash; //!< cached hash code
|
||||
T * m_ptr;
|
||||
T * m_ptr = nullptr;
|
||||
public:
|
||||
typedef T * data;
|
||||
ptr_hash_entry():m_ptr(nullptr) {}
|
||||
unsigned get_hash() const { return m_hash; }
|
||||
bool is_free() const { return m_ptr == nullptr; }
|
||||
bool is_deleted() const { return m_ptr == reinterpret_cast<T *>(1); }
|
||||
|
@ -112,10 +109,9 @@ public:
|
|||
*/
|
||||
template<typename T>
|
||||
class ptr_addr_hash_entry : public ptr_hash_entry<T> {
|
||||
T * m_ptr;
|
||||
T * m_ptr = nullptr;
|
||||
public:
|
||||
typedef T * data;
|
||||
ptr_addr_hash_entry():m_ptr(nullptr) {}
|
||||
unsigned get_hash() const { return get_ptr_hash(m_ptr); }
|
||||
bool is_free() const { return m_ptr == nullptr; }
|
||||
bool is_deleted() const { return m_ptr == reinterpret_cast<T *>(1); }
|
||||
|
|
|
@ -22,8 +22,6 @@ template<typename T>
|
|||
class lim_svector : public svector<T, unsigned> {
|
||||
unsigned_vector m_lim;
|
||||
public:
|
||||
lim_svector() {}
|
||||
|
||||
void push_scope() {
|
||||
m_lim.push_back(this->size());
|
||||
}
|
||||
|
|
|
@ -86,8 +86,6 @@ class max_cliques : public T {
|
|||
unsigned_vector const& next(unsigned vertex) const { return m_next[vertex]; }
|
||||
|
||||
public:
|
||||
max_cliques() {}
|
||||
|
||||
void add_edge(unsigned src, unsigned dst) {
|
||||
m_next.reserve(std::max(src, dst) + 1);
|
||||
m_next.reserve(std::max(negate(src), negate(dst)) + 1);
|
||||
|
|
|
@ -48,12 +48,12 @@ Revision History:
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
|
||||
#if defined(__GNUC__)
|
||||
#define _trailing_zeros32(X) __builtin_ctz(X)
|
||||
#elif defined(_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(__MINGW32__)
|
||||
// This is needed for _tzcnt_u32 and friends.
|
||||
#include <immintrin.h>
|
||||
#define _trailing_zeros32(X) _tzcnt_u32(X)
|
||||
#elif defined(__GNUC__)
|
||||
#define _trailing_zeros32(X) __builtin_ctz(X)
|
||||
#else
|
||||
static uint32_t _trailing_zeros32(uint32_t x) {
|
||||
uint32_t r = 0;
|
||||
|
|
|
@ -29,10 +29,9 @@ Revision History:
|
|||
*/
|
||||
template<typename T>
|
||||
class obj_hash_entry {
|
||||
T * m_ptr;
|
||||
T * m_ptr = nullptr;
|
||||
public:
|
||||
typedef T * data;
|
||||
obj_hash_entry():m_ptr(nullptr) {}
|
||||
unsigned get_hash() const { return m_ptr->hash(); }
|
||||
bool is_free() const { return m_ptr == nullptr; }
|
||||
bool is_deleted() const { return m_ptr == reinterpret_cast<T *>(1); }
|
||||
|
@ -82,7 +81,6 @@ public:
|
|||
key_data m_data;
|
||||
public:
|
||||
typedef key_data data;
|
||||
obj_map_entry() {}
|
||||
unsigned get_hash() const { return m_data.hash(); }
|
||||
bool is_free() const { return m_data.m_key == nullptr; }
|
||||
bool is_deleted() const { return m_data.m_key == reinterpret_cast<Key *>(1); }
|
||||
|
|
|
@ -29,11 +29,10 @@ Revision History:
|
|||
template<typename T1, typename T2>
|
||||
class obj_pair_hash_entry {
|
||||
unsigned m_hash; // cached hash code
|
||||
std::pair<T1*, T2*> m_data;
|
||||
std::pair<T1*, T2*> m_data { nullptr, nullptr };
|
||||
|
||||
public:
|
||||
typedef std::pair<T1*, T2*> data;
|
||||
obj_pair_hash_entry():m_data(static_cast<T1*>(nullptr),static_cast<T2*>(nullptr)) {}
|
||||
unsigned get_hash() const { return m_hash; }
|
||||
bool is_free() const { return m_data.first == 0; }
|
||||
bool is_deleted() const { return m_data.first == reinterpret_cast<T1 *>(1); }
|
||||
|
@ -94,7 +93,6 @@ protected:
|
|||
key_data m_data;
|
||||
public:
|
||||
typedef key_data data;
|
||||
entry() {}
|
||||
unsigned get_hash() const { return m_data.hash(); }
|
||||
bool is_free() const { return m_data.m_key1 == nullptr; }
|
||||
bool is_deleted() const { return m_data.m_key1 == reinterpret_cast<Key1 *>(1); }
|
||||
|
|
|
@ -34,7 +34,6 @@ protected:
|
|||
typedef chashtable<obj_pair, hash_proc, eq_proc> set;
|
||||
set m_set;
|
||||
public:
|
||||
obj_pair_set() {}
|
||||
void insert(T1 * t1, T2 * t2) { m_set.insert(obj_pair(t1, t2)); }
|
||||
void insert(obj_pair const & p) { m_set.insert(p); }
|
||||
bool insert_if_not_there(T1 * t1, T2 * t2) { return m_set.insert_if_not_there2(obj_pair(t1, t2)); }
|
||||
|
|
|
@ -30,11 +30,10 @@ Revision History:
|
|||
template<typename T1, typename T2, typename T3>
|
||||
class obj_triple_hash_entry {
|
||||
unsigned m_hash; // cached hash code
|
||||
triple<T1*, T2*, T3*> m_data;
|
||||
triple<T1*, T2*, T3*> m_data { nullptr, nullptr, nullptr };
|
||||
|
||||
public:
|
||||
typedef triple<T1*, T2*, T3*> data;
|
||||
obj_triple_hash_entry():m_data(0,0,0) {}
|
||||
unsigned get_hash() const { return m_hash; }
|
||||
bool is_free() const { return m_data.first == 0; }
|
||||
bool is_deleted() const { return m_data.first == reinterpret_cast<T1 *>(1); }
|
||||
|
@ -99,7 +98,6 @@ protected:
|
|||
key_data m_data;
|
||||
public:
|
||||
typedef key_data data;
|
||||
entry() {}
|
||||
unsigned get_hash() const { return m_data.hash(); }
|
||||
bool is_free() const { return m_data.m_key1 == nullptr; }
|
||||
bool is_deleted() const { return m_data.m_key1 == reinterpret_cast<Key1 *>(1); }
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace sat {
|
|||
};
|
||||
|
||||
const literal null_literal;
|
||||
struct literal_hash : obj_hash<literal> {};
|
||||
using literal_hash = obj_hash<literal>;
|
||||
|
||||
inline literal to_literal(unsigned x) { literal l; l.m_val = x; return l; }
|
||||
inline bool operator<(literal const & l1, literal const & l2) { return l1.m_val < l2.m_val; }
|
||||
|
|
|
@ -22,8 +22,8 @@ Revision History:
|
|||
|
||||
template<typename T>
|
||||
class scoped_vector {
|
||||
unsigned m_size;
|
||||
unsigned m_elems_start;
|
||||
unsigned m_size = 0;
|
||||
unsigned m_elems_start = 0;
|
||||
unsigned_vector m_sizes;
|
||||
vector<T> m_elems;
|
||||
unsigned_vector m_elems_lim;
|
||||
|
@ -31,8 +31,6 @@ class scoped_vector {
|
|||
unsigned_vector m_src, m_dst;
|
||||
unsigned_vector m_src_lim;
|
||||
public:
|
||||
scoped_vector(): m_size(0), m_elems_start(0) {}
|
||||
|
||||
// m_index : External-Index -> Internal-Index
|
||||
// m_index.size() = max(m_sizes)
|
||||
// m_src[i] -> m_dst[i] // trail into m_index updates
|
||||
|
@ -183,4 +181,3 @@ private:
|
|||
m_elems_start <= m_elems.size();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
#include "util/region.h"
|
||||
#include "util/string_buffer.h"
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#ifndef SINGLE_THREAD
|
||||
#include <thread>
|
||||
#endif
|
||||
|
@ -35,6 +36,7 @@ const symbol symbol::null;
|
|||
/**
|
||||
\brief Symbol table manager. It stores the symbol strings created at runtime.
|
||||
*/
|
||||
namespace {
|
||||
class internal_symbol_table {
|
||||
region m_region; //!< Region used to store symbol strings.
|
||||
str_hashtable m_table; //!< Table of created symbol strings.
|
||||
|
@ -73,6 +75,22 @@ public:
|
|||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef SINGLE_THREAD
|
||||
static std::optional<internal_symbol_table> g_symbol_tables;
|
||||
|
||||
void initialize_symbols() {
|
||||
if (!g_symbol_tables) {
|
||||
g_symbol_tables.emplace();
|
||||
}
|
||||
}
|
||||
|
||||
void finalize_symbols() {
|
||||
g_symbol_tables.reset();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct internal_symbol_tables {
|
||||
unsigned sz;
|
||||
|
@ -101,11 +119,7 @@ static internal_symbol_tables* g_symbol_tables = nullptr;
|
|||
|
||||
void initialize_symbols() {
|
||||
if (!g_symbol_tables) {
|
||||
#ifdef SINGLE_THREAD
|
||||
unsigned num_tables = 1;
|
||||
#else
|
||||
unsigned num_tables = 2 * std::min((unsigned) std::thread::hardware_concurrency(), 64u);
|
||||
#endif
|
||||
g_symbol_tables = alloc(internal_symbol_tables, num_tables);
|
||||
|
||||
}
|
||||
|
@ -115,6 +129,7 @@ void finalize_symbols() {
|
|||
dealloc(g_symbol_tables);
|
||||
g_symbol_tables = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
symbol::symbol(char const * d) {
|
||||
if (d == nullptr)
|
||||
|
@ -130,11 +145,8 @@ symbol & symbol::operator=(char const * d) {
|
|||
|
||||
std::string symbol::str() const {
|
||||
SASSERT(!is_marked());
|
||||
if (GET_TAG(m_data) == 0) {
|
||||
if (m_data)
|
||||
return m_data;
|
||||
else
|
||||
return "<null>";
|
||||
if (GET_TAG(m_data) == 0) {
|
||||
return m_data ? m_data : "<null>";
|
||||
}
|
||||
else {
|
||||
string_buffer<128> buffer;
|
||||
|
|
|
@ -26,8 +26,7 @@ Revision History:
|
|||
|
||||
class trail {
|
||||
public:
|
||||
virtual ~trail() {
|
||||
}
|
||||
virtual ~trail() {}
|
||||
virtual void undo() = 0;
|
||||
};
|
||||
|
||||
|
@ -48,9 +47,6 @@ public:
|
|||
m_value = new_value;
|
||||
}
|
||||
|
||||
~value_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_value = m_old_value;
|
||||
}
|
||||
|
@ -69,9 +65,6 @@ public:
|
|||
m_values(values) {
|
||||
}
|
||||
|
||||
~scoped_value_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_value = m_values.back();
|
||||
m_values.pop_back();
|
||||
|
@ -86,9 +79,6 @@ public:
|
|||
m_value(value) {
|
||||
}
|
||||
|
||||
~reset_flag_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_value = false;
|
||||
}
|
||||
|
@ -121,8 +111,7 @@ public:
|
|||
m_vector(v),
|
||||
m_old_size(v.size()) {
|
||||
}
|
||||
~restore_size_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_vector.shrink(m_old_size);
|
||||
}
|
||||
|
@ -140,9 +129,6 @@ public:
|
|||
m_old_value(v[idx]) {
|
||||
}
|
||||
|
||||
~vector_value_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_vector[m_idx] = m_old_value;
|
||||
}
|
||||
|
@ -162,9 +148,6 @@ public:
|
|||
m_old_value(v[i][j]) {
|
||||
}
|
||||
|
||||
~vector2_value_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_vector[m_i][m_j] = m_old_value;
|
||||
}
|
||||
|
@ -177,7 +160,6 @@ class insert_obj_map : public trail {
|
|||
D* m_obj;
|
||||
public:
|
||||
insert_obj_map(obj_map<D,R>& t, D* o) : m_map(t), m_obj(o) {}
|
||||
~insert_obj_map() override {}
|
||||
void undo() override { m_map.remove(m_obj); }
|
||||
};
|
||||
|
||||
|
@ -188,7 +170,6 @@ class remove_obj_map : public trail {
|
|||
R m_value;
|
||||
public:
|
||||
remove_obj_map(obj_map<D,R>& t, D* o, R v) : m_map(t), m_obj(o), m_value(v) {}
|
||||
~remove_obj_map() override {}
|
||||
void undo() override { m_map.insert(m_obj, m_value); }
|
||||
};
|
||||
|
||||
|
@ -198,7 +179,6 @@ class insert_map : public trail {
|
|||
D m_obj;
|
||||
public:
|
||||
insert_map(M& t, D o) : m_map(t), m_obj(o) {}
|
||||
~insert_map() override {}
|
||||
void undo() override { m_map.remove(m_obj); }
|
||||
};
|
||||
|
||||
|
@ -210,8 +190,7 @@ class insert_ref_map : public trail {
|
|||
D m_obj;
|
||||
public:
|
||||
insert_ref_map(Mgr& m, M& t, D o) : m(m), m_map(t), m_obj(o) {}
|
||||
virtual ~insert_ref_map() {}
|
||||
virtual void undo() { m_map.remove(m_obj); m.dec_ref(m_obj); }
|
||||
void undo() override { m_map.remove(m_obj); m.dec_ref(m_obj); }
|
||||
};
|
||||
|
||||
template<typename Mgr, typename D, typename R>
|
||||
|
@ -222,8 +201,7 @@ class insert_ref2_map : public trail {
|
|||
R* m_val;
|
||||
public:
|
||||
insert_ref2_map(Mgr& m, obj_map<D,R*>& t, D*o, R*r) : m(m), m_map(t), m_obj(o), m_val(r) {}
|
||||
virtual ~insert_ref2_map() {}
|
||||
virtual void undo() { m_map.remove(m_obj); m.dec_ref(m_obj); m.dec_ref(m_val); }
|
||||
void undo() override { m_map.remove(m_obj); m.dec_ref(m_obj); m.dec_ref(m_val); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -250,9 +228,6 @@ public:
|
|||
m_idx(idx) {
|
||||
}
|
||||
|
||||
~set_vector_idx_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_vector[m_idx] = nullptr;
|
||||
}
|
||||
|
@ -286,7 +261,7 @@ public:
|
|||
m_value(m_vector[index].back()) {
|
||||
}
|
||||
|
||||
virtual void undo() {
|
||||
void undo() override {
|
||||
m_vector[m_index].push_back(m_value);
|
||||
}
|
||||
};
|
||||
|
@ -317,7 +292,7 @@ public:
|
|||
m_index(index) {
|
||||
}
|
||||
|
||||
virtual void undo() {
|
||||
void undo() override {
|
||||
m_vector[m_index].pop_back();
|
||||
}
|
||||
};
|
||||
|
@ -351,9 +326,6 @@ public:
|
|||
m_idx(idx),
|
||||
m_hist(hist) {}
|
||||
|
||||
~history_trail() override {
|
||||
}
|
||||
|
||||
void undo() override {
|
||||
m_dst[m_idx] = m_hist.back();
|
||||
m_hist.pop_back();
|
||||
|
@ -382,7 +354,7 @@ public:
|
|||
m_obj(obj) {
|
||||
}
|
||||
|
||||
virtual void undo() {
|
||||
void undo() override {
|
||||
m_obj.reset();
|
||||
}
|
||||
};
|
||||
|
@ -393,7 +365,6 @@ class insert_obj_trail : public trail {
|
|||
T* m_obj;
|
||||
public:
|
||||
insert_obj_trail(obj_hashtable<T>& t, T* o) : m_table(t), m_obj(o) {}
|
||||
~insert_obj_trail() override {}
|
||||
void undo() override { m_table.remove(m_obj); }
|
||||
};
|
||||
|
||||
|
@ -404,8 +375,7 @@ class remove_obj_trail : public trail {
|
|||
T* m_obj;
|
||||
public:
|
||||
remove_obj_trail(obj_hashtable<T>& t, T* o) : m_table(t), m_obj(o) {}
|
||||
virtual ~remove_obj_trail() {}
|
||||
virtual void undo() { m_table.insert(m_obj); }
|
||||
void undo() override { m_table.insert(m_obj); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -425,10 +395,6 @@ class trail_stack {
|
|||
unsigned_vector m_scopes;
|
||||
region m_region;
|
||||
public:
|
||||
trail_stack() {}
|
||||
|
||||
~trail_stack() {}
|
||||
|
||||
region & get_region() { return m_region; }
|
||||
|
||||
void reset() {
|
||||
|
@ -457,4 +423,3 @@ public:
|
|||
m_region.pop_scope(num_scopes);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ Revision History:
|
|||
class union_find_default_ctx {
|
||||
public:
|
||||
typedef trail_stack _trail_stack;
|
||||
union_find_default_ctx() : m_stack() {}
|
||||
|
||||
void unmerge_eh(unsigned, unsigned) {}
|
||||
void merge_eh(unsigned, unsigned, unsigned, unsigned) {}
|
||||
|
@ -51,7 +50,6 @@ class union_find {
|
|||
union_find & m_owner;
|
||||
public:
|
||||
mk_var_trail(union_find & o):m_owner(o) {}
|
||||
~mk_var_trail() override {}
|
||||
void undo() override {
|
||||
m_owner.m_find.pop_back();
|
||||
m_owner.m_size.pop_back();
|
||||
|
@ -69,7 +67,6 @@ class union_find {
|
|||
unsigned m_r1;
|
||||
public:
|
||||
merge_trail(union_find & o, unsigned r1):m_owner(o), m_r1(r1) {}
|
||||
~merge_trail() override {}
|
||||
void undo() override { m_owner.unmerge(m_r1); }
|
||||
};
|
||||
|
||||
|
|
|
@ -163,14 +163,10 @@ template<typename T, bool CallDestructors=true, typename SZ = unsigned>
|
|||
class vector {
|
||||
#define SIZE_IDX -1
|
||||
#define CAPACITY_IDX -2
|
||||
T * m_data;
|
||||
T * m_data = nullptr;
|
||||
|
||||
void destroy_elements() {
|
||||
iterator it = begin();
|
||||
iterator e = end();
|
||||
for (; it != e; ++it) {
|
||||
it->~T();
|
||||
}
|
||||
std::destroy_n(m_data, size());
|
||||
}
|
||||
|
||||
void free_memory() {
|
||||
|
@ -178,17 +174,21 @@ class vector {
|
|||
}
|
||||
|
||||
void expand_vector() {
|
||||
// ensure that the data is sufficiently aligned
|
||||
// better fail to compile than produce code that may crash
|
||||
static_assert((sizeof(SZ) * 2) % alignof(T) == 0);
|
||||
|
||||
if (m_data == nullptr) {
|
||||
SZ capacity = 2;
|
||||
SZ * mem = reinterpret_cast<SZ*>(memory::allocate(sizeof(T) * capacity + sizeof(SZ) * 2));
|
||||
*mem = capacity;
|
||||
*mem = capacity;
|
||||
mem++;
|
||||
*mem = 0;
|
||||
*mem = 0;
|
||||
mem++;
|
||||
m_data = reinterpret_cast<T *>(mem);
|
||||
m_data = reinterpret_cast<T *>(mem);
|
||||
}
|
||||
else {
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value, "");
|
||||
static_assert(std::is_nothrow_move_constructible<T>::value);
|
||||
SASSERT(capacity() > 0);
|
||||
SZ old_capacity = reinterpret_cast<SZ *>(m_data)[CAPACITY_IDX];
|
||||
SZ old_capacity_T = sizeof(T) * old_capacity + sizeof(SZ) * 2;
|
||||
|
@ -203,15 +203,12 @@ class vector {
|
|||
m_data = reinterpret_cast<T *>(mem + 2);
|
||||
} else {
|
||||
mem = (SZ*)memory::allocate(new_capacity_T);
|
||||
auto old_data = m_data;
|
||||
auto old_size = size();
|
||||
mem[1] = old_size;
|
||||
m_data = reinterpret_cast<T *>(mem + 2);
|
||||
for (unsigned i = 0; i < old_size; ++i) {
|
||||
new (&m_data[i]) T(std::move(old_data[i]));
|
||||
old_data[i].~T();
|
||||
}
|
||||
memory::deallocate(old_mem);
|
||||
auto new_data = reinterpret_cast<T *>(mem + 2);
|
||||
std::uninitialized_move_n(m_data, old_size, new_data);
|
||||
destroy();
|
||||
m_data = new_data;
|
||||
}
|
||||
*mem = new_capacity;
|
||||
}
|
||||
|
@ -243,12 +240,9 @@ public:
|
|||
typedef T * iterator;
|
||||
typedef const T * const_iterator;
|
||||
|
||||
vector():
|
||||
m_data(nullptr) {
|
||||
}
|
||||
vector() = default;
|
||||
|
||||
vector(SZ s) {
|
||||
m_data = nullptr;
|
||||
init(s);
|
||||
}
|
||||
|
||||
|
@ -271,25 +265,22 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
vector(SZ s, T const & elem):
|
||||
m_data(nullptr) {
|
||||
vector(SZ s, T const & elem) {
|
||||
resize(s, elem);
|
||||
}
|
||||
|
||||
vector(vector const & source):
|
||||
m_data(nullptr) {
|
||||
vector(vector const & source) {
|
||||
if (source.m_data) {
|
||||
copy_core(source);
|
||||
}
|
||||
SASSERT(size() == source.size());
|
||||
}
|
||||
|
||||
vector(vector&& other) noexcept : m_data(nullptr) {
|
||||
vector(vector&& other) noexcept {
|
||||
std::swap(m_data, other.m_data);
|
||||
}
|
||||
|
||||
vector(SZ s, T const * data):
|
||||
m_data(nullptr) {
|
||||
vector(SZ s, T const * data) {
|
||||
for (SZ i = 0; i < s; i++) {
|
||||
push_back(data[i]);
|
||||
}
|
||||
|
@ -321,7 +312,6 @@ public:
|
|||
bool operator!=(vector const & other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
vector & operator=(vector const & source) {
|
||||
if (this == &source) {
|
||||
|
|
|
@ -276,16 +276,10 @@ bool operator<(const zstring& lhs, const zstring& rhs) {
|
|||
for (unsigned i = 0; i < len; ++i) {
|
||||
unsigned Li = lhs[i];
|
||||
unsigned Ri = rhs[i];
|
||||
if (Li < Ri) {
|
||||
return true;
|
||||
}
|
||||
else if (Li > Ri) {
|
||||
return false;
|
||||
}
|
||||
if (Li != Ri)
|
||||
return Li < Ri;
|
||||
}
|
||||
// at this point, all compared characters are equal,
|
||||
// so decide based on the relative lengths
|
||||
return lhs.length() < rhs.length();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,14 +16,14 @@ Author:
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "util/vector.h"
|
||||
#include "util/buffer.h"
|
||||
#include "util/rational.h"
|
||||
|
||||
class zstring {
|
||||
private:
|
||||
buffer<unsigned> m_buffer;
|
||||
buffer<uint32_t> m_buffer;
|
||||
bool well_formed() const;
|
||||
bool uses_unicode() const;
|
||||
bool is_escape_char(char const *& s, unsigned& result);
|
||||
|
@ -32,7 +32,7 @@ public:
|
|||
static unsigned unicode_num_bits() { return 18; }
|
||||
static unsigned ascii_max_char() { return 255; }
|
||||
static unsigned ascii_num_bits() { return 8; }
|
||||
zstring() {}
|
||||
zstring() = default;
|
||||
zstring(char const* s);
|
||||
zstring(const std::string &str) : zstring(str.c_str()) {}
|
||||
zstring(rational const& r): zstring(r.to_string()) {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue