coord/ops: add rshift coord operation

shifts each element to the right `num' places and fills the left space
with a constant or elements from another vector.
This commit is contained in:
Danny Robson 2017-08-25 13:03:21 +10:00
parent e9ef2ae316
commit 3c9dcba2fb
2 changed files with 59 additions and 0 deletions

View File

@ -1052,6 +1052,53 @@ namespace util {
return out; return out;
} }
///////////////////////////////////////////////////////////////////////////
/// shifts all elements `num' indices to the right, setting the left-most
/// `num' indices to the value `fill'.
///
/// num must be between 0 and S. when 0 it is equivalent to an ordinary
/// fill, when S it is equivalent to a noop.
template<
std::size_t S,
typename T,
template <size_t,typename> class K,
typename = std::enable_if_t<
is_coord_v<K<S,T>>, void
>
>
constexpr
K<S,T>
rshift (const K<S,T> k, const int num, const K<S,T> fill)
{
CHECK_LIMIT (num, 0, int (S));
K<S,T> res {};
std::copy_n (std::cbegin (k), S - num, std::begin (res) + num);
std::copy_n (std::cbegin (fill), num, std::begin (res));
return res;
}
//-------------------------------------------------------------------------
template<
std::size_t S,
typename T,
template <size_t,typename> class K,
typename = std::enable_if_t<
is_coord_v<K<S,T>>, void
>
>
constexpr
K<S,T>
rshift (const K<S,T> k, const int num, T fill)
{
return rshift (k, num, K<S,T> {fill});
}
/// returns the data at a templated index in a coordinate. /// returns the data at a templated index in a coordinate.
/// ///
/// specifically required for structured bindings support. /// specifically required for structured bindings support.

View File

@ -99,5 +99,17 @@ main (void)
tap.expect_eq (seq.indices<2,0,0,1> (), res, "coord::indices expansion"); tap.expect_eq (seq.indices<2,0,0,1> (), res, "coord::indices expansion");
}; };
// ensure that util::shift operations appear to operate correctly
{
const util::vector3i seq { 0, 1, 2 };
tap.expect_eq (rshift (seq, 1, 0), util::make_vector (0, 0, 1), "rshift, scalar fill");
tap.expect_eq (
rshift (seq, 2, util::make_vector (3, 4, 5 )),
util::make_vector (3, 4, 0),
"rshift, coord fill"
);
};
return tap.status (); return tap.status ();
} }