Skip to content

Commit

Permalink
Merge pull request #9 from braxtons12/improve_algorithms
Browse files Browse the repository at this point in the history
Improve mpl::List::find_if implementation
  • Loading branch information
braxtons12 authored Mar 5, 2024
2 parents aee6119 + 8b9792c commit 2ce1f9c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 19 deletions.
40 changes: 22 additions & 18 deletions include/hyperion/mpl/list.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/// @file list.h
/// @author Braxton Salyer <braxtonsalyer@gmail.com>
/// @brief Meta-programming facilities for working with a list of types or values
/// @version 0.6
/// @date 2024-03-04
/// @version 0.7
/// @date 2024-03-05
///
/// MIT License
/// @copyright Copyright (c) 2024 Braxton Salyer <braxtonsalyer@gmail.com>
Expand Down Expand Up @@ -555,24 +555,28 @@ namespace hyperion::mpl {
/// `sizeof...(TTypes)`
///
/// @param predicate the predicate to satisfy
/// @param index The next index to check
/// @return The index of the first element to satisfy `predicate`, or if no element
/// satisfies `predicate`, `Value<sizeof...(TTypes)>`
template<typename TPredicate>
[[nodiscard]] static constexpr auto
find_if_impl([[maybe_unused]] TPredicate&& predicate, // NOLINT(*-missing-std-forward))
[[maybe_unused]] MetaValue auto index) noexcept
requires(decltype(index)::value <= sizeof...(TTypes))
{
if constexpr(detail::at<as_meta<TTypes>...>(index).satisfies(TPredicate{})) {
return index;
}
else if constexpr(decltype(index){} + 1_value < sizeof...(TTypes)) {
return find_if_impl(std::forward<TPredicate>(predicate), index + 1_value);
}
else {
return Value<sizeof...(TTypes), usize>{};
}
find_if_impl([[maybe_unused]] TPredicate&& predicate) // NOLINT(*-missing-std-forward))
noexcept {
constexpr auto values = []<auto... Indices>(std::index_sequence<Indices...>) {
constexpr auto _at = [](MetaValue auto index) noexcept {
return detail::at<as_meta<TTypes>...>(index);
};
return std::array{
static_cast<bool>(_at(Value<Indices>{}).satisfies(TPredicate{}))...};
}(std::make_index_sequence<sizeof...(TTypes)>{});
constexpr auto first = [values]() {
for(auto i = 0_usize; i < values.size(); ++i) {
if(values[i]) {
return i;
}
}
return values.size();
}();
return Value<static_cast<usize>(first), usize>{};
}

public:
Expand Down Expand Up @@ -616,7 +620,7 @@ namespace hyperion::mpl {
requires(MetaPredicateOf<TPredicate, as_meta<TTypes>> && ...)
|| requires { (as_meta<TTypes>{}.satisfies(TPredicate{}), ...); }
[[nodiscard]] constexpr auto find_if(TPredicate&& predicate) const noexcept {
auto result = find_if_impl(std::forward<TPredicate>(predicate), 0_value);
auto result = find_if_impl(std::forward<TPredicate>(predicate));
if constexpr(decltype(result){} == Value<sizeof...(TTypes), usize>{}) {
return decltype_<not_found_tag>();
}
Expand Down Expand Up @@ -896,7 +900,7 @@ namespace hyperion::mpl {
requires(MetaPredicateOf<TPredicate, as_meta<TTypes>> && ...)
|| requires { (as_meta<TTypes>{}.satisfies(TPredicate{}), ...); }
[[nodiscard]] constexpr auto index_if(TPredicate&& predicate) const noexcept {
return find_if_impl(std::forward<TPredicate>(predicate), 0_value);
return find_if_impl(std::forward<TPredicate>(predicate));
}

/// @brief Returns the index of the first element of this `List`
Expand Down
2 changes: 1 addition & 1 deletion xmake.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---@diagnostic disable: undefined-global,undefined-field
set_project("hyperion_mpl")
set_version("0.6.0")
set_version("0.7.0")

set_xmakever("2.8.7")

Expand Down

0 comments on commit 2ce1f9c

Please sign in to comment.