diff --git a/coord/ops.hpp b/coord/ops.hpp index c996b8d4..70dadb81 100644 --- a/coord/ops.hpp +++ b/coord/ops.hpp @@ -1052,6 +1052,53 @@ namespace util { 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 class K, + typename = std::enable_if_t< + is_coord_v>, void + > + > + constexpr + K + rshift (const K k, const int num, const K fill) + { + CHECK_LIMIT (num, 0, int (S)); + + K 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 class K, + typename = std::enable_if_t< + is_coord_v>, void + > + > + constexpr + K + rshift (const K k, const int num, T fill) + { + return rshift (k, num, K {fill}); + } + + /// returns the data at a templated index in a coordinate. /// /// specifically required for structured bindings support. diff --git a/test/coord.cpp b/test/coord.cpp index 8de918aa..7f606db9 100644 --- a/test/coord.cpp +++ b/test/coord.cpp @@ -99,5 +99,17 @@ main (void) 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 (); }