14 // can take the bottom 3 bits of a ptr [ptrs must be 8-byte aligned]
15 static const uintptr_t LowBitsMask = 0x7;
17 constexpr inline marked_ptr() : px(0) {}
20 inline marked_ptr(U *px) : px(reinterpret_cast<uintptr_t>(px))
23 if (static_cast<T *>(px))
25 INVARIANT(!(this->px & LowBitsMask));
28 // both operator= and copy-ctor PROPAGATE mark bits
31 inline marked_ptr(const marked_ptr<U> &o)
35 if (static_cast<T *>((U *) nullptr))
41 operator=(const marked_ptr<U> &o)
44 if (static_cast<T *>((U *) nullptr))
71 return reinterpret_cast<T *>(px & ~LowBitsMask);
78 INVARIANT(!(px & LowBitsMask));
80 if (static_cast<T *>(px))
82 this->px = reinterpret_cast<uintptr_t>(px);
88 return px & LowBitsMask;
92 set_flags(uint8_t flags)
94 INVARIANT(!(flags & ~LowBitsMask));
95 px = (px & ~LowBitsMask) | flags;
99 or_flags(uint8_t flags)
101 INVARIANT(!(flags & ~LowBitsMask));
105 template <typename U>
107 operator==(const marked_ptr<U> &o) const
109 return get() == o.get();
112 template <typename U>
114 operator!=(const marked_ptr<U> &o) const
116 return !operator==(o);
119 template <typename U>
121 operator<(const marked_ptr<U> &o) const
123 return get() < o.get();
126 template <typename U>
128 operator>=(const marked_ptr<U> &o) const
130 return !operator<(o);
133 template <typename U>
135 operator>(const marked_ptr<U> &o) const
137 return get() > o.get();
140 template <typename U>
142 operator<=(const marked_ptr<U> &o) const
144 return !operator>(o);
151 template <typename T>
152 inline std::ostream &
153 operator<<(std::ostream &o, const marked_ptr<T> &p)
155 o << "[px=" << util::hexify(p.get()) << ", flags=0x" << util::hexify(p.get_flags()) << "]";
160 template <typename T>
161 struct hash<marked_ptr<T>> {
163 operator()(marked_ptr<T> p) const
165 return hash<T *>()(p.get());
170 #endif /* _MARKED_PTR_H_ */