xref: /llvm-project/libcxx/test/std/atomics/atomics.ref/bitwise_and_assign.pass.cpp (revision 09e3a360581dc36d0820d3fb6da9bd7cfed87b5d)
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