1 // 2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3 // See https://llvm.org/LICENSE.txt for license information. 4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // 6 //===----------------------------------------------------------------------===// 7 8 // UNSUPPORTED: c++03, c++11, c++14, c++17 9 // XFAIL: !has-64-bit-atomics 10 11 // integral-type fetch_and(integral-type, memory_order = memory_order::seq_cst) const noexcept; 12 13 #include <atomic> 14 #include <cassert> 15 #include <concepts> 16 #include <type_traits> 17 #include <utility> 18 19 #include "atomic_helpers.h" 20 #include "test_macros.h" 21 22 template <typename T> 23 concept has_fetch_and = requires { 24 std::declval<T const>().fetch_and(std::declval<T>()); 25 std::declval<T const>().fetch_and(std::declval<T>(), std::declval<std::memory_order>()); 26 }; 27 28 template <typename T> 29 struct TestDoesNotHaveFetchAnd { 30 void operator()() const { static_assert(!has_fetch_and<std::atomic_ref<T>>); } 31 }; 32 33 template <typename T> 34 struct TestFetchAnd { 35 void operator()() const { 36 static_assert(std::is_integral_v<T>); 37 38 T x(T(1)); 39 std::atomic_ref<T> const a(x); 40 41 { 42 std::same_as<T> decltype(auto) y = a.fetch_and(T(2)); 43 assert(y == T(1)); 44 assert(x == T(0)); 45 ASSERT_NOEXCEPT(a.fetch_and(T(0))); 46 } 47 48 x = T(1); 49 50 { 51 std::same_as<T> decltype(auto) y = a.fetch_and(T(2), std::memory_order_relaxed); 52 assert(y == T(1)); 53 assert(x == T(0)); 54 ASSERT_NOEXCEPT(a.fetch_and(T(0), std::memory_order_relaxed)); 55 } 56 } 57 }; 58 59 int main(int, char**) { 60 TestEachIntegralType<TestFetchAnd>()(); 61 62 TestEachFloatingPointType<TestDoesNotHaveFetchAnd>()(); 63 64 TestEachPointerType<TestDoesNotHaveFetchAnd>()(); 65 66 TestDoesNotHaveFetchAnd<bool>()(); 67 TestDoesNotHaveFetchAnd<UserAtomicType>()(); 68 TestDoesNotHaveFetchAnd<LargeUserAtomicType>()(); 69 return 0; 70 } 71