142ba740aSDamien L-G // 242ba740aSDamien L-G // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 342ba740aSDamien L-G // See https://llvm.org/LICENSE.txt for license information. 442ba740aSDamien L-G // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 542ba740aSDamien L-G // 642ba740aSDamien L-G //===----------------------------------------------------------------------===// 742ba740aSDamien L-G 842ba740aSDamien L-G // UNSUPPORTED: c++03, c++11, c++14, c++17 942ba740aSDamien L-G // XFAIL: !has-64-bit-atomics 1042ba740aSDamien L-G 1142ba740aSDamien L-G // integral-type operator&=(integral-type) const noexcept; 1242ba740aSDamien L-G 1342ba740aSDamien L-G #include <atomic> 1442ba740aSDamien L-G #include <cassert> 1542ba740aSDamien L-G #include <concepts> 1642ba740aSDamien L-G #include <type_traits> 17*09e3a360SLouis Dionne #include <utility> 1842ba740aSDamien L-G 1942ba740aSDamien L-G #include "atomic_helpers.h" 2042ba740aSDamien L-G #include "test_macros.h" 2142ba740aSDamien L-G 2242ba740aSDamien L-G template <typename T> 2342ba740aSDamien L-G concept has_bitwise_and_assign = requires { std::declval<T const>() &= std::declval<T>(); }; 2442ba740aSDamien L-G 2542ba740aSDamien L-G template <typename T> 2642ba740aSDamien L-G struct TestDoesNotHaveBitwiseAndAssign { 2742ba740aSDamien L-G void operator()() const { static_assert(!has_bitwise_and_assign<std::atomic_ref<T>>); } 2842ba740aSDamien L-G }; 2942ba740aSDamien L-G 3042ba740aSDamien L-G template <typename T> 3142ba740aSDamien L-G struct TestBitwiseAndAssign { 3242ba740aSDamien L-G void operator()() const { 3342ba740aSDamien L-G static_assert(std::is_integral_v<T>); 3442ba740aSDamien L-G 3542ba740aSDamien L-G T x(T(1)); 3642ba740aSDamien L-G std::atomic_ref<T> const a(x); 3742ba740aSDamien L-G 3842ba740aSDamien L-G std::same_as<T> decltype(auto) y = (a &= T(1)); 3942ba740aSDamien L-G assert(y == T(1)); 4042ba740aSDamien L-G assert(x == T(1)); 4142ba740aSDamien L-G ASSERT_NOEXCEPT(a &= T(0)); 4242ba740aSDamien L-G 4342ba740aSDamien L-G y = (a &= T(2)); 4442ba740aSDamien L-G assert(y == T(0)); 4542ba740aSDamien L-G assert(x == T(0)); 4642ba740aSDamien L-G } 4742ba740aSDamien L-G }; 4842ba740aSDamien L-G 4942ba740aSDamien L-G int main(int, char**) { 5042ba740aSDamien L-G TestEachIntegralType<TestBitwiseAndAssign>()(); 5142ba740aSDamien L-G 5242ba740aSDamien L-G TestEachFloatingPointType<TestDoesNotHaveBitwiseAndAssign>()(); 5342ba740aSDamien L-G 5442ba740aSDamien L-G TestEachPointerType<TestDoesNotHaveBitwiseAndAssign>()(); 5542ba740aSDamien L-G 5642ba740aSDamien L-G TestDoesNotHaveBitwiseAndAssign<bool>()(); 5742ba740aSDamien L-G TestDoesNotHaveBitwiseAndAssign<UserAtomicType>()(); 5842ba740aSDamien L-G TestDoesNotHaveBitwiseAndAssign<LargeUserAtomicType>()(); 5942ba740aSDamien L-G 6042ba740aSDamien L-G return 0; 6142ba740aSDamien L-G } 62