coord/base: add indices
query using supplemental values
This commit is contained in:
parent
4cf6bb292b
commit
0d9374d3dd
@ -232,22 +232,63 @@ namespace cruft::coord {
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/// returns an instance with elements specified by the Indices
|
||||
/// Returns an instance with elements specified by the Indices
|
||||
/// parameter. eg, point2f p{}.indices<0,2> would return {p.x, p.z}.
|
||||
///
|
||||
/// it's ugly as sin, but simplifies some situations where we don't
|
||||
/// want a temporary.
|
||||
template <std::size_t ...Indices>
|
||||
/// Given we don't take any arguments all indices must be valid for
|
||||
/// the current object.
|
||||
template <
|
||||
std::size_t ...Indices,
|
||||
typename = std::enable_if_t<cruft::max (Indices...) < S>
|
||||
>
|
||||
constexpr auto
|
||||
indices (void) const
|
||||
{
|
||||
return redim_t<SelfT,sizeof...(Indices)> {
|
||||
this->data[Indices]...
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// Return an instance of the same type where the elements of the new
|
||||
/// value area specified by the Indices... template parameter.
|
||||
///
|
||||
/// If the index is greater than the maximum index of this type then
|
||||
/// the value is taken from a pack of supplementary values.
|
||||
///
|
||||
/// eg, vector2f{0,1}.indices<0,2,1> (2) would result in {0,2,1}
|
||||
template <
|
||||
std::size_t ...Indices,
|
||||
typename ...U,
|
||||
typename = std::enable_if_t<
|
||||
// At least one index doesn't address our current data
|
||||
cruft::max (Indices...) >= S &&
|
||||
// The new data type must be the old data type
|
||||
(std::is_same_v<T,U> && ...)
|
||||
>
|
||||
>
|
||||
constexpr auto
|
||||
indices (U&& ...supplementary) const
|
||||
{
|
||||
static_assert (
|
||||
all (make_vector ((Indices < S)...)),
|
||||
cruft::max (Indices...) < S + sizeof...(supplementary),
|
||||
"indices must fall within the defined range for the type"
|
||||
);
|
||||
|
||||
// Expand the pack using either:
|
||||
// * data from ourselves,
|
||||
// * or rebasing the index into a tuple of the supplementary values
|
||||
//
|
||||
// The index to std::get _must_ be valid even if we don't use the
|
||||
// result (otherwise we tend to encounter static assertions). Thus
|
||||
// we conditionally specify a zero index if we know it won't get
|
||||
// used.
|
||||
return redim_t<SelfT,sizeof...(Indices)> {
|
||||
this->data[Indices]...
|
||||
Indices < S
|
||||
? this->data[Indices]
|
||||
: std::get<
|
||||
(Indices > S) ? Indices - S : 0
|
||||
> (std::tuple (supplementary...))...
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -104,9 +104,16 @@ main (void)
|
||||
// ensure that klass::indices appears to link correctly
|
||||
{
|
||||
const cruft::vector3i seq { 0, 1, 2 };
|
||||
const cruft::vector4i res { 2, 0, 0, 1 };
|
||||
|
||||
{
|
||||
const cruft::vector4i res { 2, 0, 0, 1 };
|
||||
tap.expect_eq (seq.indices<2,0,0,1> (), res, "coord::indices expansion");
|
||||
}
|
||||
|
||||
{
|
||||
const cruft::vector4i res { 2, 3, 4, 0 };
|
||||
tap.expect_eq (seq.indices<2,3,4,0> (3, 4), res, "coord::indices supplemental expansion");
|
||||
}
|
||||
};
|
||||
|
||||
// ensure that cruft::shift operations appear to operate correctly
|
||||
|
Loading…
Reference in New Issue
Block a user