coord/ops: make 'all' and 'any' constexpr
This commit is contained in:
parent
14718594c9
commit
84963aacf8
@ -899,38 +899,90 @@ namespace util {
|
|||||||
#undef SCALAR_OP
|
#undef SCALAR_OP
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
namespace detail {
|
||||||
|
template <
|
||||||
|
std::size_t S,
|
||||||
|
template <std::size_t,typename> class K,
|
||||||
|
std::size_t ...I,
|
||||||
|
typename = std::enable_if_t<
|
||||||
|
is_coord_v<K<S,bool>>,
|
||||||
|
void
|
||||||
|
>
|
||||||
|
>
|
||||||
|
constexpr bool
|
||||||
|
any (const K<S,bool> k, std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return (k[I] || ...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///---------------------------------------------------------------------------
|
||||||
|
/// returns true if any element is true.
|
||||||
|
///
|
||||||
|
/// this function must be suitable for use in static_assert, so it must remain
|
||||||
|
/// constexpr.
|
||||||
|
///
|
||||||
|
/// we would ideally use std::any_of, but it is not constexpr.
|
||||||
|
/// we would ideally use range-for, but cbegin is not constexpr.
|
||||||
|
/// so... moar templates.
|
||||||
template <
|
template <
|
||||||
size_t S,
|
size_t S,
|
||||||
template <size_t,typename> class K,
|
template <size_t,typename> class K,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
is_coord_v<K<S,bool>>, void
|
is_coord_v<K<S,bool>>, void
|
||||||
>
|
>,
|
||||||
|
typename Indices = std::make_index_sequence<S>
|
||||||
>
|
>
|
||||||
constexpr
|
constexpr
|
||||||
bool
|
bool
|
||||||
any (const K<S,bool> k)
|
any (const K<S,bool> k)
|
||||||
{
|
{
|
||||||
return std::any_of (std::cbegin (k),
|
return detail::any (k, Indices{});
|
||||||
std::cend (k),
|
}
|
||||||
identity<bool>);
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
namespace detail {
|
||||||
|
template <
|
||||||
|
std::size_t S,
|
||||||
|
template <size_t,typename> class K,
|
||||||
|
std::size_t ...I,
|
||||||
|
typename = std::enable_if_t<
|
||||||
|
is_coord_v<K<S,bool>>,
|
||||||
|
void
|
||||||
|
>
|
||||||
|
>
|
||||||
|
constexpr bool
|
||||||
|
all (const K<S,bool> k, std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return (k[I] && ...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
/// returns true if all elements are true.
|
||||||
|
///
|
||||||
|
/// this function must be suitable for use in static_assert, so it must be
|
||||||
|
/// constexpr.
|
||||||
|
///
|
||||||
|
/// we would ideally use std::all_of, but it is not constexpr.
|
||||||
|
/// we would ideally use range-for, but cbegin is not constexpr.
|
||||||
|
/// so... moar templates.
|
||||||
template <
|
template <
|
||||||
size_t S,
|
size_t S,
|
||||||
template <size_t,typename> class K,
|
template <size_t,typename> class K,
|
||||||
typename = std::enable_if_t<
|
typename = std::enable_if_t<
|
||||||
is_coord_v<K<S,bool>>, void
|
is_coord_v<K<S,bool>>, void
|
||||||
>
|
>,
|
||||||
|
typename Indices = std::make_index_sequence<S>
|
||||||
>
|
>
|
||||||
constexpr
|
constexpr
|
||||||
bool
|
bool
|
||||||
all (const K<S,bool> k)
|
all (const K<S,bool> k)
|
||||||
{
|
{
|
||||||
return std::all_of (std::cbegin (k),
|
return detail::all (k, Indices {});
|
||||||
std::cend (k),
|
|
||||||
identity<bool>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +54,18 @@ main (void)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test expected outputs for various logical operations
|
||||||
|
{
|
||||||
|
constexpr util::point3i a { 0, -1, 2 };
|
||||||
|
constexpr util::point3i b { 0, 1, -2 };
|
||||||
|
constexpr util::point3i c { -9, -9, -9 };
|
||||||
|
|
||||||
|
tap.expect (!all (a <= b), "all, expected failure");
|
||||||
|
tap.expect ( all (a <= a), "all, expected success");
|
||||||
|
tap.expect (!any (a <= c), "any, expected failure");
|
||||||
|
tap.expect ( any (a <= b), "any, expected success");
|
||||||
|
};
|
||||||
|
|
||||||
// ensure the util::select function behaves as expected
|
// ensure the util::select function behaves as expected
|
||||||
{
|
{
|
||||||
const util::point3f a { -1, 2, 0 };
|
const util::point3f a { -1, 2, 0 };
|
||||||
|
Loading…
Reference in New Issue
Block a user