Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthapz committed Nov 1, 2024
2 parents 18f6189 + 73421dc commit b09dce0
Showing 1 changed file with 54 additions and 10 deletions.
64 changes: 54 additions & 10 deletions modules/stormkit/Core/Functional/Utils.mpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@ namespace stormkit { inline namespace core { namespace details {
export namespace stormkit { inline namespace core {
inline constexpr auto either = details::EitherFunc {};

template<auto Func, typename... Args>
[[nodiscard]] constexpr auto bindFront(Args&&... args) noexcept -> decltype(auto);

template<typename Func, typename... Args>
// requires(std::invocable<Func, Args...>)
[[nodiscard]] constexpr auto bindFront(Func&& func, Args&&... args) noexcept -> decltype(auto);

template<typename Func, typename... Args>
// requires(std::invocable<Func, Args...>)
[[nodiscard]] constexpr auto bindBack(Func&& func, Args&&... args) noexcept -> decltype(auto);

template<auto Func, typename... Args>
[[nodiscard]] constexpr auto bindBack(Args&&... args) noexcept -> decltype(auto);
}} // namespace stormkit::core

////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -69,30 +73,70 @@ namespace stormkit { inline namespace core {
}
} // namespace details

/////////////////////////////////////
/////////////////////////////////////
template<auto Func, typename... Args>
STORMKIT_FORCE_INLINE constexpr auto bindFront(Args&&... args) noexcept -> decltype(auto) {
return std::bind_front<Func>(std::forward<Args>(args)...);
}

/////////////////////////////////////
/////////////////////////////////////
template<typename Func, typename... Args>
// requires(std::invocable<Func, Args...>)
STORMKIT_FORCE_INLINE constexpr auto bindFront(Func&& func, Args&&... args) noexcept
-> decltype(auto) {
return std::bind_front(std::forward<Func>(func), std::forward<Args>(args)...);
}

/////////////////////////////////////
/////////////////////////////////////
template<auto Func, typename... Args>
STORMKIT_FORCE_INLINE constexpr auto bindBack(Args&&... args) noexcept -> decltype(auto) {
#if defined(__cpp_lib_bind_back) and __cpp_lib_bind_back >= 202202L
return std::bind_back<Func>(std::forward<Args>(args)...);
#else
if constexpr (IsPointer<Func> or std::is_member_pointer_v<Func>)
static_assert(Func != nullptr);
return
[... bound_args(std::forward<Args>(args))]<typename Self, typename... CallArgs>(
this Self&&,
CallArgs&&... call_args) noexcept(std::is_nothrow_invocable_v<Func,
CallArgs...,
meta::ForwardLike<
Self,
meta::DecayType<
Args>>...>)
-> decltype(auto) {
return std::invoke(Func,
std::forward<CallArgs>(call_args)...,
std::forward_like<Self>(bound_args)...);
};
#endif
}

/////////////////////////////////////
/////////////////////////////////////
template<typename Func, typename... Args>
// requires(std::invocable<Func, Args...>)
STORMKIT_FORCE_INLINE constexpr auto bindBack(Func&& func, Args&&... args) noexcept
-> decltype(auto) {
#if defined(__cpp_lib_bind_back) and __cpp_lib_bind_back >= 202202L
return std::bind_back(std::forward<Func>(func), std::forward<Args>(args)...);
#else
return [&]<typename... CallArgs>(CallArgs&&... call_args) noexcept(
std::is_nothrow_invocable_v<Func, CallArgs..., Args...>) -> decltype(auto) {
return std::invoke(std::forward<Func>(func),
std::forward<CallArgs>(call_args)...,
std::forward<Args>(args)...);
};
return
[func = std::forward<Func>(func),
... bound_args(std::forward<Args>(args))]<typename Self, typename... CallArgs>(
this Self&&,
CallArgs&&... call_args) noexcept(std::is_nothrow_invocable_v<Func,
CallArgs...,
meta::ForwardLike<
Self,
meta::DecayType<
Args>>...>)
-> decltype(auto) {
return std::invoke(func,
std::forward<CallArgs>(call_args)...,
std::forward_like<Self>(bound_args)...);
};
#endif
}
}} // namespace stormkit::core

0 comments on commit b09dce0

Please sign in to comment.