3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 09:55:19 +00:00
z3/src/util/symbol.h
Bruce Mitchener 51a947b73d Change how 64 bit builds are detected.
Instead of doing this at configure time, we look at the actual
compile time status. This also avoids hardcoding checks based on
what CPU architecture is present, which doesn't work when Z3 is
being built on non-x86_64 platforms.
2018-12-09 16:16:20 +07:00

156 lines
4.3 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
symbol.h
Abstract:
Lisp-like symbols.
Author:
Leonardo de Moura (leonardo) 2006-09-11.
Revision History:
--*/
#ifndef SYMBOL_H_
#define SYMBOL_H_
#include<ostream>
#include<climits>
#include "util/util.h"
#include "util/tptr.h"
#include "util/string_buffer.h"
template<typename T>
class symbol_table;
class symbol {
char const * m_data;
template<typename T>
friend class symbol_table;
explicit symbol(void const * data):
m_data(reinterpret_cast<char const *>(data)) {
}
bool is_marked() const {
return GET_TAG(m_data) > 1;
}
static symbol mark(symbol s) {
SASSERT(!s.is_marked());
return symbol(TAG(void *, UNTAG(void *, s.m_data), GET_TAG(s.m_data) + 2));
}
static symbol unmark(symbol s) {
SASSERT(s.is_marked());
return symbol(TAG(void *, UNTAG(void *, s.m_data), GET_TAG(s.m_data) - 2));
}
static symbol m_dummy;
public:
symbol():
m_data(nullptr) {
}
explicit symbol(char const * d);
explicit symbol(unsigned idx):
m_data(BOXTAGINT(char const *, idx, 1)) {
#if !defined(__LP64__) && !defined(_WIN64)
SASSERT(idx < (SIZE_MAX >> PTR_ALIGNMENT));
#endif
}
static symbol dummy() { return m_dummy; }
static const symbol null;
symbol & operator=(char const * d);
friend bool operator==(symbol const & s1, symbol const & s2) { return s1.m_data == s2.m_data; }
friend bool operator!=(symbol const & s1, symbol const & s2) { return s1.m_data != s2.m_data; }
bool is_numerical() const { return GET_TAG(m_data) == 1; }
unsigned int get_num() const { SASSERT(is_numerical()); return UNBOXINT(m_data); }
std::string str() const;
friend bool operator==(symbol const & s1, char const * s2) {
if (s1.m_data == nullptr && s2 == nullptr)
return true;
if (s1.m_data == nullptr || s2 == nullptr)
return false;
if (!s1.is_numerical())
return strcmp(s1.bare_str(), s2) == 0;
return s1.str() == s2;
}
friend bool operator!=(symbol const & s1, char const * s2) { return !operator==(s1, s2); }
void const * c_ptr() const { return m_data; }
// Low level function.
// It is the inverse of c_ptr().
// It was made public to simplify the implementation of the C API.
static symbol mk_symbol_from_c_ptr(void const * ptr) {
return symbol(ptr);
}
unsigned hash() const {
if (m_data == nullptr) return 0x9e3779d9;
else if (is_numerical()) return get_num();
else return static_cast<unsigned>(reinterpret_cast<size_t const *>(m_data)[-1]);
}
bool contains(char c) const;
unsigned size() const;
char const * bare_str() const { SASSERT(!is_numerical()); return m_data; }
friend std::ostream & operator<<(std::ostream & target, symbol s) {
SASSERT(!s.is_marked());
if (GET_TAG(s.m_data) == 0) {
if (s.m_data) {
target << s.m_data;
}
else {
target << "null";
}
}
else {
target << "k!" << UNBOXINT(s.m_data);
}
return target;
}
template<unsigned SZ>
friend string_buffer<SZ> & operator<<(string_buffer<SZ> & target, symbol s) {
SASSERT(!s.is_marked());
if (GET_TAG(s.m_data) == 0) {
if (s.m_data) {
target << s.m_data;
}
else {
target << "null";
}
}
else {
target << "k!" << UNBOXINT(s.m_data);
}
return target;
}
};
struct symbol_hash_proc {
unsigned operator()(symbol const & s) const {
return s.hash();
}
};
struct symbol_eq_proc {
bool operator()(symbol const & s1, symbol const & s2) const {
return s1 == s2;
}
};
void initialize_symbols();
void finalize_symbols();
/*
ADD_INITIALIZER('initialize_symbols();')
ADD_FINALIZER('finalize_symbols();')
*/
// total order on symbols... I did not overloaded '<' to avoid misunderstandings.
// numerical symbols are smaller than non numerical symbols.
// two numerical symbols are compared using get_num.
// two non-numerical symbols are compared using string comparison.
bool lt(symbol const & s1, symbol const & s2);
#endif /* SYMBOL_H_ */