mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
tptr: add pointer tagging templates (#7067)
This commit is contained in:
parent
fcc7b25c19
commit
4c9f705cd1
|
@ -21,6 +21,7 @@ Revision History:
|
|||
|
||||
#include <cstdint>
|
||||
#include "util/machine.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
#define TAG_SHIFT PTR_ALIGNMENT
|
||||
#define ALIGNMENT_VALUE (1 << PTR_ALIGNMENT)
|
||||
|
@ -42,4 +43,22 @@ Revision History:
|
|||
|
||||
#define UNBOXINT(PTR) static_cast<int>(reinterpret_cast<uintptr_t>(PTR) >> PTR_ALIGNMENT)
|
||||
|
||||
template <typename U, typename T>
|
||||
U unbox(T* ptr) {
|
||||
return static_cast<U>(reinterpret_cast<std::uintptr_t>(ptr) >> PTR_ALIGNMENT);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned get_tag(T* ptr) {
|
||||
return reinterpret_cast<std::uintptr_t>(ptr) & TAG_MASK;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
T* box(U val, std::uintptr_t tag = 0) {
|
||||
static_assert( sizeof(T*) >= sizeof(U) + PTR_ALIGNMENT );
|
||||
SASSERT_EQ(tag & PTR_MASK, 0);
|
||||
T* ptr = reinterpret_cast<T*>((static_cast<std::uintptr_t>(val) << PTR_ALIGNMENT) | tag);
|
||||
SASSERT_EQ(val, unbox<U>(ptr)); // roundtrip of conversion integer -> pointer -> integer is not actually guaranteed by the C++ standard (but seems fine in practice, as indicated by previous usage of BOXINT/UNBOXINT)
|
||||
SASSERT_EQ(tag, get_tag(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue