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
|
/// explicitly does not allow a fill parameter given it can't be used
|
||||||
/// when reducing dimensions.
|
/// 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 <
|
template <
|
||||||
size_t D,
|
size_t D,
|
||||||
typename _sfinae = SelfT
|
typename = std::enable_if_t<
|
||||||
>
|
has_redim_v<SelfT> && S >= D,
|
||||||
std::enable_if_t<
|
void
|
||||||
has_redim_v<_sfinae>,
|
>
|
||||||
redim_t<_sfinae,D>
|
|
||||||
>
|
>
|
||||||
|
auto
|
||||||
redim (void) const
|
redim (void) const
|
||||||
{
|
{
|
||||||
redim_t<SelfT,D> out;
|
redim_t<SelfT,D> out;
|
||||||
|
for (size_t i = 0; i < D; ++i)
|
||||||
std::copy_n (std::cbegin (this->data),
|
out[i] = this->data[i];
|
||||||
min (S, D),
|
|
||||||
std::begin (out.data));
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,17 +177,24 @@ namespace util::coord {
|
|||||||
///
|
///
|
||||||
/// explicitly requires a fill parameter so that we avoid undefined
|
/// explicitly requires a fill parameter so that we avoid undefined
|
||||||
/// values.
|
/// 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>
|
template<size_t D,typename _sfinae = SelfT>
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
has_redim_v<_sfinae>,
|
has_redim_v<_sfinae> && S <= D,
|
||||||
redim_t<_sfinae,D>
|
redim_t<_sfinae,D>
|
||||||
>
|
>
|
||||||
redim (const redim_t<_sfinae,D> fill) const
|
redim (const redim_t<_sfinae,D> fill) const
|
||||||
{
|
{
|
||||||
redim_t<SelfT,D> out;
|
redim_t<SelfT,D> out;
|
||||||
|
|
||||||
auto next = std::copy (cbegin (), cend (), std::begin (out));
|
for (size_t i = 0; i < S; ++i)
|
||||||
std::copy (std::cbegin (fill) + S, std::cend (fill), next);
|
out[i] = this->data[i];
|
||||||
|
for (size_t i = S; i < D; ++i)
|
||||||
|
out[i] = fill[i];
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,20 +204,26 @@ namespace util::coord {
|
|||||||
///
|
///
|
||||||
/// explicitly requires a fill parameter so that we avoid undefined
|
/// explicitly requires a fill parameter so that we avoid undefined
|
||||||
/// values.
|
/// 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 <
|
template <
|
||||||
size_t D,
|
size_t D,
|
||||||
typename _sfinae = SelfT
|
typename _sfinae = SelfT
|
||||||
>
|
>
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
has_redim_v<_sfinae>,
|
has_redim_v<_sfinae> && S <= D,
|
||||||
redim_t<_sfinae,D>
|
redim_t<_sfinae,D>
|
||||||
>
|
>
|
||||||
redim (T fill) const
|
redim (T fill) const
|
||||||
{
|
{
|
||||||
redim_t<SelfT,D> out;
|
redim_t<SelfT,D> out;
|
||||||
|
for (size_t i = 0; i < S; ++i)
|
||||||
auto next = std::copy (cbegin (), cend (), std::begin (out));
|
out[i] = this->data[i];
|
||||||
std::fill (next, std::end (out), fill);
|
for (size_t i = S; i < D; ++i)
|
||||||
|
out[i] = fill;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ main (void)
|
|||||||
const point2f r { 0.f, 1.f };
|
const point2f r { 0.f, 1.f };
|
||||||
|
|
||||||
tap.expect_eq (q, r, "redim to lower dimension");
|
tap.expect_eq (q, r, "redim to lower dimension");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Redim to higher dimension without fill
|
// 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
|
// 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.
|
// 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);
|
static const point4f FILL (1.f, 2.f, 3.f, 4.f);
|
||||||
const point2f p (0.1f, 1.f);
|
const point2f p (0.1f, 1.f);
|
||||||
@ -54,7 +54,6 @@ main (void)
|
|||||||
"redim to higher with fill"
|
"redim to higher with fill"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Simple linking check for coord type casting. Relies on truncation.
|
// Simple linking check for coord type casting. Relies on truncation.
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user