summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/callable_traits/test/is_invocable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/callable_traits/test/is_invocable.cpp')
-rw-r--r--src/boost/libs/callable_traits/test/is_invocable.cpp381
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