LLVM  14.0.0git
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 = std::remove_reference_t<T>;
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, std::enable_if_t<std::is_pointer<T>::value>> {
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>
58 struct add_const_past_pointer<T, std::enable_if_t<std::is_pointer<T>::value>> {
59  using type = const std::remove_pointer_t<T> *;
60 };
61 
62 template <typename T, typename Enable = void>
64  using type = const T &;
65 };
66 template <typename T>
68  std::enable_if_t<std::is_pointer<T>::value>> {
70 };
71 
72 namespace detail {
73 /// Internal utility to detect trivial copy construction.
74 template<typename T> union copy_construction_triviality_helper {
75  T t;
79 };
80 /// Internal utility to detect trivial move construction.
81 template<typename T> union move_construction_triviality_helper {
82  T t;
86 };
87 
88 template<class T>
90  T t;
91 };
92 
93 } // end namespace detail
94 
95 /// An implementation of `std::is_trivially_copy_constructible` since we have
96 /// users with STLs that don't yet include it.
97 template <typename T>
99  : std::is_copy_constructible<
100  ::llvm::detail::copy_construction_triviality_helper<T>> {};
101 template <typename T>
102 struct is_trivially_copy_constructible<T &> : std::true_type {};
103 template <typename T>
104 struct is_trivially_copy_constructible<T &&> : std::false_type {};
105 
106 /// An implementation of `std::is_trivially_move_constructible` since we have
107 /// users with STLs that don't yet include it.
108 template <typename T>
110  : std::is_move_constructible<
111  ::llvm::detail::move_construction_triviality_helper<T>> {};
112 template <typename T>
113 struct is_trivially_move_constructible<T &> : std::true_type {};
114 template <typename T>
115 struct is_trivially_move_constructible<T &&> : std::true_type {};
116 
117 
118 template <typename T>
120  template<class F>
121  static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
122  static std::false_type get(...);
123  static constexpr bool value = decltype(get((T*)nullptr))::value;
124 };
125 
126 template <typename T>
128  template<class F>
129  static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
130  static std::false_type get(...);
131  static constexpr bool value = decltype(get((T*)nullptr))::value;
132 };
133 
134 
135 // An implementation of `std::is_trivially_copyable` since STL version
136 // is not equally supported by all compilers, especially GCC 4.9.
137 // Uniform implementation of this trait is important for ABI compatibility
138 // as it has an impact on SmallVector's ABI (among others).
139 template <typename T>
141 
142  // copy constructors
143  static constexpr bool has_trivial_copy_constructor =
144  std::is_copy_constructible<detail::trivial_helper<T>>::value;
145  static constexpr bool has_deleted_copy_constructor =
146  !std::is_copy_constructible<T>::value;
147 
148  // move constructors
149  static constexpr bool has_trivial_move_constructor =
150  std::is_move_constructible<detail::trivial_helper<T>>::value;
151  static constexpr bool has_deleted_move_constructor =
152  !std::is_move_constructible<T>::value;
153 
154  // copy assign
155  static constexpr bool has_trivial_copy_assign =
157  static constexpr bool has_deleted_copy_assign =
159 
160  // move assign
161  static constexpr bool has_trivial_move_assign =
163  static constexpr bool has_deleted_move_assign =
165 
166  // destructor
167  static constexpr bool has_trivial_destructor =
168  std::is_destructible<detail::trivial_helper<T>>::value;
169 
170  public:
171 
172  static constexpr bool value =
173  has_trivial_destructor &&
174  (has_deleted_move_assign || has_trivial_move_assign) &&
175  (has_deleted_move_constructor || has_trivial_move_constructor) &&
176  (has_deleted_copy_assign || has_trivial_copy_assign) &&
177  (has_deleted_copy_constructor || has_trivial_copy_constructor);
178 
179 #ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE
180  static_assert(value == std::is_trivially_copyable<T>::value,
181  "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable");
182 #endif
183 };
184 template <typename T>
185 class is_trivially_copyable<T*> : public std::true_type {
186 };
187 
188 
189 } // end namespace llvm
190 
191 #endif // LLVM_SUPPORT_TYPE_TRAITS_H
llvm::is_move_assignable
Definition: type_traits.h:127
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::is_integral_or_enum::value
static const bool value
Definition: type_traits.h:34
llvm::detail::move_construction_triviality_helper::t
T t
Definition: type_traits.h:82
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::const_pointer_or_const_ref< T, std::enable_if_t< std::is_pointer< T >::value > >::type
typename add_const_past_pointer< T >::type type
Definition: type_traits.h:69
llvm::is_copy_assignable::value
static constexpr bool value
Definition: type_traits.h:123
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::add_lvalue_reference_if_not_pointer
If T is a pointer, just return it. If it is not, return T&.
Definition: type_traits.h:44
llvm::is_trivially_copyable
Definition: type_traits.h:140
llvm::add_lvalue_reference_if_not_pointer::type
T & type
Definition: type_traits.h:44
llvm::add_lvalue_reference_if_not_pointer< T, std::enable_if_t< std::is_pointer< T >::value > >::type
T type
Definition: type_traits.h:49
llvm::const_pointer_or_const_ref::type
const T & type
Definition: type_traits.h:64
llvm::add_const_past_pointer< T, std::enable_if_t< std::is_pointer< T >::value > >::type
const std::remove_pointer_t< T > * type
Definition: type_traits.h:59
llvm::is_trivially_copyable::value
static constexpr bool value
Definition: type_traits.h:172
llvm::detail::copy_construction_triviality_helper::copy_construction_triviality_helper
copy_construction_triviality_helper()=default
llvm::is_trivially_move_constructible
An implementation of std::is_trivially_move_constructible since we have users with STLs that don't ye...
Definition: type_traits.h:109
llvm::is_copy_assignable
Definition: type_traits.h:119
llvm::detail::move_construction_triviality_helper
Internal utility to detect trivial move construction.
Definition: type_traits.h:81
llvm::detail::copy_construction_triviality_helper::~copy_construction_triviality_helper
~copy_construction_triviality_helper()=default
Compiler.h
llvm::is_trivially_copy_constructible
An implementation of std::is_trivially_copy_constructible since we have users with STLs that don't ye...
Definition: type_traits.h:98
llvm::add_const_past_pointer::type
const T type
Definition: type_traits.h:55
std
Definition: BitVector.h:838
llvm::detail::trivial_helper
Definition: type_traits.h:89
llvm::detail::copy_construction_triviality_helper::t
T t
Definition: type_traits.h:75
llvm::is_move_assignable::value
static constexpr bool value
Definition: type_traits.h:131
llvm::const_pointer_or_const_ref
Definition: type_traits.h:63
llvm::is_move_assignable::get
static auto get(F *) -> decltype(std::declval< F & >()=std::declval< F && >(), std::true_type
Definition: type_traits.h:129
llvm::detail::copy_construction_triviality_helper
Internal utility to detect trivial copy construction.
Definition: type_traits.h:74
llvm::is_copy_assignable::get
static auto get(F *) -> decltype(std::declval< F & >()=std::declval< const F & >(), std::true_type
Definition: type_traits.h:121
llvm::add_const_past_pointer
If T is a pointer to X, return a pointer to const X.
Definition: type_traits.h:55
llvm::detail::move_construction_triviality_helper::move_construction_triviality_helper
move_construction_triviality_helper()=default
llvm::detail::move_construction_triviality_helper::~move_construction_triviality_helper
~move_construction_triviality_helper()=default
llvm::is_integral_or_enum
Metafunction that determines whether the given type is either an integral type or an enumeration type...
Definition: type_traits.h:30
llvm::detail::trivial_helper::t
T t
Definition: type_traits.h:90