brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · 1f287f6 Raw
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_plus_equals = requires { std::declval<T const>() += std::declval<T>(); };27 28template <typename T>29struct TestDoesNotHaveOperatorPlusEquals {30  void operator()() const { static_assert(!has_operator_plus_equals<std::atomic_ref<T>>); }31};32 33template <typename T>34struct TestOperatorPlusEquals {35  void operator()() const {36    if constexpr (std::is_arithmetic_v<T>) {37      T x(T(1));38      std::atomic_ref<T> const a(x);39 40      std::same_as<T> decltype(auto) y = (a += T(2));41      assert(y == T(3));42      assert(x == T(3));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[1]};48      std::atomic_ref<T> const a(p);49 50      std::same_as<T> decltype(auto) y = (a += 2);51      assert(y == &t[3]);52      assert(a == &t[3]);53      ASSERT_NOEXCEPT(a += 0);54    } else {55      static_assert(std::is_void_v<T>);56    }57 58    // memory_order::seq_cst59    {60      auto plus_equals = [](std::atomic_ref<T> const& x, T old_val, T new_val) { x += (new_val - old_val); };61      auto load        = [](std::atomic_ref<T> const& x) { return x.load(); };62      test_seq_cst<T>(plus_equals, load);63    }64  }65};66 67int main(int, char**) {68  TestEachIntegralType<TestOperatorPlusEquals>()();69 70  TestOperatorPlusEquals<float>()();71  TestOperatorPlusEquals<double>()();72 73  TestEachPointerType<TestOperatorPlusEquals>()();74 75  TestDoesNotHaveOperatorPlusEquals<bool>()();76  TestDoesNotHaveOperatorPlusEquals<UserAtomicType>()();77  TestDoesNotHaveOperatorPlusEquals<LargeUserAtomicType>()();78 79  return 0;80}81