coord: mitigate gcc ICE when using redim

This commit is contained in:
Danny Robson 2018-01-17 13:27:57 +11:00
parent b4e242ffd4
commit a8b4c93ccd
2 changed files with 33 additions and 18 deletions

View File

@ -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;
}

View File

@ -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.
{