71 lines · cpp
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-exception5//6//===----------------------------------------------------------------------===//7 8// UNSUPPORTED: c++03, c++11, c++14, c++179// XFAIL: !has-64-bit-atomics10 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 22template <typename T>23concept 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 28template <typename T>29struct TestDoesNotHaveFetchAnd {30 void operator()() const { static_assert(!has_fetch_and<std::atomic_ref<T>>); }31};32 33template <typename T>34struct 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 59int 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