coord: mitigate gcc ICE when using redim
This commit is contained in:
parent
b4e242ffd4
commit
a8b4c93ccd
@ -148,21 +148,24 @@ namespace util::coord {
|
||||
///
|
||||
/// explicitly does not allow a fill parameter given it can't be used
|
||||
/// when reducing dimensions.
|
||||
///
|
||||
/// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or
|
||||
/// similar algorithms to move the data as it produces an ICE on some
|
||||
/// code fragements if it does. Namely:
|
||||
/// "internal compiler error: in trunc_int_for_mode, at explow.c:55"
|
||||
template <
|
||||
size_t D,
|
||||
typename _sfinae = SelfT
|
||||
>
|
||||
std::enable_if_t<
|
||||
has_redim_v<_sfinae>,
|
||||
redim_t<_sfinae,D>
|
||||
typename = std::enable_if_t<
|
||||
has_redim_v<SelfT> && S >= D,
|
||||
void
|
||||
>
|
||||
>
|
||||
auto
|
||||
redim (void) const
|
||||
{
|
||||
redim_t<SelfT,D> out;
|
||||
|
||||
std::copy_n (std::cbegin (this->data),
|
||||
min (S, D),
|
||||
std::begin (out.data));
|
||||
for (size_t i = 0; i < D; ++i)
|
||||
out[i] = this->data[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -174,17 +177,24 @@ namespace util::coord {
|
||||
///
|
||||
/// explicitly requires a fill parameter so that we avoid undefined
|
||||
/// values.
|
||||
///
|
||||
/// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or
|
||||
/// similar algorithms to move the data as it produces an ICE on some
|
||||
/// code fragements if it does. Namely:
|
||||
/// "internal compiler error: in trunc_int_for_mode, at explow.c:55"
|
||||
template<size_t D,typename _sfinae = SelfT>
|
||||
std::enable_if_t<
|
||||
has_redim_v<_sfinae>,
|
||||
has_redim_v<_sfinae> && S <= D,
|
||||
redim_t<_sfinae,D>
|
||||
>
|
||||
redim (const redim_t<_sfinae,D> fill) const
|
||||
{
|
||||
redim_t<SelfT,D> out;
|
||||
|
||||
auto next = std::copy (cbegin (), cend (), std::begin (out));
|
||||
std::copy (std::cbegin (fill) + S, std::cend (fill), next);
|
||||
for (size_t i = 0; i < S; ++i)
|
||||
out[i] = this->data[i];
|
||||
for (size_t i = S; i < D; ++i)
|
||||
out[i] = fill[i];
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -194,20 +204,26 @@ namespace util::coord {
|
||||
///
|
||||
/// explicitly requires a fill parameter so that we avoid undefined
|
||||
/// values.
|
||||
///
|
||||
/// HACK,gcc#,gcc-7.x: This function _must not_ use std::copy or
|
||||
/// similar algorithms to move the data as it produces an ICE on some
|
||||
/// code fragements if it does. Namely:
|
||||
/// "internal compiler error: in trunc_int_for_mode, at explow.c:55"
|
||||
template <
|
||||
size_t D,
|
||||
typename _sfinae = SelfT
|
||||
>
|
||||
std::enable_if_t<
|
||||
has_redim_v<_sfinae>,
|
||||
has_redim_v<_sfinae> && S <= D,
|
||||
redim_t<_sfinae,D>
|
||||
>
|
||||
redim (T fill) const
|
||||
{
|
||||
redim_t<SelfT,D> out;
|
||||
|
||||
auto next = std::copy (cbegin (), cend (), std::begin (out));
|
||||
std::fill (next, std::end (out), fill);
|
||||
for (size_t i = 0; i < S; ++i)
|
||||
out[i] = this->data[i];
|
||||
for (size_t i = S; i < D; ++i)
|
||||
out[i] = fill;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ main (void)
|
||||
const point2f r { 0.f, 1.f };
|
||||
|
||||
tap.expect_eq (q, r, "redim to lower dimension");
|
||||
|
||||
}
|
||||
|
||||
// Redim to higher dimension without fill
|
||||
@ -39,7 +40,6 @@ main (void)
|
||||
//
|
||||
// HACK: This fails under GCC-7.1.0, and i'm not wasting any more time
|
||||
// reducing this test case. it's _really_ template heavy.
|
||||
#if !(__GNUC_PREREQ (7, 1))
|
||||
{
|
||||
static const point4f FILL (1.f, 2.f, 3.f, 4.f);
|
||||
const point2f p (0.1f, 1.f);
|
||||
@ -54,7 +54,6 @@ main (void)
|
||||
"redim to higher with fill"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Simple linking check for coord type casting. Relies on truncation.
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user