81 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 operator-=(integral-type) const noexcept;12// floating-point-type operator-=(floating-point-type) const noexcept;13// T* operator-=(difference_type) const noexcept;14 15#include <atomic>16#include <cassert>17#include <concepts>18#include <type_traits>19#include <utility>20 21#include "atomic_helpers.h"22#include "test_helper.h"23#include "test_macros.h"24 25template <typename T>26concept has_operator_minus_equals = requires { std::declval<T const>() -= std::declval<T>(); };27 28template <typename T>29struct TestDoesNotHaveOperatorMinusEquals {30 void operator()() const { static_assert(!has_operator_minus_equals<std::atomic_ref<T>>); }31};32 33template <typename T>34struct TestOperatorMinusEquals {35 void operator()() const {36 if constexpr (std::is_arithmetic_v<T>) {37 T x(T(3));38 std::atomic_ref<T> const a(x);39 40 std::same_as<T> decltype(auto) y = (a -= T(2));41 assert(y == T(1));42 assert(x == T(1));43 ASSERT_NOEXCEPT(a -= T(0));44 } else if constexpr (std::is_pointer_v<T>) {45 using U = std::remove_pointer_t<T>;46 U t[9] = {};47 T p{&t[3]};48 std::atomic_ref<T> const a(p);49 50 std::same_as<T> decltype(auto) y = (a -= 2);51 assert(y == &t[1]);52 assert(a == &t[1]);53 ASSERT_NOEXCEPT(a -= 0);54 } else {55 static_assert(std::is_void_v<T>);56 }57 58 // memory_order::seq_cst59 {60 auto minus_equals = [](std::atomic_ref<T> const& x, T old_val, T new_val) { x -= (old_val - new_val); };61 auto load = [](std::atomic_ref<T> const& x) { return x.load(); };62 test_seq_cst<T>(minus_equals, load);63 }64 }65};66 67int main(int, char**) {68 TestEachIntegralType<TestOperatorMinusEquals>()();69 70 TestOperatorMinusEquals<float>()();71 TestOperatorMinusEquals<double>()();72 73 TestEachPointerType<TestOperatorMinusEquals>()();74 75 TestDoesNotHaveOperatorMinusEquals<bool>()();76 TestDoesNotHaveOperatorMinusEquals<UserAtomicType>()();77 TestDoesNotHaveOperatorMinusEquals<LargeUserAtomicType>()();78 79 return 0;80}81