diff options
Diffstat (limited to 'src/boost/libs/callable_traits/test/is_invocable.cpp')
-rw-r--r-- | src/boost/libs/callable_traits/test/is_invocable.cpp | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/src/boost/libs/callable_traits/test/is_invocable.cpp b/src/boost/libs/callable_traits/test/is_invocable.cpp new file mode 100644 index 00000000..b9fa0ea4 --- /dev/null +++ b/src/boost/libs/callable_traits/test/is_invocable.cpp @@ -0,0 +1,381 @@ +/* +Copyright Barrett Adair 2016-2017 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) +*/ + +#include <type_traits> +#include <functional> +#include <utility> +#include <boost/callable_traits/is_invocable.hpp> +#include "test.hpp" + +#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2 +//gcc < 4.9 doesn't like the invoke_case pattern used here +int main(){} +#else + +template<typename T> +struct tag { + using type = T; +}; + +template<bool Expect, typename... Args> +struct invoke_case { + template<typename Callable> + void operator()(tag<Callable>) const { + +// when available, test parity with std implementation (c++2a breaks our expectations but we still match std impl) +#if defined(__cpp_lib_is_invocable) || __cplusplus >= 201707L + CT_ASSERT((std::is_invocable<Callable, Args...>() == boost::callable_traits::is_invocable<Callable, Args...>())); +#else + CT_ASSERT((Expect == boost::callable_traits::is_invocable<Callable, Args...>())); +#endif + + } +}; + +template<typename Callable, typename... InvokeCases> +void run_tests() { + using ignored = int[]; + ignored x {(InvokeCases{}(tag<Callable>{}),0)..., 0}; + (void)x; +} + +struct foo {}; + +int main() { + + run_tests<void(foo::*)() + ,invoke_case<true, foo> + ,invoke_case<true, foo*> + ,invoke_case<true, foo&> + ,invoke_case<true, foo&&> + ,invoke_case<true, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + run_tests<void(foo::*)() LREF + ,invoke_case<false, foo> + ,invoke_case<true, foo*> + ,invoke_case<true, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<true, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + run_tests<void(foo::*)() RREF + ,invoke_case<true, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<true, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + run_tests<void(foo::*)() const + ,invoke_case<true, foo> + ,invoke_case<true, foo*> + ,invoke_case<true, foo&> + ,invoke_case<true, foo&&> + ,invoke_case<true, std::reference_wrapper<foo>> + ,invoke_case<true, foo const> + ,invoke_case<true, foo const*> + ,invoke_case<true, foo const&> + ,invoke_case<true, foo const&&> + ,invoke_case<true, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + +// MSVC doesn't handle cv + ref qualifiers in expression sfinae correctly +#ifndef BOOST_CLBL_TRTS_MSVC + + run_tests<void(foo::*)() const LREF + ,invoke_case<false, foo> + ,invoke_case<true, foo*> + ,invoke_case<true, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<true, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<true, foo const*> + ,invoke_case<true, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<true, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + run_tests<void(foo::*)() const RREF + ,invoke_case<true, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<true, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<true, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<true, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + +#endif // #ifndef BOOST_CLBL_TRTS_MSVC + + run_tests<int + ,invoke_case<false, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + auto f = [](int){}; + + run_tests<decltype(f) + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(f)& + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(f)) + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(f))& + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(f))&& + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(f)) const & + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(f)) const && + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(f)&& + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(f) const & + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(f) const && + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + auto g = [](){}; + + run_tests<decltype(g) + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(g)& + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(g)) + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(g))& + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(g))&& + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(g)) const & + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(std::ref(g)) const && + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(g)&& + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(g) const & + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<decltype(g) const && + ,invoke_case<true> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + +// libc++ requires constructible types be passed to std::is_invocable +#ifndef _LIBCPP_VERSION + + run_tests<void(int) + ,invoke_case<true, int> + ,invoke_case<true, char> + ,invoke_case<false, void*> + >(); + + run_tests<void(int) const + ,invoke_case<false, int> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<void() + ,invoke_case<false, int> + ,invoke_case<false, char> + ,invoke_case<false, void*> + >(); + + run_tests<void + ,invoke_case<false, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); +#endif + + run_tests<int + ,invoke_case<false, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); + + run_tests<void* + ,invoke_case<false, foo> + ,invoke_case<false, foo*> + ,invoke_case<false, foo&> + ,invoke_case<false, foo&&> + ,invoke_case<false, std::reference_wrapper<foo>> + ,invoke_case<false, foo const> + ,invoke_case<false, foo const*> + ,invoke_case<false, foo const&> + ,invoke_case<false, foo const&&> + ,invoke_case<false, std::reference_wrapper<foo const>> + ,invoke_case<false, foo, int> + ,invoke_case<false, foo*, int> + ,invoke_case<false, foo&, int> + ,invoke_case<false, foo&&, int> + ,invoke_case<false, std::reference_wrapper<foo>, int> + >(); +} + +#endif //#ifdef BOOST_CLBL_TRTS_GCC_OLDER_THAN_4_9_2 |