1 /*
2  *  Created by Jozef on 02/12/2018.
3  *  Copyright 2018 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 #ifndef TWOBLUECUBES_CATCH_META_HPP_INCLUDED
10 #define TWOBLUECUBES_CATCH_META_HPP_INCLUDED
11 
12 #include <type_traits>
13 
14 namespace Catch {
15     template<typename T>
16     struct always_false : std::false_type {};
17 
18     template <typename> struct true_given : std::true_type {};
19     struct is_callable_tester {
20         template <typename Fun, typename... Args>
21         true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
22         template <typename...>
23         std::false_type static test(...);
24     };
25 
26     template <typename T>
27     struct is_callable;
28 
29     template <typename Fun, typename... Args>
30     struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};
31 
32 
33 #if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703
34     // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is
35     // replaced with std::invoke_result here.
36     template <typename Func, typename... U>
37     using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;
38 #else
39     // Keep ::type here because we still support C++11
40     template <typename Func, typename... U>
41     using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;
42 #endif
43 
44 } // namespace Catch
45 
46 namespace mpl_{
47     struct na;
48 }
49 
50 #endif // TWOBLUECUBES_CATCH_META_HPP_INCLUDED
51