1 //===- TypeTraitsTest.cpp - type_traits unit tests ------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/STLExtras.h" 10 #include "gtest/gtest.h" 11 12 using namespace llvm; 13 14 //===----------------------------------------------------------------------===// 15 // function_traits 16 //===----------------------------------------------------------------------===// 17 18 namespace { 19 /// Check a callable type of the form `bool(const int &)`. 20 template <typename CallableT> struct CheckFunctionTraits { 21 static_assert( 22 std::is_same<typename function_traits<CallableT>::result_t, bool>::value, 23 "expected result_t to be `bool`"); 24 static_assert( 25 std::is_same<typename function_traits<CallableT>::template arg_t<0>, 26 const int &>::value, 27 "expected arg_t<0> to be `const int &`"); 28 static_assert(function_traits<CallableT>::num_args == 1, 29 "expected num_args to be 1"); 30 }; 31 32 /// Test function pointers. 33 using FuncType = bool (*)(const int &); 34 struct CheckFunctionPointer : CheckFunctionTraits<FuncType> {}; 35 36 static bool func(const int &v); 37 struct CheckFunctionPointer2 : CheckFunctionTraits<decltype(&func)> {}; 38 39 /// Test method pointers. 40 struct Foo { 41 bool func(const int &v); 42 }; 43 struct CheckMethodPointer : CheckFunctionTraits<decltype(&Foo::func)> {}; 44 45 /// Test lambda references. 46 auto lambdaFunc = [](const int &v) -> bool { return true; }; 47 struct CheckLambda : CheckFunctionTraits<decltype(lambdaFunc)> {}; 48 49 } // end anonymous namespace 50 51 //===----------------------------------------------------------------------===// 52 // is_detected 53 //===----------------------------------------------------------------------===// 54 55 namespace { 56 struct HasFooMethod { 57 void foo() {} 58 }; 59 struct NoFooMethod {}; 60 61 template <class T> using has_foo_method_t = decltype(std::declval<T &>().foo()); 62 63 static_assert(is_detected<has_foo_method_t, HasFooMethod>::value, 64 "expected foo method to be detected"); 65 static_assert(!is_detected<has_foo_method_t, NoFooMethod>::value, 66 "expected no foo method to be detected"); 67 } // end anonymous namespace 68 69 //===----------------------------------------------------------------------===// 70 // is_invocable 71 //===----------------------------------------------------------------------===// 72 73 static void invocable_fn(int) {} 74 75 static_assert(is_invocable<decltype(invocable_fn), int>::value, 76 "expected function to be invocable"); 77 static_assert(!is_invocable<decltype(invocable_fn), void *>::value, 78 "expected function not to be invocable"); 79 static_assert(!is_invocable<decltype(invocable_fn), int, int>::value, 80 "expected function not to be invocable"); 81