diff options
author | Pedro Alves <pedro@palves.net> | 2022-07-19 00:26:33 +0100 |
---|---|---|
committer | Pedro Alves <pedro@palves.net> | 2022-07-25 16:04:05 +0100 |
commit | e249e6b8012ea0a14e5768d31becd7b4caff8e77 (patch) | |
tree | ec2b076aae5d31a0c08077cb3ac663ef701f1d09 /gdbsupport/packed.h | |
parent | 4ca26ad7dec88ab6fa8507ba069e9f1b3c5196da (diff) | |
download | gdb-e249e6b8012ea0a14e5768d31becd7b4caff8e77.zip gdb-e249e6b8012ea0a14e5768d31becd7b4caff8e77.tar.gz gdb-e249e6b8012ea0a14e5768d31becd7b4caff8e77.tar.bz2 |
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/packed.h')
-rw-r--r-- | gdbsupport/packed.h | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/gdbsupport/packed.h b/gdbsupport/packed.h index 53164a9..d721b02 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 |