@@ -49,12 +49,24 @@ constexpr bool msvc_is_lock_free_macro_value() {
49
49
#else
50
50
# error "Unknown compiler"
51
51
#endif
52
- enum class LockFreeStatus { unknown = -1 , never = 0 , sometimes = 1 , always = 2 };
53
- #define COMPARE_TYPES (T1, T2 ) (sizeof (T1) == sizeof (T2) && alignof (T1) >= alignof (T2))
52
+
53
+ // The entire LockFreeStatus/LockFreeStatusEnum/LockFreeStatusType exists entirely to work around the support
54
+ // for C++03, which many of our atomic tests run under. This is a bit of a hack, but it's the best we can do.
55
+ //
56
+ // We could limit the testing involving these things to C++11 or greater? But test coverage in C++03 seems important too.
57
+ #if TEST_STD_VER < 11
58
+ struct LockFreeStatusEnum {
59
+ enum LockFreeStatus { unknown = -1 , never = 0 , sometimes = 1 , always = 2 };
60
+ };
61
+ typedef LockFreeStatusEnum::LockFreeStatus LockFreeStatus;
62
+ #else
63
+ enum class LockFreeStatus : int { unknown = -1 , never = 0 , sometimes = 1 , always = 2 };
64
+ #endif
65
+ #define COMPARE_TYPES (T1, T2 ) (sizeof (T1) == sizeof (T2) && TEST_ALIGNOF(T1) >= TEST_ALIGNOF(T2))
54
66
55
67
template <class T >
56
- constexpr inline LockFreeStatus get_known_atomic_lock_free_status () {
57
- return LockFreeStatus{
68
+ struct LockFreeStatusInfo {
69
+ static const LockFreeStatus value = LockFreeStatus(
58
70
COMPARE_TYPES (T, char )
59
71
? TEST_ATOMIC_CHAR_LOCK_FREE
60
72
: (COMPARE_TYPES(T, short )
@@ -65,20 +77,23 @@ constexpr inline LockFreeStatus get_known_atomic_lock_free_status() {
65
77
? TEST_ATOMIC_LONG_LOCK_FREE
66
78
: (COMPARE_TYPES(T, long long )
67
79
? TEST_ATOMIC_LLONG_LOCK_FREE
68
- : (COMPARE_TYPES (T, void *) ? TEST_ATOMIC_POINTER_LOCK_FREE : -1 )))))};
69
- }
80
+ : (COMPARE_TYPES(T, void *) ? TEST_ATOMIC_POINTER_LOCK_FREE : -1 ))))));
70
81
71
- template <class T >
72
- constexpr bool is_lock_free_status_known () {
73
- return get_known_atomic_lock_free_status<T>() != LockFreeStatus::unknown;
74
- }
82
+ static const bool status_known = value != LockFreeStatus::unknown;
83
+ };
75
84
76
- static_assert (is_lock_free_status_known<char >(), "");
77
- static_assert (is_lock_free_status_known<short >(), "");
78
- static_assert (is_lock_free_status_known<int >(), "");
79
- static_assert (is_lock_free_status_known<long >(), "");
80
- static_assert (is_lock_free_status_known<long long >(), "");
81
- static_assert (is_lock_free_status_known<void *>(), "");
85
+ static_assert (LockFreeStatusInfo<char >::status_known, " " );
86
+ static_assert (LockFreeStatusInfo<short >::status_known, " " );
87
+ static_assert (LockFreeStatusInfo<int >::status_known, " " );
88
+ static_assert (LockFreeStatusInfo<long >::status_known, " " );
89
+ static_assert (LockFreeStatusInfo<long long >::status_known, " " );
90
+ static_assert (LockFreeStatusInfo<void *>::status_known, " " );
91
+
92
+ // I think these are always supposed to be lock free, and it's worth trying to hardcode expected values.
93
+ static_assert (LockFreeStatusInfo<char >::value == LockFreeStatus::always, " " );
94
+ static_assert (LockFreeStatusInfo<short >::value == LockFreeStatus::always, " " );
95
+ static_assert (LockFreeStatusInfo<int >::value == LockFreeStatus::always,
96
+ " " ); // This one may not always be lock free, but we'll let the CI decide.
82
97
83
98
// These macros are somewhat suprising to use, since they take the values 0, 1, or 2.
84
99
// To make the tests clearer, get rid of them in preference of AtomicInfo.
0 commit comments