brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 15bf0ec Raw
134 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++(int) const noexcept;12// integral-type operator--(int) const noexcept;13// integral-type operator++() const noexcept;14// integral-type operator--() const noexcept;15 16#include <atomic>17#include <cassert>18#include <concepts>19#include <type_traits>20#include <utility>21 22#include "atomic_helpers.h"23#include "test_macros.h"24 25template <typename T>26concept has_pre_increment_operator = requires { ++std::declval<T const>(); };27 28template <typename T>29concept has_post_increment_operator = requires { std::declval<T const>()++; };30 31template <typename T>32concept has_pre_decrement_operator = requires { --std::declval<T const>(); };33 34template <typename T>35concept has_post_decrement_operator = requires { std::declval<T const>()--; };36 37template <typename T>38constexpr bool does_not_have_increment_nor_decrement_operators() {39  return !has_pre_increment_operator<T> && !has_pre_decrement_operator<T> && !has_post_increment_operator<T> &&40         !has_post_decrement_operator<T>;41}42 43template <typename T>44struct TestDoesNotHaveIncrementDecrement {45  void operator()() const { static_assert(does_not_have_increment_nor_decrement_operators<std::atomic_ref<T>>()); }46};47 48template <typename T>49struct TestIncrementDecrement {50  void operator()() const {51    if constexpr (std::is_integral_v<T>) {52      T x(T(1));53      std::atomic_ref<T> const a(x);54 55      {56        std::same_as<T> decltype(auto) y = ++a;57        assert(y == T(2));58        assert(x == T(2));59        ASSERT_NOEXCEPT(++a);60      }61 62      {63        std::same_as<T> decltype(auto) y = --a;64        assert(y == T(1));65        assert(x == T(1));66        ASSERT_NOEXCEPT(--a);67      }68 69      {70        std::same_as<T> decltype(auto) y = a++;71        assert(y == T(1));72        assert(x == T(2));73        ASSERT_NOEXCEPT(a++);74      }75 76      {77        std::same_as<T> decltype(auto) y = a--;78        assert(y == T(2));79        assert(x == T(1));80        ASSERT_NOEXCEPT(a--);81      }82    } else if constexpr (std::is_pointer_v<T>) {83      using U = std::remove_pointer_t<T>;84      U t[9]  = {};85      T p{&t[1]};86      std::atomic_ref<T> const a(p);87 88      {89        std::same_as<T> decltype(auto) y = ++a;90        assert(y == &t[2]);91        assert(p == &t[2]);92        ASSERT_NOEXCEPT(++a);93      }94 95      {96        std::same_as<T> decltype(auto) y = --a;97        assert(y == &t[1]);98        assert(p == &t[1]);99        ASSERT_NOEXCEPT(--a);100      }101 102      {103        std::same_as<T> decltype(auto) y = a++;104        assert(y == &t[1]);105        assert(p == &t[2]);106        ASSERT_NOEXCEPT(a++);107      }108 109      {110        std::same_as<T> decltype(auto) y = a--;111        assert(y == &t[2]);112        assert(p == &t[1]);113        ASSERT_NOEXCEPT(a--);114      }115    } else {116      static_assert(std::is_void_v<T>);117    }118  }119};120 121int main(int, char**) {122  TestEachIntegralType<TestIncrementDecrement>()();123 124  TestEachFloatingPointType<TestDoesNotHaveIncrementDecrement>()();125 126  TestEachPointerType<TestIncrementDecrement>()();127 128  TestDoesNotHaveIncrementDecrement<bool>()();129  TestDoesNotHaveIncrementDecrement<UserAtomicType>()();130  TestDoesNotHaveIncrementDecrement<LargeUserAtomicType>()();131 132  return 0;133}134