commit 23281a48b3ddbf2f6971d0c1830375dea15e733e
parent 08e58cf4ec791a7f2f6423a7cadfacafd9529348
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date: Mon, 2 Dec 2019 19:20:08 +0000
is_invocable_r
Diffstat:
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/include/kfr/cometa.hpp b/include/kfr/cometa.hpp
@@ -573,7 +573,7 @@ struct concat_impl<T1, T2, T3, Ts...>
using type = typename concat_impl<typename concat_impl<T1, T2>::type, T3, Ts...>::type;
};
-template <typename Fn, typename Args, typename enable=void>
+template <typename Fn, typename Args, typename enable = void>
struct is_invocable_impl : std::false_type
{
};
@@ -584,6 +584,18 @@ struct is_invocable_impl<Fn, ctypes_t<Args...>, void_t<decltype(std::declval<Fn>
{
};
+template <typename Fn, typename Ret, typename Args, typename enable = void>
+struct is_invocable_r_impl : std::false_type
+{
+};
+
+template <typename Fn, typename Ret, typename... Args>
+struct is_invocable_r_impl<Fn, Ret, ctypes_t<Args...>,
+ void_t<decltype(std::declval<Fn>()(std::declval<Args>()...))>>
+{
+ static constexpr bool value = is_convertible<decltype(std::declval<Fn>()(std::declval<Args>()...)), Ret>;
+};
+
} // namespace details
template <typename T1, typename... Ts>
using concat_lists = typename details::concat_impl<decay<T1>, decay<Ts>...>::type;
@@ -595,11 +607,17 @@ constexpr inline concat_lists<T1, Ts...> cconcat(T1, Ts...)
}
#ifdef __cpp_lib_is_invocable
-template <typename T, typename... Args>
-constexpr inline bool is_invocable = std::is_invocable<T, Args...>::value;
+template <typename Fn, typename... Args>
+constexpr inline bool is_invocable = std::is_invocable<Fn, Args...>::value;
+
+template <typename Ret, typename Fn, typename... Args>
+constexpr inline bool is_invocable_r = std::is_invocable_r<Ret, Fn, Args...>::value;
#else
-template <typename T, typename... Args>
-constexpr inline bool is_invocable = details::is_invocable_impl<T, ctypes_t<Args...>>::value;
+template <typename Fn, typename... Args>
+constexpr inline bool is_invocable = details::is_invocable_impl<Fn, ctypes_t<Args...>>::value;
+
+template <typename Ret, typename Fn, typename... Args>
+constexpr inline bool is_invocable_r = details::is_invocable_r_impl<Ret, Fn, ctypes_t<Args...>>::value;
#endif
namespace details
diff --git a/include/kfr/cometa/function.hpp b/include/kfr/cometa/function.hpp
@@ -65,6 +65,8 @@ struct function_impl : public function_abstract<R, Args...>
{
inline static void* operator new(size_t size) noexcept { return aligned_allocate(size, alignof(Fn)); }
inline static void operator delete(void* ptr) noexcept { return aligned_deallocate(ptr); }
+
+#ifdef __cpp_aligned_new
inline static void* operator new(size_t size, std::align_val_t al) noexcept
{
return aligned_allocate(size, static_cast<size_t>(al));
@@ -73,6 +75,7 @@ struct function_impl : public function_abstract<R, Args...>
{
return aligned_deallocate(ptr);
}
+#endif
template <typename Fn_>
function_impl(Fn_ fn) : fn(std::forward<Fn_>(fn))
@@ -92,7 +95,7 @@ struct function<R(Args...)>
function(nullptr_t) noexcept {}
template <typename Fn,
- typename = enable_if<is_invocable<R, Fn, Args...> && !is_same<decay<Fn>, function>>>
+ typename = enable_if<is_invocable_r<R, Fn, Args...> && !is_same<decay<Fn>, function>>>
function(Fn fn) : impl(new details::function_impl<decay<Fn>, R, Args...>(std::move(fn)))
{
}
diff --git a/tests/generate_data.cpp b/tests/generate_data.cpp
@@ -86,6 +86,7 @@ int main()
{
using num = mpfr::number;
mpfr::scoped_precision prec(512);
+
generate_test(
cint<1>, "sin", [](const num& x) { return mpfr::sin(x); }, 0, M_PI * 2);
generate_test(