LLVM  10.0.0svn
type_traits.h
Go to the documentation of this file.
1 //===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
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 // This file provides useful additions to the standard type_traits library.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_SUPPORT_TYPE_TRAITS_H
14 #define LLVM_SUPPORT_TYPE_TRAITS_H
15 
16 #include "llvm/Support/Compiler.h"
17 #include <type_traits>
18 #include <utility>
19 
20 namespace llvm {
21 
22 
23 /// Metafunction that determines whether the given type is either an
24 /// integral type or an enumeration type, including enum classes.
25 ///
26 /// Note that this accepts potentially more integral types than is_integral
27 /// because it is based on being implicitly convertible to an integral type.
28 /// Also note that enum classes aren't implicitly convertible to integral types,
29 /// the value may therefore need to be explicitly converted before being used.
30 template <typename T> class is_integral_or_enum {
31  using UnderlyingT = typename std::remove_reference<T>::type;
32 
33 public:
34  static const bool value =
35  !std::is_class<UnderlyingT>::value && // Filter conversion operators.
36  !std::is_pointer<UnderlyingT>::value &&
37  !std::is_floating_point<UnderlyingT>::value &&
38  (std::is_enum<UnderlyingT>::value ||
39  std::is_convertible<UnderlyingT, unsigned long long>::value);
40 };
41 
42 /// If T is a pointer, just return it. If it is not, return T&.
43 template<typename T, typename Enable = void>
45 
46 template <typename T>
48  T, typename std::enable_if<std::is_pointer<T>::value>::type> {
49  using type = T;
50 };
51 
52 /// If T is a pointer to X, return a pointer to const X. If it is not,
53 /// return const T.
54 template<typename T, typename Enable = void>
55 struct add_const_past_pointer { using type = const T; };
56 
57 template <typename T>
59  T, typename std::enable_if<std::is_pointer<T>::value>::type> {
60  using type = const typename std::remove_pointer<T>::type *;
61 };
62 
63 template <typename T, typename Enable = void>
65  using type = const T &;
66 };
67 template <typename T>
69  T, typename std::enable_if<std::is_pointer<T>::value>::type> {
71 };
72 
73 namespace detail {
74 /// Internal utility to detect trivial copy construction.
75 template<typename T> union copy_construction_triviality_helper {
76  T t;
80 };
81 /// Internal utility to detect trivial move construction.
82 template<typename T> union move_construction_triviality_helper {
83  T t;
87 };
88 
89 template<class T>
91  T t;
92 };
93 
94 } // end namespace detail
95 
96 /// An implementation of `std::is_trivially_copy_constructible` since we have
97 /// users with STLs that don't yet include it.
98 template <typename T>
100  : std::is_copy_constructible<
101  ::llvm::detail::copy_construction_triviality_helper<T>> {};
102 template <typename T>
103 struct is_trivially_copy_constructible<T &> : std::true_type {};
104 template <typename T>
105 struct is_trivially_copy_constructible<T &&> : std::false_type {};
106 
107 /// An implementation of `std::is_trivially_move_constructible` since we have
108 /// users with STLs that don't yet include it.
109 template <typename T>
111  : std::is_move_constructible<
112  ::llvm::detail::move_construction_triviality_helper<T>> {};
113 template <typename T>
114 struct is_trivially_move_constructible<T &> : std::true_type {};
115 template <typename T>
116 struct is_trivially_move_constructible<T &&> : std::true_type {};
117 
118 
119 template <typename T>
121  template<class F>
122  static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
123  static std::false_type get(...);
124  static constexpr bool value = decltype(get((T*)nullptr))::value;
125 };
126 
127 template <typename T>
129  template<class F>
130  static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
131  static std::false_type get(...);
132  static constexpr bool value = decltype(get((T*)nullptr))::value;
133 };
134 
135 
136 // An implementation of `std::is_trivially_copyable` since STL version
137 // is not equally supported by all compilers, especially GCC 4.9.
138 // Uniform implementation of this trait is important for ABI compatibility
139 // as it has an impact on SmallVector's ABI (among others).
140 template <typename T>
142 
143  // copy constructors
144  static constexpr bool has_trivial_copy_constructor =
145  std::is_copy_constructible<detail::trivial_helper<T>>::value;
146  static constexpr bool has_deleted_copy_constructor =
147  !std::is_copy_constructible<T>::value;
148 
149  // move constructors
150  static constexpr bool has_trivial_move_constructor =
151  std::is_move_constructible<detail::trivial_helper<T>>::value;
152  static constexpr bool has_deleted_move_constructor =
153  !std::is_move_constructible<T>::value;
154 
155  // copy assign
156  static constexpr bool has_trivial_copy_assign =
158  static constexpr bool has_deleted_copy_assign =
160 
161  // move assign
162  static constexpr bool has_trivial_move_assign =
164  static constexpr bool has_deleted_move_assign =
166 
167  // destructor
168  static constexpr bool has_trivial_destructor =
169  std::is_destructible<detail::trivial_helper<T>>::value;
170 
171  public:
172 
173  static constexpr bool value =
174  has_trivial_destructor &&
175  (has_deleted_move_assign || has_trivial_move_assign) &&
176  (has_deleted_move_constructor || has_trivial_move_constructor) &&
177  (has_deleted_copy_assign || has_trivial_copy_assign) &&
178  (has_deleted_copy_constructor || has_trivial_copy_constructor);
179 
180 #ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
181  static_assert(value == std::is_trivially_copyable<T>::value,
182  "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
183 #endif
184 };
185 template <typename T>
186 class is_trivially_copyable<T*> : public std::true_type {
187 };
188 
189 
190 } // end namespace llvm
191 
192 #endif // LLVM_SUPPORT_TYPE_TRAITS_H
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static const bool value
Definition: type_traits.h:34
F(f)
Definition: BitVector.h:937
Metafunction that determines whether the given type is either an integral type or an enumeration type...
Definition: type_traits.h:30
An implementation of std::is_trivially_move_constructible since we have users with STLs that don&#39;t ye...
Definition: type_traits.h:110
An implementation of std::is_trivially_copy_constructible since we have users with STLs that don&#39;t ye...
Definition: type_traits.h:99
If T is a pointer to X, return a pointer to const X.
Definition: type_traits.h:55
Internal utility to detect trivial copy construction.
Definition: type_traits.h:75
If T is a pointer, just return it. If it is not, return T&.
Definition: type_traits.h:44
Internal utility to detect trivial move construction.
Definition: type_traits.h:82