summaryrefslogtreecommitdiff
path: root/gdbsupport
diff options
context:
space:
mode:
authorPedro Alves <pedro@palves.net>2022-07-19 00:26:33 +0100
committerPedro Alves <pedro@palves.net>2022-07-25 16:04:05 +0100
commite249e6b8012ea0a14e5768d31becd7b4caff8e77 (patch)
treeec2b076aae5d31a0c08077cb3ac663ef701f1d09 /gdbsupport
parent4ca26ad7dec88ab6fa8507ba069e9f1b3c5196da (diff)
downloadbinutils-gdb-e249e6b8012ea0a14e5768d31becd7b4caff8e77.tar.gz
struct packed: Unit tests and more operators
For PR gdb/29373, I wrote an alternative implementation of struct packed that uses a gdb_byte array for internal representation, needed for mingw+clang. While adding that, I wrote some unit tests to make sure both implementations behave the same. While at it, I implemented all relational operators. This commit adds said unit tests and relational operators. The alternative gdb_byte array implementation will come next. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29373 Change-Id: I023315ee03622c59c397bf4affc0b68179c32374
Diffstat (limited to 'gdbsupport')
-rw-r--r--gdbsupport/packed.h79
1 files changed, 49 insertions, 30 deletions
diff --git a/gdbsupport/packed.h b/gdbsupport/packed.h
index 53164a9e0c3..d721b02c056 100644
--- a/gdbsupport/packed.h
+++ b/gdbsupport/packed.h
@@ -19,6 +19,7 @@
#define PACKED_H
#include "traits.h"
+#include <atomic>
/* Each instantiation and full specialization of the packed template
defines a type that behaves like a given scalar type, but that has
@@ -68,37 +69,55 @@ private:
T m_val : (Bytes * HOST_CHAR_BIT) ATTRIBUTE_PACKED;
};
-/* Add some comparisons between std::atomic<packed<T>> and T. We need
- this because the regular comparisons would require two implicit
- conversions to go from T to std::atomic<packed<T>>:
-
- T -> packed<T>
- packed<T> -> std::atomic<packed<T>>
-
- and C++ only does one. */
-
-template<typename T, size_t Bytes>
-bool operator== (T lhs, const std::atomic<packed<T, Bytes>> &rhs)
-{
- return lhs == rhs.load ();
-}
-
-template<typename T, size_t Bytes>
-bool operator== (const std::atomic<packed<T, Bytes>> &lhs, T rhs)
-{
- return lhs.load () == rhs;
-}
+/* Add some comparisons between std::atomic<packed<T>> and packed<T>
+ and T. We need this because even though std::atomic<T> doesn't
+ define these operators, the relational expressions still work via
+ implicit conversions. Those wouldn't work when wrapped in packed
+ without these operators, because they'd require two implicit
+ conversions to go from T to packed<T> to std::atomic<packed<T>>
+ (and back), and C++ only does one. */
+
+#define PACKED_ATOMIC_OP(OP) \
+ template<typename T, size_t Bytes> \
+ bool operator OP (const std::atomic<packed<T, Bytes>> &lhs, \
+ const std::atomic<packed<T, Bytes>> &rhs) \
+ { \
+ return lhs.load () OP rhs.load (); \
+ } \
+ \
+ template<typename T, size_t Bytes> \
+ bool operator OP (T lhs, const std::atomic<packed<T, Bytes>> &rhs) \
+ { \
+ return lhs OP rhs.load (); \
+ } \
+ \
+ template<typename T, size_t Bytes> \
+ bool operator OP (const std::atomic<packed<T, Bytes>> &lhs, T rhs) \
+ { \
+ return lhs.load () OP rhs; \
+ } \
+ \
+ template<typename T, size_t Bytes> \
+ bool operator OP (const std::atomic<packed<T, Bytes>> &lhs, \
+ packed<T, Bytes> rhs) \
+ { \
+ return lhs.load () OP rhs; \
+ } \
+ \
+ template<typename T, size_t Bytes> \
+ bool operator OP (packed<T, Bytes> lhs, \
+ const std::atomic<packed<T, Bytes>> &rhs) \
+ { \
+ return lhs OP rhs.load (); \
+ }
-template<typename T, size_t Bytes>
-bool operator!= (T lhs, const std::atomic<packed<T, Bytes>> &rhs)
-{
- return !(lhs == rhs);
-}
+PACKED_ATOMIC_OP (==)
+PACKED_ATOMIC_OP (!=)
+PACKED_ATOMIC_OP (>)
+PACKED_ATOMIC_OP (<)
+PACKED_ATOMIC_OP (>=)
+PACKED_ATOMIC_OP (<=)
-template<typename T, size_t Bytes>
-bool operator!= (const std::atomic<packed<T, Bytes>> &lhs, T rhs)
-{
- return !(lhs == rhs);
-}
+#undef PACKED_ATOMIC_OP
#endif