mirror of
https://github.com/BlackMATov/invoke.hpp.git
synced 2025-12-15 06:25:25 +07:00
@@ -1,4 +1,4 @@
|
|||||||
# 3.8 version is required for `cxx_std_14`
|
# 3.8 version is required for `cxx_std_11`
|
||||||
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
|
||||||
|
|
||||||
if(NOT DEFINED PROJECT_NAME)
|
if(NOT DEFINED PROJECT_NAME)
|
||||||
@@ -8,7 +8,7 @@ endif()
|
|||||||
project(invoke.hpp)
|
project(invoke.hpp)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} INTERFACE)
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
|
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_11)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
target_include_directories(${PROJECT_NAME} INTERFACE headers)
|
||||||
|
|
||||||
if(BUILD_AS_STANDALONE)
|
if(BUILD_AS_STANDALONE)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# invoke.hpp
|
# invoke.hpp
|
||||||
|
|
||||||
> std::invoke/std::apply analogs for C++14
|
> std::invoke/std::apply analogs for C++11/14
|
||||||
|
|
||||||
[![travis][badge.travis]][travis]
|
[![travis][badge.travis]][travis]
|
||||||
[![appveyor][badge.appveyor]][appveyor]
|
[![appveyor][badge.appveyor]][appveyor]
|
||||||
@@ -12,14 +12,14 @@
|
|||||||
[badge.travis]: https://img.shields.io/travis/BlackMATov/invoke.hpp/master.svg?logo=travis
|
[badge.travis]: https://img.shields.io/travis/BlackMATov/invoke.hpp/master.svg?logo=travis
|
||||||
[badge.appveyor]: https://img.shields.io/appveyor/ci/BlackMATov/invoke-hpp/master.svg?logo=appveyor
|
[badge.appveyor]: https://img.shields.io/appveyor/ci/BlackMATov/invoke-hpp/master.svg?logo=appveyor
|
||||||
[badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/invoke.hpp/master.svg?logo=codecov
|
[badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/invoke.hpp/master.svg?logo=codecov
|
||||||
[badge.language]: https://img.shields.io/badge/language-C%2B%2B14-red.svg
|
[badge.language]: https://img.shields.io/badge/language-C%2B%2B11-red.svg
|
||||||
[badge.license]: https://img.shields.io/badge/license-MIT-blue.svg
|
[badge.license]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||||
[badge.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C
|
[badge.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C
|
||||||
|
|
||||||
[travis]: https://travis-ci.org/BlackMATov/invoke.hpp
|
[travis]: https://travis-ci.org/BlackMATov/invoke.hpp
|
||||||
[appveyor]: https://ci.appveyor.com/project/BlackMATov/invoke-hpp
|
[appveyor]: https://ci.appveyor.com/project/BlackMATov/invoke-hpp
|
||||||
[codecov]: https://codecov.io/gh/BlackMATov/invoke.hpp
|
[codecov]: https://codecov.io/gh/BlackMATov/invoke.hpp
|
||||||
[language]: https://en.wikipedia.org/wiki/C%2B%2B14
|
[language]: https://en.wikipedia.org/wiki/C%2B%2B11
|
||||||
[license]: https://en.wikipedia.org/wiki/MIT_License
|
[license]: https://en.wikipedia.org/wiki/MIT_License
|
||||||
[paypal]: https://www.paypal.me/matov
|
[paypal]: https://www.paypal.me/matov
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#define INVOKE_HPP_NOEXCEPT_RETURN(...) \
|
|
||||||
noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
|
|
||||||
|
|
||||||
#define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \
|
#define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \
|
||||||
noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; }
|
noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; }
|
||||||
|
|
||||||
@@ -35,6 +32,42 @@ namespace invoke_hpp
|
|||||||
using void_t = typename impl::make_void<Args...>::type;
|
using void_t = typename impl::make_void<Args...>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// integer_sequence
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace invoke_hpp
|
||||||
|
{
|
||||||
|
template < typename T, T... Ints >
|
||||||
|
struct integer_sequence {
|
||||||
|
using value_type = T;
|
||||||
|
static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template < std::size_t... Ints >
|
||||||
|
using index_sequence = integer_sequence<std::size_t, Ints...>;
|
||||||
|
|
||||||
|
namespace impl
|
||||||
|
{
|
||||||
|
template < typename T, std::size_t N, T... Ints >
|
||||||
|
struct make_integer_sequence_impl
|
||||||
|
: make_integer_sequence_impl<T, N - 1, N - 1, Ints...> {};
|
||||||
|
|
||||||
|
template < typename T, T... Ints >
|
||||||
|
struct make_integer_sequence_impl<T, 0, Ints...>
|
||||||
|
: integer_sequence<T, Ints...> {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename T, std::size_t N >
|
||||||
|
using make_integer_sequence = impl::make_integer_sequence_impl<T, N>;
|
||||||
|
|
||||||
|
template < std::size_t N >
|
||||||
|
using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||||
|
|
||||||
|
template < typename... Ts >
|
||||||
|
using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// is_reference_wrapper
|
// is_reference_wrapper
|
||||||
//
|
//
|
||||||
@@ -54,7 +87,7 @@ namespace invoke_hpp
|
|||||||
|
|
||||||
template < typename T >
|
template < typename T >
|
||||||
struct is_reference_wrapper
|
struct is_reference_wrapper
|
||||||
: impl::is_reference_wrapper_impl<std::remove_cv_t<T>> {};
|
: impl::is_reference_wrapper_impl<typename std::remove_cv<T>::type> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -72,7 +105,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename Derived,
|
typename Base, typename F, typename Derived,
|
||||||
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
|
typename std::enable_if<std::is_base_of<Base, typename std::decay<Derived>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref)
|
constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -81,7 +114,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename RefWrap,
|
typename Base, typename F, typename RefWrap,
|
||||||
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
|
typename std::enable_if<is_reference_wrapper<typename std::decay<RefWrap>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref)
|
constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -90,10 +123,10 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename Pointer,
|
typename Base, typename F, typename Pointer,
|
||||||
typename std::enable_if_t<
|
typename std::enable_if<
|
||||||
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
|
!std::is_base_of<Base, typename std::decay<Pointer>::type>::value &&
|
||||||
!is_reference_wrapper<std::decay_t<Pointer>>::value
|
!is_reference_wrapper<typename std::decay<Pointer>::type>::value
|
||||||
, int> = 0
|
, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr)
|
constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -106,7 +139,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename Derived, typename... Args,
|
typename Base, typename F, typename Derived, typename... Args,
|
||||||
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
|
typename std::enable_if<std::is_base_of<Base, typename std::decay<Derived>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args)
|
constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -115,7 +148,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename RefWrap, typename... Args,
|
typename Base, typename F, typename RefWrap, typename... Args,
|
||||||
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
|
typename std::enable_if<is_reference_wrapper<typename std::decay<RefWrap>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args)
|
constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -124,10 +157,10 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename Base, typename F, typename Pointer, typename... Args,
|
typename Base, typename F, typename Pointer, typename... Args,
|
||||||
typename std::enable_if_t<
|
typename std::enable_if<
|
||||||
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
|
!std::is_base_of<Base, typename std::decay<Pointer>::type>::value &&
|
||||||
!is_reference_wrapper<std::decay_t<Pointer>>::value
|
!is_reference_wrapper<typename std::decay<Pointer>::type>::value
|
||||||
, int> = 0
|
, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args)
|
constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -137,7 +170,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename F, typename... Args,
|
typename F, typename... Args,
|
||||||
typename std::enable_if_t<!std::is_member_pointer<std::decay_t<F>>::value, int> = 0
|
typename std::enable_if<!std::is_member_pointer<typename std::decay<F>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke(F&& f, Args&&... args)
|
constexpr auto invoke(F&& f, Args&&... args)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -146,7 +179,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename F, typename T,
|
typename F, typename T,
|
||||||
typename std::enable_if_t<std::is_member_object_pointer<std::decay_t<F>>::value, int> = 0
|
typename std::enable_if<std::is_member_object_pointer<typename std::decay<F>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke(F&& f, T&& t)
|
constexpr auto invoke(F&& f, T&& t)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -155,7 +188,7 @@ namespace invoke_hpp
|
|||||||
template
|
template
|
||||||
<
|
<
|
||||||
typename F, typename... Args,
|
typename F, typename... Args,
|
||||||
typename std::enable_if_t<std::is_member_function_pointer<std::decay_t<F>>::value, int> = 0
|
typename std::enable_if<std::is_member_function_pointer<typename std::decay<F>::type>::value, int>::type = 0
|
||||||
>
|
>
|
||||||
constexpr auto invoke(F&& f, Args&&... args)
|
constexpr auto invoke(F&& f, Args&&... args)
|
||||||
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
@@ -205,10 +238,10 @@ namespace invoke_hpp
|
|||||||
|
|
||||||
template < typename R, typename F, typename... Args >
|
template < typename R, typename F, typename... Args >
|
||||||
struct is_invocable_r_impl<void_t<is_invocable_r_impl_tag, invoke_result_t<F, Args...>>, R, F, Args...>
|
struct is_invocable_r_impl<void_t<is_invocable_r_impl_tag, invoke_result_t<F, Args...>>, R, F, Args...>
|
||||||
: std::conditional_t<
|
: std::conditional<
|
||||||
std::is_void<R>::value,
|
std::is_void<R>::value,
|
||||||
std::true_type,
|
std::true_type,
|
||||||
std::is_convertible<invoke_result_t<F, Args...>, R>> {};
|
std::is_convertible<invoke_result_t<F, Args...>, R>>::type {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename R, typename F, typename... Args >
|
template < typename R, typename F, typename... Args >
|
||||||
@@ -228,21 +261,20 @@ namespace invoke_hpp
|
|||||||
namespace impl
|
namespace impl
|
||||||
{
|
{
|
||||||
template < typename F, typename Tuple, std::size_t... I >
|
template < typename F, typename Tuple, std::size_t... I >
|
||||||
constexpr decltype(auto) apply_impl(F&& f, Tuple&& args, std::index_sequence<I...>)
|
constexpr auto apply_impl(F&& f, Tuple&& args, index_sequence<I...>)
|
||||||
INVOKE_HPP_NOEXCEPT_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
invoke_hpp::invoke(
|
invoke_hpp::invoke(
|
||||||
std::forward<F>(f),
|
std::forward<F>(f),
|
||||||
std::get<I>(std::forward<Tuple>(args))...))
|
std::get<I>(std::forward<Tuple>(args))...))
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename F, typename Tuple >
|
template < typename F, typename Tuple >
|
||||||
constexpr decltype(auto) apply(F&& f, Tuple&& args)
|
constexpr auto apply(F&& f, Tuple&& args)
|
||||||
INVOKE_HPP_NOEXCEPT_RETURN(
|
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
|
||||||
impl::apply_impl(
|
impl::apply_impl(
|
||||||
std::forward<F>(f),
|
std::forward<F>(f),
|
||||||
std::forward<Tuple>(args),
|
std::forward<Tuple>(args),
|
||||||
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>()))
|
make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef INVOKE_HPP_NOEXCEPT_RETURN
|
|
||||||
#undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN
|
#undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN
|
||||||
|
|||||||
Reference in New Issue
Block a user