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
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
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 <
|
||||
size_t S,
|
||||
template <size_t,typename> class K,
|
||||
typename = std::enable_if_t<
|
||||
is_coord_v<K<S,bool>>, void
|
||||
>
|
||||
>,
|
||||
typename Indices = std::make_index_sequence<S>
|
||||
>
|
||||
constexpr
|
||||
bool
|
||||
any (const K<S,bool> k)
|
||||
{
|
||||
return std::any_of (std::cbegin (k),
|
||||
std::cend (k),
|
||||
identity<bool>);
|
||||
return detail::any (k, Indices{});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
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 <
|
||||
size_t S,
|
||||
template <size_t,typename> class K,
|
||||
typename = std::enable_if_t<
|
||||
is_coord_v<K<S,bool>>, void
|
||||
>
|
||||
>,
|
||||
typename Indices = std::make_index_sequence<S>
|
||||
>
|
||||
constexpr
|
||||
bool
|
||||
all (const K<S,bool> k)
|
||||
{
|
||||
return std::all_of (std::cbegin (k),
|
||||
std::cend (k),
|
||||
identity<bool>);
|
||||
return detail::all (k, Indices {});
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
const util::point3f a { -1, 2, 0 };
|
||||
|
Loading…
Reference in New Issue
Block a user