From 2275c75fe9539e6e81fb13f61f710b153c6ef2be Mon Sep 17 00:00:00 2001 From: "graehl@gmail.com" Date: Sun, 8 Aug 2010 08:49:13 +0000 Subject: cfg git-svn-id: https://ws10smt.googlecode.com/svn/trunk@493 ec762483-ff6d-05da-a07a-a48fb63a330f --- decoder/int_or_pointer.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 decoder/int_or_pointer.h (limited to 'decoder/int_or_pointer.h') diff --git a/decoder/int_or_pointer.h b/decoder/int_or_pointer.h new file mode 100755 index 00000000..4b6a9e4a --- /dev/null +++ b/decoder/int_or_pointer.h @@ -0,0 +1,70 @@ +#ifndef INT_OR_POINTER_H +#define INT_OR_POINTER_H + +// if you ever wanted to store a discriminated union of pointer/integer without an extra boolean flag, this will do it, assuming your pointers are never odd. + +// check lsb for expected tag? +#ifndef IOP_CHECK_LSB +# define IOP_CHECK_LSB 1 +#endif +#if IOP_CHECK_LSB +# define iop_assert(x) assert(x) +#else +# define iop_assert(x) +#endif + +#include +#include + +template +struct IntOrPointer { + typedef Pointed pointed_type; + typedef Int integer_type; + typedef Pointed *value_type; + typedef IntOrPointer self_type; + IntOrPointer(int j) { *this=j; } + IntOrPointer(size_t j) { *this=j; } + IntOrPointer(value_type v) { *this=v; } + bool is_integer() const { return i&1; } + bool is_pointer() const { return !(i&1); } + value_type & pointer() { return p; } + const value_type & pointer() const { iop_assert(is_pointer()); return p; } + integer_type integer() const { iop_assert(is_integer()); return i >> 1; } + void set_integer(Int j) { i=2*j+1; } + void set_pointer(value_type p_) { p=p_;iop_assert(is_pointer()); } + void operator=(unsigned j) { i = 2*(integer_type)j+1; } + void operator=(int j) { i = 2*(integer_type)j+1; } + template + void operator=(C j) { i = 2*(integer_type)j+1; } + void operator=(value_type v) { p=v; } + IntOrPointer() {} + IntOrPointer(const self_type &s) : p(s.p) {} + void operator=(const self_type &s) { p=s.p; } + template + bool operator ==(C* v) const { return p==v; } + template + bool operator ==(const C* v) const { return p==v; } + template + bool operator ==(C j) const { return integer() == j; } + bool operator ==(self_type s) const { return p==s.p; } + bool operator !=(self_type s) const { return p!=s.p; } + template void print(O&o) const + { + if (is_integer()) + o << integer(); + else { + o << "0x" << std::hex << (size_t)pointer() << std::dec; + } + } + friend inline std::ostream& operator<<(std::ostream &o,self_type const& s) { + s.print(o); return o; + } +protected: + union { + value_type p; // must be even (guaranteed unless you're pointing at packed chars) + integer_type i; // stored as 2*data+1, so only has half the range (one less bit) of a normal integer_type + }; +}; + + +#endif -- cgit v1.2.3