// 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();
}