diff --git a/CMakeLists.txt b/CMakeLists.txt index 5162735..328bcf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) if(NOT DEFINED PROJECT_NAME) @@ -8,7 +8,7 @@ endif() project(invoke.hpp) 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) if(BUILD_AS_STANDALONE) diff --git a/README.md b/README.md index 94a7c03..ee5c829 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # invoke.hpp -> std::invoke/std::apply analogs for C++14 +> std::invoke/std::apply analogs for C++11/14 [![travis][badge.travis]][travis] [![appveyor][badge.appveyor]][appveyor] @@ -12,14 +12,14 @@ [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.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.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C [travis]: https://travis-ci.org/BlackMATov/invoke.hpp [appveyor]: https://ci.appveyor.com/project/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 [paypal]: https://www.paypal.me/matov diff --git a/headers/invoke.hpp/invoke.hpp b/headers/invoke.hpp/invoke.hpp index 8dfb861..5bd950e 100644 --- a/headers/invoke.hpp/invoke.hpp +++ b/headers/invoke.hpp/invoke.hpp @@ -11,9 +11,6 @@ #include #include -#define INVOKE_HPP_NOEXCEPT_RETURN(...) \ - noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } - #define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \ noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; } @@ -35,6 +32,42 @@ namespace invoke_hpp using void_t = typename impl::make_void::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; + + namespace impl + { + template < typename T, std::size_t N, T... Ints > + struct make_integer_sequence_impl + : make_integer_sequence_impl {}; + + template < typename T, T... Ints > + struct make_integer_sequence_impl + : integer_sequence {}; + } + + template < typename T, std::size_t N > + using make_integer_sequence = impl::make_integer_sequence_impl; + + template < std::size_t N > + using make_index_sequence = make_integer_sequence; + + template < typename... Ts > + using index_sequence_for = make_index_sequence; +} + // // is_reference_wrapper // @@ -54,7 +87,7 @@ namespace invoke_hpp template < typename T > struct is_reference_wrapper - : impl::is_reference_wrapper_impl> {}; + : impl::is_reference_wrapper_impl::type> {}; } // @@ -72,7 +105,7 @@ namespace invoke_hpp template < typename Base, typename F, typename Derived, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -81,7 +114,7 @@ namespace invoke_hpp template < typename Base, typename F, typename RefWrap, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -90,10 +123,10 @@ namespace invoke_hpp template < typename Base, typename F, typename Pointer, - typename std::enable_if_t< - !std::is_base_of>::value && - !is_reference_wrapper>::value - , int> = 0 + typename std::enable_if< + !std::is_base_of::type>::value && + !is_reference_wrapper::type>::value + , int>::type = 0 > constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -106,7 +139,7 @@ namespace invoke_hpp template < typename Base, typename F, typename Derived, typename... Args, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -115,7 +148,7 @@ namespace invoke_hpp template < typename Base, typename F, typename RefWrap, typename... Args, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -124,10 +157,10 @@ namespace invoke_hpp template < typename Base, typename F, typename Pointer, typename... Args, - typename std::enable_if_t< - !std::is_base_of>::value && - !is_reference_wrapper>::value - , int> = 0 + typename std::enable_if< + !std::is_base_of::type>::value && + !is_reference_wrapper::type>::value + , int>::type = 0 > constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -137,7 +170,7 @@ namespace invoke_hpp template < typename F, typename... Args, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke(F&& f, Args&&... args) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -146,7 +179,7 @@ namespace invoke_hpp template < typename F, typename T, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke(F&& f, T&& t) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -155,7 +188,7 @@ namespace invoke_hpp template < typename F, typename... Args, - typename std::enable_if_t>::value, int> = 0 + typename std::enable_if::type>::value, int>::type = 0 > constexpr auto invoke(F&& f, Args&&... args) INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( @@ -205,10 +238,10 @@ namespace invoke_hpp template < typename R, typename F, typename... Args > struct is_invocable_r_impl>, R, F, Args...> - : std::conditional_t< + : std::conditional< std::is_void::value, std::true_type, - std::is_convertible, R>> {}; + std::is_convertible, R>>::type {}; } template < typename R, typename F, typename... Args > @@ -228,21 +261,20 @@ namespace invoke_hpp namespace impl { template < typename F, typename Tuple, std::size_t... I > - constexpr decltype(auto) apply_impl(F&& f, Tuple&& args, std::index_sequence) - INVOKE_HPP_NOEXCEPT_RETURN( + constexpr auto apply_impl(F&& f, Tuple&& args, index_sequence) + INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( invoke_hpp::invoke( std::forward(f), std::get(std::forward(args))...)) } template < typename F, typename Tuple > - constexpr decltype(auto) apply(F&& f, Tuple&& args) - INVOKE_HPP_NOEXCEPT_RETURN( + constexpr auto apply(F&& f, Tuple&& args) + INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN( impl::apply_impl( std::forward(f), std::forward(args), - std::make_index_sequence>::value>())) + make_index_sequence::type>::value>())) } -#undef INVOKE_HPP_NOEXCEPT_RETURN #undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN