|
11 | 11 |
|
12 | 12 | namespace eve
|
13 | 13 | {
|
14 |
| -//TODO DOC |
15 |
| -//================================================================================================ |
16 |
| -//! @addtogroup core_reduction |
17 |
| -//! @{ |
18 |
| -//! @var first_true |
19 |
| -//! @brief A function to find a first true value, if there is one. |
20 |
| -//! |
21 |
| -//! @code |
22 |
| -//! #include <eve/module/core.hpp> |
23 |
| -//! @endcode |
24 |
| -//! |
25 |
| -//! ## Should you check for any? |
26 |
| -//! |
27 |
| -//! The function is considering the case when nothing is set to be likely, |
28 |
| -//! checking for eve::any before hand is not going to be helpful. |
29 |
| -//! At the moment there isn't a function that would do it otherwise. |
30 |
| -//! |
31 |
| -//! ## What if I know there is a match? |
32 |
| -//! We would recommend `*eve::first_true(m)` - this is likely to trigger |
33 |
| -//! compiler optimizations, based on it being UB otherwise. |
34 |
| -//! |
35 |
| -//! @groupheader{Callable Signatures} |
36 |
| -//! |
37 |
| -//! @code |
38 |
| -//! template <logical_simd_value L> |
39 |
| -//! std::optional<std::ptrdiff_t> first_true(L m); // (1) |
40 |
| -//! |
41 |
| -//! template <logical_simd_value L> |
42 |
| -//! std::optional<std::ptrdiff_t> first_true(top_bits<L> m); // (2) |
43 |
| -//! |
44 |
| -//! template <relative_conditional_expr C, logical_simd_value L> |
45 |
| -//! std::optional<std::ptrdiff_t> first_true[C ignore](L m); // (3) |
46 |
| -//! |
47 |
| -//! std::optional<std::ptrdiff_t> first_true(bool m); // (4) |
48 |
| -//! @endcode |
49 |
| -//! |
50 |
| -//! **Parameters** |
51 |
| -//! |
52 |
| -//! * m - logical_value or top_bits where to find first true value |
53 |
| -//! * ignore - ignored elements are considered false. Only supported for |
54 |
| -//! `logical_simd_value` |
55 |
| -//! |
56 |
| -//! **Return value** |
57 |
| -//! |
58 |
| -//! Returns `std::nullopt` if eve::none(m). |
59 |
| -//! Otherwise returns 0 based index. |
60 |
| -//! |
61 |
| -//! @groupheader{Example} |
62 |
| -//! |
63 |
| -//! @godbolt{doc/core/first_true.cpp} |
64 |
| -//================================================================================================ |
65 |
| -EVE_MAKE_CALLABLE(first_true_, first_true); |
66 |
| -//================================================================================================ |
67 |
| -//! @} |
68 |
| -//================================================================================================ |
| 14 | + template<typename Options> |
| 15 | + struct first_true_t : conditional_callable<first_true_t, Options> |
| 16 | + { |
| 17 | + template<relaxed_logical_value T> |
| 18 | + EVE_FORCEINLINE std::optional<std::ptrdiff_t> operator()(T v) const noexcept |
| 19 | + { |
| 20 | + static_assert(detail::validate_mask_for<decltype(this->options()), T>(), |
| 21 | + "[eve::first_true] - Cannot use a relative conditional expression or a simd value to mask a scalar value"); |
| 22 | + |
| 23 | + return EVE_DISPATCH_CALL(v); |
| 24 | + } |
| 25 | + |
| 26 | + template<logical_simd_value T> |
| 27 | + EVE_FORCEINLINE std::optional<std::ptrdiff_t> operator()(top_bits<T> v) const noexcept |
| 28 | + { |
| 29 | + return EVE_DISPATCH_CALL(v); |
| 30 | + } |
| 31 | + |
| 32 | + EVE_CALLABLE_OBJECT(first_true_t, first_true_); |
| 33 | + }; |
| 34 | + |
| 35 | + //================================================================================================ |
| 36 | + //! @addtogroup core_reduction |
| 37 | + //! @{ |
| 38 | + //! @var first_true |
| 39 | + //! @brief Returns the index of the first element in the input which evaluates to `true`, if there is one. |
| 40 | + //! |
| 41 | + //! @code |
| 42 | + //! #include <eve/module/core.hpp> |
| 43 | + //! @endcode |
| 44 | + //! |
| 45 | + //! @groupheader{Callable Signatures} |
| 46 | + //! |
| 47 | + //! @code |
| 48 | + //! template <relaxed_logical_value L> |
| 49 | + //! std::optional<std::ptrdiff_t> first_true(L m) noexcept; // 1 |
| 50 | + //! |
| 51 | + //! template <logical_simd_value L> |
| 52 | + //! std::optional<std::ptrdiff_t> first_true(top_bits<L> m) noexcept; // 1 |
| 53 | + //! |
| 54 | + //! // lane masking |
| 55 | + //! std::optional<std::ptrdiff_t> first_true[conditional_expr auto c](/* any of the above */) noexcept; // 2 |
| 56 | + //! std::optional<std::ptrdiff_t> first_true[logical_value auto c](/* any of the above */) noexcept; // 2 |
| 57 | + //! |
| 58 | + //! @endcode |
| 59 | + //! |
| 60 | + //! **Parameters** |
| 61 | + //! |
| 62 | + //! * m - logical_value or top_bits where to find first true value |
| 63 | + //! |
| 64 | + //! **Return value** |
| 65 | + //! |
| 66 | + //! 1. An `std::optional` containing the index of the first element which evaluates to `true`, |
| 67 | + //! `std::nullopt` if there are none. |
| 68 | + //! 2. Same as 1. but masked elements are ignored during the search. |
| 69 | + //! |
| 70 | + //! ## Should you check for any? |
| 71 | + //! |
| 72 | + //! The function is considering the case when nothing is set to be likely, |
| 73 | + //! checking for eve::any before hand is not going to be helpful. |
| 74 | + //! At the moment there isn't a function that would do it otherwise. |
| 75 | + //! |
| 76 | + //! ## What if I know there is a match? |
| 77 | + //! We would recommend `*eve::first_true(m)` - this is likely to trigger |
| 78 | + //! compiler optimizations, based on it being UB otherwise. |
| 79 | + //! |
| 80 | + //! @groupheader{Example} |
| 81 | + //! @godbolt{doc/core/first_true.cpp} |
| 82 | + //================================================================================================ |
| 83 | + inline constexpr auto first_true = functor<first_true_t>; |
| 84 | + //================================================================================================ |
| 85 | + //! @} |
| 86 | + //================================================================================================ |
69 | 87 | }
|
70 | 88 |
|
71 |
| -#include <eve/arch.hpp> |
72 | 89 | #include <eve/module/core/regular/impl/first_true.hpp>
|
73 | 90 |
|
74 | 91 | #if defined(EVE_INCLUDE_ARM_NEON_HEADER)
|
75 | 92 | # include <eve/module/core/regular/impl/simd/arm/neon/first_true.hpp>
|
76 | 93 | #endif
|
77 | 94 |
|
78 |
| - |
79 | 95 | #if defined(EVE_INCLUDE_ARM_SVE_HEADER)
|
80 | 96 | # include <eve/module/core/regular/impl/simd/arm/sve/first_true.hpp>
|
81 | 97 | #endif
|
0 commit comments