// Copyright (C) 2020-2024 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this library; see the file COPYING3. If not see // . // expensive: * [1-9] * * #include "bits/main.h" using std::experimental::simd_cast; using std::experimental::static_simd_cast; template struct gen_cast { std::array data; template gen_cast(const V& v) { for (size_t i = 0; i < V::size(); ++i) { data[i] = static_cast(v[i]); } } template constexpr T operator()(I) { return data[I::value]; } }; template struct gen_seq_t { using From = typename V::value_type; const size_t N = cvt_input_data.size(); size_t offset = 0; constexpr void operator++() { offset += V::size(); } explicit constexpr operator bool() const { return offset < N; } template constexpr From operator()(I) const { size_t i = I::value + offset; return i < N ? cvt_input_data[i] : From(i); } }; template struct foo { template auto operator()(const T& v) -> decltype(simd_cast(v)); }; template void casts() { using From = typename V::value_type; constexpr auto N = V::size(); if constexpr (N <= std::experimental::simd_abi::max_fixed_size) { using W = std::experimental::fixed_size_simd; if constexpr (std::is_integral_v) { using A = typename V::abi_type; using TU = std::make_unsigned_t; using TS = std::make_signed_t; COMPARE(typeid(static_simd_cast(V())), typeid(std::experimental::simd)); COMPARE(typeid(static_simd_cast(V())), typeid(std::experimental::simd)); } using is_simd_cast_allowed = decltype(vir::test::sfinae_is_callable_t(foo())); COMPARE(is_simd_cast_allowed::value, std::__digits::value <= std::__digits::value && std::__finite_max::value <= std::__finite_max::value && !(std::is_signed::value && std::is_unsigned::value)); if constexpr (is_simd_cast_allowed::value) { for (gen_seq_t gen_seq; gen_seq; ++gen_seq) { const V seq(gen_seq); COMPARE(simd_cast(seq), seq); COMPARE(simd_cast(seq), W(gen_cast(seq))) << "seq = " << seq; auto test = simd_cast(seq); // decltype(test) is not W if // a) V::abi_type is not fixed_size and // b.1) V::value_type and To are integral and of equal rank or // b.2) V::value_type and To are equal COMPARE(test, decltype(test)(gen_cast(seq))); if (std::is_same::value) { COMPARE(typeid(decltype(test)), typeid(V)); } } } for (gen_seq_t gen_seq; gen_seq; ++gen_seq) { const V seq(gen_seq); COMPARE(static_simd_cast(seq), seq); COMPARE(static_simd_cast(seq), W(gen_cast(seq))) << '\n' << seq; auto test = static_simd_cast(seq); // decltype(test) is not W if // a) V::abi_type is not fixed_size and // b.1) V::value_type and To are integral and of equal rank or // b.2) V::value_type and To are equal COMPARE(test, decltype(test)(gen_cast(seq))); if (std::is_same::value) { COMPARE(typeid(decltype(test)), typeid(V)); } } } } template void test() { casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); casts(); }