coord/base: add restrictions to redim with/out params

redim to lower dimensionality should not allow a parameter, and redim to
higher dimensions should require a fill parameter.
This commit is contained in:
Danny Robson 2017-08-24 14:34:46 +10:00
parent 1d4992e3e4
commit ad345f19d5

View File

@ -18,6 +18,8 @@
#define __UTIL_COORD_BASE_HPP #define __UTIL_COORD_BASE_HPP
#include "init.hpp" #include "init.hpp"
#include "./ops.hpp"
#include "../maths.hpp" #include "../maths.hpp"
#include <algorithm> #include <algorithm>
@ -103,51 +105,59 @@ namespace util::coord {
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// redimension /// returns an instance with the same data, but truncated to `D'
template <size_t D> /// elements
KLASS<D,T> ///
/// explicitly does not allow a fill parameter given it can't be used
/// when reducing dimensions.
template <std::size_t D>
std::enable_if_t<
D <= S, KLASS<D,T>
>
redim (void) const redim (void) const
{ {
KLASS<D,T> out; KLASS<D,T> out;
std::copy_n (std::cbegin (this->data), std::copy_n (cbegin (), D, std::begin (out.data));
min (S, D),
std::begin (out.data));
return out; return out;
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
template<size_t D> /// returns an instance with the same data, but more elements, where
KLASS<D,T> /// the new elements are initialised with values with the same index
/// in the coordinate `fill'.
///
/// explicitly requires a fill parameter so that we avoid undefined
/// values.
template <std::size_t D>
std::enable_if_t<
(D > S), KLASS<D,T>
>
redim (const KLASS<D,T> fill) const redim (const KLASS<D,T> fill) const
{ {
KLASS<D,T> out; KLASS<D,T> out;
static constexpr auto L1 = min (S, D); auto next = std::copy (cbegin (), cend (), std::begin (out));
static constexpr auto L2 = D - L1; std::copy (std::cbegin (fill) + S, std::cend (fill), next);
std::copy_n (std::cbegin (this->data),
L1,
std::begin (out.data));
std::copy_n (fill.data + L1,
L2,
out.data + L1);
return out; return out;
} }
//--------------------------------------------------------------------- //---------------------------------------------------------------------
template <size_t D> /// returns an instance with the same data, but more elements, where
KLASS<D,T> /// all the new elemenst are initialised with the scalar `fill'.
///
/// explicitly requires a fill parameter so that we avoid undefined
/// values.
template <std::size_t D>
std::enable_if_t<
(D > S), KLASS<D,T>
>
redim (T fill) const redim (T fill) const
{ {
KLASS<D,T> out; KLASS<D,T> out;
auto cursor = std::copy_n (std::cbegin (this->data), auto next = std::copy (cbegin (), cend (), std::begin (out));
min (S, D), std::fill (next, std::end (out), fill);
std::begin (out.data));
std::fill (cursor, std::end (out.data), fill);
return out; return out;
} }
}; };