mCRL2
Loading...
Searching...
No Matches
tagged_pointer.h
Go to the documentation of this file.
1// Author(s): Maurice Laveaux
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8//
9
10#ifndef MCRL2_UTILITIES_TAGGED_POINTER_H_
11#define MCRL2_UTILITIES_TAGGED_POINTER_H_
12
13#include <functional>
14#include <type_traits>
15
18
19namespace mcrl2::utilities
20{
21
24template<typename T>
25T* tag(const T* p)
26{
27 return reinterpret_cast<T*>(reinterpret_cast<std::size_t>(p) | 1);
28}
29
30template<typename T>
32{
33 return reinterpret_cast<T*>(reinterpret_cast<std::size_t>(p.load(std::memory_order_relaxed)) | 1);
34}
35
37template<typename T>
38T* pointer(const T* p)
39{
40 return reinterpret_cast<T*>(reinterpret_cast<std::size_t>(p) & ~static_cast<std::size_t>(1));
41}
42
43template<typename T>
45{
46 return reinterpret_cast<T*>(reinterpret_cast<std::size_t>(p.load(std::memory_order_relaxed)) & ~static_cast<std::size_t>(1));
47}
48
50template<typename T>
51bool tagged(const T* p)
52{
53 return reinterpret_cast<std::size_t>(p) & 1;
54}
55
56template<typename T>
58{
59 return reinterpret_cast<std::size_t>(p.load(std::memory_order_relaxed)) & 1;
60}
61
64template<typename T>
66{
67public:
69 explicit tagged_pointer(T* p)
70 : m_pointer(p)
71 {}
72
74 bool tagged() const
75 {
77 }
78
80 void tag() const
81 {
83 }
84
86 void untag() const
87 {
88 m_pointer = const_cast<T*>(get());
89 }
90
91 bool defined() const
92 {
93 return get() != nullptr;
94 }
95
96 void operator=(std::nullptr_t)
97 {
98 m_pointer = mcrl2::utilities::tag(static_cast<T*>(nullptr));
99 }
100
101 bool operator==(std::nullptr_t) const
102 {
103 return get() == nullptr;
104 }
105
106 bool operator!=(std::nullptr_t) const
107 {
108 return !(*this == nullptr);
109 }
110
111 bool operator==(const tagged_pointer& other) const
112 {
113 return get() == other.get();
114 }
115
116 bool operator!=(const tagged_pointer& other) const
117 {
118 return !(*this == other);
119 }
120
121 bool operator <(const tagged_pointer& other) const noexcept
122 {
123 return get() < other.get();
124 }
125
126 bool operator <=(const tagged_pointer& other) const noexcept
127 {
128 return get() <= other.get();
129 }
130
131 bool operator >(const tagged_pointer& other) const noexcept
132 {
133 return get() > other.get();
134 }
135
136 bool operator >=(const tagged_pointer& other) const noexcept
137 {
138 return get() >= other.get();
139 }
140
141 const T& operator*() const
142 {
143 return *get();
144 }
145
147 {
148 return *get();
149 }
150
151 const T* operator->() const
152 {
153 return get();
154 }
155
157 {
158 return get();
159 }
160
161 const T* get() const
162 {
163 return pointer(m_pointer);
164 }
165
166 T* get()
167 {
168 return pointer(m_pointer);
169 }
170
172 {
173 // This is not atomic, so swaps are only allowed when no tags are being applied concurrently.
174 auto tmp = other.m_pointer;
175 other.m_pointer = m_pointer;
176 m_pointer = tmp;
177 }
178
179private:
180 mutable std::conditional_t<detail::GlobalThreadSafe, detail::atomic_wrapper<T*>, T*> m_pointer = nullptr;
181};
182
183} // namespace mcrl2::utilities
184
185namespace std
186{
187
189template<typename T>
190struct hash<mcrl2::utilities::tagged_pointer<T>>
191{
193 {
194 const std::hash<const T*> hasher;
195 return hasher(p.get());
196 }
197};
198
199} // namespace std
200
201#endif // MCRL2_UTILITIES_TAGGED_POINTER_H
A pointer storage object that uses a least significant bit as a mark. Can be used by objects that are...
bool operator==(const tagged_pointer &other) const
bool operator>(const tagged_pointer &other) const noexcept
bool operator>=(const tagged_pointer &other) const noexcept
bool operator==(std::nullptr_t) const
void swap(tagged_pointer< T > &other)
void untag() const
Remove the tag.
bool operator<(const tagged_pointer &other) const noexcept
void tag() const
Apply a tag to the pointer that can be checked with tagged().
bool operator!=(std::nullptr_t) const
bool operator<=(const tagged_pointer &other) const noexcept
bool operator!=(const tagged_pointer &other) const
std::conditional_t< detail::GlobalThreadSafe, detail::atomic_wrapper< T * >, T * > m_pointer
T * tag(const T *p)
Applies a tag to a pointer.
bool tagged(const T *p)
T * pointer(const T *p)
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
STL namespace.
std::size_t operator()(const mcrl2::utilities::tagged_pointer< T > &p) const
#define hash(l, r, m)
Definition tree_set.cpp:23