llvm.org GIT mirror llvm / 52b38c4
[Support] Fix llvm::unique_function when building with GCC 4.9 by introducing llvm::trivially_{copy,move}_constructible type traits. This uses a completely portable implementation of these traits provided by Richard Smith. You can see it on compiler explorer in all its glory: https://godbolt.org/g/QEDZjW I have transcribed it, clang-formatted it, added some comments, and made the tests fit into a unittest file. I have also switched llvm::unique_function over to use these new, much more portable traits. =D Hopefully this will fix the build bot breakage from my prior commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336161 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 1 year, 3 months ago
4 changed file(s) with 120 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
3434
3535 #include "llvm/ADT/PointerIntPair.h"
3636 #include "llvm/ADT/PointerUnion.h"
37 #include "llvm/Support/type_traits.h"
3738 #include
38 #include
3939
4040 namespace llvm {
4141
5757 template
5858 using AdjustedParamT = typename std::conditional<
5959 !std::is_reference::value &&
60 std::is_trivially_copy_constructible::value &&
61 std::is_trivially_move_constructible::value &&
60 llvm::is_trivially_copy_constructible::value &&
61 llvm::is_trivially_move_constructible::value &&
6262 sizeof(T) <= (2 * sizeof(void *)),
6363 T, T &>::type;
6464
103103 using type = typename add_const_past_pointer::type;
104104 };
105105
106 namespace detail {
107 /// Internal utility to detect trivial copy construction.
108 template union copy_construction_triviality_helper {
109 T t;
110 copy_construction_triviality_helper() = default;
111 copy_construction_triviality_helper(const copy_construction_triviality_helper&) = default;
112 ~copy_construction_triviality_helper() = default;
113 };
114 /// Internal utility to detect trivial move construction.
115 template union move_construction_triviality_helper {
116 T t;
117 move_construction_triviality_helper() = default;
118 move_construction_triviality_helper(move_construction_triviality_helper&&) = default;
119 ~move_construction_triviality_helper() = default;
120 };
121 } // end namespace detail
122
123 /// An implementation of `std::is_trivially_copy_constructible` since we have
124 /// users with STLs that don't yet include it.
125 template
126 struct is_trivially_copy_constructible
127 : std::is_copy_constructible<
128 ::llvm::detail::copy_construction_triviality_helper> {};
129 template
130 struct is_trivially_copy_constructible : std::true_type {};
131 template
132 struct is_trivially_copy_constructible : std::false_type {};
133
134 /// An implementation of `std::is_trivially_move_constructible` since we have
135 /// users with STLs that don't yet include it.
136 template
137 struct is_trivially_move_constructible
138 : std::is_move_constructible<
139 ::llvm::detail::move_construction_triviality_helper> {};
140 template
141 struct is_trivially_move_constructible : std::true_type {};
142 template
143 struct is_trivially_move_constructible : std::true_type {};
144
106145 } // end namespace llvm
107146
108147 // If the compiler supports detecting whether a class is final, define
5858 Threading.cpp
5959 TimerTest.cpp
6060 TypeNameTest.cpp
61 TypeTraitsTest.cpp
6162 TrailingObjectsTest.cpp
6263 TrigramIndexTest.cpp
6364 UnicodeTest.cpp
0 //===- TypeTraitsTest.cpp -------------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Support/type_traits.h"
10
11 namespace {
12
13 // Compile-time tests using static assert.
14 namespace triviality {
15
16 // Helper for compile time checking trivially copy constructible and trivially
17 // move constructible type traits.
18 template
19 bool IsTriviallyMoveConstructible>
20 void TrivialityTester() {
21 static_assert(llvm::is_trivially_copy_constructible::value ==
22 IsTriviallyCopyConstructible,
23 "Mismatch in expected trivial copy construction!");
24 static_assert(llvm::is_trivially_move_constructible::value ==
25 IsTriviallyMoveConstructible,
26 "Mismatch in expected trivial move construction!");
27
28 #if __clang__ || _MSC_VER || __GNUC__ > 5
29 // On compilers with support for the standard traits, make sure they agree.
30 static_assert(std::is_trivially_copy_constructible::value ==
31 IsTriviallyCopyConstructible,
32 "Mismatch in expected trivial copy construction!");
33 static_assert(std::is_trivially_move_constructible::value ==
34 IsTriviallyMoveConstructible,
35 "Mismatch in expected trivial move construction!");
36 #endif
37 };
38
39 template void TrivialityTester();
40 template void TrivialityTester();
41 template void TrivialityTester();
42 template void TrivialityTester();
43
44 struct X {};
45 struct Y {
46 Y(const Y &);
47 };
48 struct Z {
49 Z(const Z &);
50 Z(Z &&);
51 };
52 struct A {
53 A(const A &) = default;
54 A(A &&);
55 };
56 struct B {
57 B(const B &);
58 B(B &&) = default;
59 };
60
61 template void TrivialityTester();
62 template void TrivialityTester();
63 template void TrivialityTester();
64 template void TrivialityTester();
65 template void TrivialityTester();
66
67 template void TrivialityTester();
68 template void TrivialityTester();
69 template void TrivialityTester();
70 template void TrivialityTester();
71 template void TrivialityTester();
72 template void TrivialityTester();
73
74 } // namespace triviality
75
76 } // end anonymous namespace