98 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// <experimental/simd>12//13// [simd.reference]14// template<class U> reference+=(U&& x) && noexcept;15// template<class U> reference-=(U&& x) && noexcept;16// template<class U> reference*=(U&& x) && noexcept;17// template<class U> reference/=(U&& x) && noexcept;18// template<class U> reference%=(U&& x) && noexcept;19 20#include <experimental/simd>21#include <functional>22 23#include "../test_utils.h"24 25namespace ex = std::experimental::parallelism_v2;26 27struct PlusAssign {28 template <typename T, typename U>29 void operator()(T&& lhs, const U& rhs) const noexcept {30 std::forward<T>(lhs) += rhs;31 }32};33 34struct MinusAssign {35 template <typename T, typename U>36 void operator()(T&& lhs, const U& rhs) const noexcept {37 std::forward<T>(lhs) -= rhs;38 }39};40 41struct MultipliesAssign {42 template <typename T, typename U>43 void operator()(T&& lhs, const U& rhs) const noexcept {44 std::forward<T>(lhs) *= rhs;45 }46};47 48struct DividesAssign {49 template <typename T, typename U>50 void operator()(T&& lhs, const U& rhs) const noexcept {51 std::forward<T>(lhs) /= rhs;52 }53};54 55struct ModulusAssign {56 template <typename T, typename U>57 void operator()(T&& lhs, const U& rhs) const noexcept {58 std::forward<T>(lhs) %= rhs;59 }60};61 62template <typename T, typename SimdAbi, typename Op, typename OpAssign>63struct SimdReferenceOperatorHelper {64 template <class U>65 void operator()() const {66 ex::simd<T, SimdAbi> origin_simd(static_cast<T>(3));67 static_assert(noexcept(OpAssign{}(origin_simd[0], static_cast<U>(2))));68 OpAssign{}(origin_simd[0], static_cast<U>(2));69 assert((T)origin_simd[0] == (T)Op{}(static_cast<T>(3), static_cast<T>(std::forward<U>(2))));70 }71};72 73template <class T, std::size_t>74struct CheckReferenceArithOperators {75 template <class SimdAbi>76 void operator()() {77 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::plus<>, PlusAssign>());78 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::minus<>, MinusAssign>());79 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::multiplies<>, MultipliesAssign>());80 types::for_each(simd_test_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::divides<>, DividesAssign>());81 }82};83 84template <class T, std::size_t>85struct CheckReferenceModOperators {86 template <class SimdAbi>87 void operator()() {88 types::for_each(89 simd_test_integer_types(), SimdReferenceOperatorHelper<T, SimdAbi, std::modulus<>, ModulusAssign>());90 }91};92 93int main(int, char**) {94 test_all_simd_abi<CheckReferenceArithOperators>();95 types::for_each(types::integer_types(), TestAllSimdAbiFunctor<CheckReferenceModOperators>());96 return 0;97}98