carl  24.04
Computer ARithmetic Library
pointerOperations.h
Go to the documentation of this file.
1 /*
2  * @file pointerOperations.h
3  * @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
4  *
5  * This file contains generic operations on pointers.
6  * We define our own suite of STL like operations like std::equal_to or std::less
7  * on pointers (and shared pointers) with our own semantic.
8  *
9  * We consider two pointers equal, if the pointers themselves are equal or the
10  * objects they point to are equal. Similarly, a pointer is smaller than another,
11  * if the object it points to is smaller. A nullptr is considered the smallest.
12  */
13 
14 #pragma once
15 
16 #include <functional>
17 #include <memory>
18 #include <cassert>
19 
20 namespace carl {
21 
22 /**
23  * Alternative specialization of std::equal_to for pointer types.
24  *
25  * We consider two pointers equal, if they point to the same memory location or the objects they point to are equal.
26  * Note that the memory location may also be zero.
27  */
28 template<typename T, bool mayBeNull = true>
29 struct equal_to {
30  std::equal_to<T> eq;
31  bool operator()(const T& lhs, const T& rhs) const {
32  return eq(lhs, rhs);
33  }
34 };
35 
36 template<typename T, bool mayBeNull>
37 struct equal_to<T*, mayBeNull> {
38  bool operator()(const T* lhs, const T* rhs) const {
39  if (lhs == rhs) {
40  return true;
41  }
42  if (mayBeNull) {
43  if (lhs == nullptr || rhs == nullptr) {
44  return false;
45  }
46  }
47  assert(lhs != nullptr);
48  assert(rhs != nullptr);
49  return std::equal_to<T>()(*lhs, *rhs);
50  }
51 };
52 
53 template<typename T, bool mayBeNull>
54 struct equal_to<std::shared_ptr<T>, mayBeNull> {
55  bool operator()(const std::shared_ptr<const T>& lhs, const std::shared_ptr<const T>& rhs) const {
56  if (lhs == rhs) {
57  return true;
58  }
59  if (mayBeNull) {
60  if (lhs == nullptr || rhs == nullptr) {
61  return false;
62  }
63  }
64  return std::equal_to<T>()(*lhs, *rhs);
65  }
66 };
67 
68 template<typename T, bool mayBeNull = true>
69 struct not_equal_to {
70  std::not_equal_to<T> neq;
71  bool operator()(const T& lhs, const T& rhs) const {
72  return neq(lhs, rhs);
73  }
74 };
75 
76 template<typename T, bool mayBeNull>
77 struct not_equal_to<T*, mayBeNull> {
78  bool operator()(const T* lhs, const T* rhs) const {
79  return !equal_to<T, mayBeNull>()(lhs, rhs);
80  }
81 };
82 
83 template<typename T, bool mayBeNull>
84 struct not_equal_to<std::shared_ptr<T>, mayBeNull> {
85  bool operator()(const std::shared_ptr<const T>& lhs, const std::shared_ptr<const T>& rhs) const {
86  return !equal_to<T, mayBeNull>()(lhs, rhs);
87  }
88 };
89 
90 /**
91  * Alternative specialization of std::less for pointer types.
92  *
93  * We consider two pointers equal, if they point to the same memory location or the objects they point to are equal.
94  * Note that the memory location may also be zero.
95  */
96 template<typename T, bool mayBeNull = true>
97 struct less {
98  std::less<T> _less;
99  bool operator()(const T& lhs, const T& rhs) const {
100  return _less(lhs, rhs);
101  }
102 };
103 
104 template<typename T, bool mayBeNull>
105 struct less<T*, mayBeNull> {
106  std::less<T> _less;
107  bool operator()(const T* lhs, const T* rhs) const {
108  if (lhs == rhs) {
109  return false;
110  }
111  if (mayBeNull) {
112  if (lhs == nullptr || rhs == nullptr) {
113  return lhs == nullptr;
114  }
115  }
116  return _less(*lhs, *rhs);
117  }
118 };
119 
120 template<typename T, bool mayBeNull>
121 struct less<std::shared_ptr<T>, mayBeNull> {
122  std::less<T> _less;
123  bool operator()(const std::shared_ptr<const T>& lhs, const std::shared_ptr<const T>& rhs) const {
124  if (lhs == rhs) {
125  return false;
126  }
127  if (mayBeNull) {
128  if (lhs == nullptr || rhs == nullptr) {
129  return lhs == nullptr;
130  }
131  }
132  return _less(*lhs, *rhs);
133  }
134 };
135 
136 template<typename T, bool mayBeNull = true>
137 struct greater {
138  std::greater<T> _greater;
139  bool operator()(const T& lhs, const T& rhs) const {
140  return _greater(lhs, rhs);
141  }
142 };
143 
144 template<typename T, bool mayBeNull>
145 struct greater<T*, mayBeNull> {
146  bool operator()(const T* lhs, const T* rhs) const {
147  return less<T, mayBeNull>()(rhs, lhs);
148  }
149 };
150 
151 template<typename T, bool mayBeNull>
152 struct greater<std::shared_ptr<T>, mayBeNull> {
153  bool operator()(const std::shared_ptr<const T>& lhs, const std::shared_ptr<const T>& rhs) const {
154  return less<T, mayBeNull>()(rhs, lhs);
155  }
156 };
157 
158 /**
159  * Alternative specialization of std::hash for pointer types.
160  *
161  * In case the pointer is not a nullptr, we return the hash of the object it points to.
162  */
163 template<typename T, bool mayBeNull = true>
164 struct hash {
165  std::hash<T> _hash;
166  bool operator()(const T& lhs, const T& rhs) const {
167  return _hash(lhs, rhs);
168  }
169 };
170 
171 template<typename T, bool mayBeNull>
172 struct hash<T*, mayBeNull> {
173  std::size_t operator()(const T* t) const {
174  if (mayBeNull) {
175  if (t == nullptr) {
176  return 0;
177  }
178  }
179  return std::hash<T>()(*t);
180  }
181 };
182 
183 template<typename T, bool mayBeNull>
184 struct hash<std::shared_ptr<T>, mayBeNull> {
185  std::size_t operator()(const std::shared_ptr<T>& t) const {
186  if (mayBeNull) {
187  if (t == nullptr) {
188  return 0;
189  }
190  }
191  return std::hash<T>()(*t);
192  }
193 };
194 
195 }
carl is the main namespace for the library.
Alternative specialization of std::equal_to for pointer types.
bool operator()(const T &lhs, const T &rhs) const
std::equal_to< T > eq
bool operator()(const T *lhs, const T *rhs) const
bool operator()(const std::shared_ptr< const T > &lhs, const std::shared_ptr< const T > &rhs) const
std::not_equal_to< T > neq
bool operator()(const T &lhs, const T &rhs) const
bool operator()(const T *lhs, const T *rhs) const
bool operator()(const std::shared_ptr< const T > &lhs, const std::shared_ptr< const T > &rhs) const
Alternative specialization of std::less for pointer types.
std::less< T > _less
bool operator()(const T &lhs, const T &rhs) const
bool operator()(const T *lhs, const T *rhs) const
bool operator()(const std::shared_ptr< const T > &lhs, const std::shared_ptr< const T > &rhs) const
bool operator()(const T &lhs, const T &rhs) const
std::greater< T > _greater
bool operator()(const T *lhs, const T *rhs) const
bool operator()(const std::shared_ptr< const T > &lhs, const std::shared_ptr< const T > &rhs) const
Alternative specialization of std::hash for pointer types.
bool operator()(const T &lhs, const T &rhs) const
std::hash< T > _hash
std::size_t operator()(const T *t) const
std::size_t operator()(const std::shared_ptr< T > &t) const