1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// type_traits
11
12// is_function
13
14#include <type_traits>
15#include <cstddef>        // for std::nullptr_t
16
17#include "test_macros.h"
18
19// NOTE: On Windows the function `test_is_function<void()>` and
20// `test_is_function<void() noexcept> has the same mangled despite being
21// a distinct instantiation. This causes Clang to emit an error. However
22// structs do not have this problem.
23
24template <class T>
25struct test_is_function {
26    static_assert( std::is_function<T>::value, "");
27    static_assert( std::is_function<const T>::value, "");
28    static_assert( std::is_function<volatile T>::value, "");
29    static_assert( std::is_function<const volatile T>::value, "");
30#if TEST_STD_VER > 14
31    static_assert( std::is_function_v<T>, "");
32    static_assert( std::is_function_v<const T>, "");
33    static_assert( std::is_function_v<volatile T>, "");
34    static_assert( std::is_function_v<const volatile T>, "");
35#endif
36};
37
38template <class T>
39struct test_is_not_function {
40    static_assert(!std::is_function<T>::value, "");
41    static_assert(!std::is_function<const T>::value, "");
42    static_assert(!std::is_function<volatile T>::value, "");
43    static_assert(!std::is_function<const volatile T>::value, "");
44#if TEST_STD_VER > 14
45    static_assert(!std::is_function_v<T>, "");
46    static_assert(!std::is_function_v<const T>, "");
47    static_assert(!std::is_function_v<volatile T>, "");
48    static_assert(!std::is_function_v<const volatile T>, "");
49#endif
50};
51
52class Empty
53{
54};
55
56class NotEmpty
57{
58    virtual ~NotEmpty();
59};
60
61union Union {};
62
63struct bit_zero
64{
65    int :  0;
66};
67
68class Abstract
69{
70    virtual ~Abstract() = 0;
71};
72
73enum Enum {zero, one};
74struct incomplete_type;
75
76typedef void (*FunctionPtr)();
77
78int main()
79{
80    test_is_function<void(void)>();
81    test_is_function<int(int)>();
82    test_is_function<int(int, double)>();
83    test_is_function<int(Abstract *)>();
84    test_is_function<void(...)>();
85
86  test_is_not_function<std::nullptr_t>();
87  test_is_not_function<void>();
88  test_is_not_function<int>();
89  test_is_not_function<int&>();
90  test_is_not_function<int&&>();
91  test_is_not_function<int*>();
92  test_is_not_function<double>();
93  test_is_not_function<char[3]>();
94  test_is_not_function<char[]>();
95  test_is_not_function<Union>();
96  test_is_not_function<Enum>();
97  test_is_not_function<FunctionPtr>(); // function pointer is not a function
98  test_is_not_function<Empty>();
99  test_is_not_function<bit_zero>();
100  test_is_not_function<NotEmpty>();
101  test_is_not_function<Abstract>();
102  test_is_not_function<Abstract*>();
103  test_is_not_function<incomplete_type>();
104
105#if TEST_STD_VER >= 11
106  test_is_function<void() noexcept>();
107  test_is_function<void() const && noexcept>();
108#endif
109}
110