llvm-project/libcxx/test/support/atomic_helpers.h

143 lines
3.7 KiB
C++

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef ATOMIC_HELPERS_H
#define ATOMIC_HELPERS_H
#include <cassert>
#include "test_macros.h"
struct UserAtomicType {
int i;
explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
friend bool operator==(const UserAtomicType& x, const UserAtomicType& y) { return x.i == y.i; }
};
/*
Enable these once we have P0528
struct WeirdUserAtomicType
{
char i, j, k; // the 3 chars of doom
explicit WeirdUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
friend bool operator==(const WeirdUserAtomicType& x, const WeirdUserAtomicType& y)
{ return x.i == y.i; }
};
struct PaddedUserAtomicType
{
char i; int j; // probably lock-free?
explicit PaddedUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
friend bool operator==(const PaddedUserAtomicType& x, const PaddedUserAtomicType& y)
{ return x.i == y.i; }
};
*/
struct LargeUserAtomicType {
int a[128]; /* decidedly not lock-free */
LargeUserAtomicType(int d = 0) TEST_NOEXCEPT {
for (auto&& e : a)
e = d++;
}
friend bool operator==(LargeUserAtomicType const& x, LargeUserAtomicType const& y) TEST_NOEXCEPT {
for (int i = 0; i < 128; ++i)
if (x.a[i] != y.a[i])
return false;
return true;
}
};
template <template <class TestArg> class TestFunctor>
struct TestEachIntegralType {
void operator()() const {
TestFunctor<char>()();
TestFunctor<signed char>()();
TestFunctor<unsigned char>()();
TestFunctor<short>()();
TestFunctor<unsigned short>()();
TestFunctor<int>()();
TestFunctor<unsigned int>()();
TestFunctor<long>()();
TestFunctor<unsigned long>()();
TestFunctor<long long>()();
TestFunctor<unsigned long long>()();
TestFunctor<wchar_t>()();
#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
TestFunctor<char8_t>()();
#endif
#ifndef TEST_HAS_NO_UNICODE_CHARS
TestFunctor<char16_t>()();
TestFunctor<char32_t>()();
#endif
TestFunctor<int8_t>()();
TestFunctor<uint8_t>()();
TestFunctor<int16_t>()();
TestFunctor<uint16_t>()();
TestFunctor<int32_t>()();
TestFunctor<uint32_t>()();
TestFunctor<int64_t>()();
TestFunctor<uint64_t>()();
}
};
template <template <class TestArg> class TestFunctor>
struct TestEachFloatingPointType {
void operator()() const {
TestFunctor<float>()();
TestFunctor<double>()();
TestFunctor<long double>()();
}
};
template <template <class TestArg> class TestFunctor>
struct TestEachPointerType {
void operator()() const {
TestFunctor<int*>()();
TestFunctor<const int*>()();
}
};
template <template <class TestArg> class TestFunctor>
struct TestEachAtomicType {
void operator()() const {
TestEachIntegralType<TestFunctor>()();
TestFunctor<UserAtomicType>()();
/*
Note: These aren't going to be lock-free,
so some libatomic.a is necessary. To handle
the case where the support functions are
missing, all tests that use this file should add:
XFAIL: !non-lockfree-atomics
*/
TestFunctor<LargeUserAtomicType>()();
/*
Enable these once we have P0528
TestFunctor<PaddedUserAtomicType>()();
TestFunctor<WeirdUserAtomicType>()();
*/
TestFunctor<int*>()();
TestFunctor<const int*>()();
TestFunctor<float>()();
TestFunctor<double>()();
}
};
#endif // ATOMIC_HELPERS_H