1 //===-- sanitizer_type_traits.h ---------------------------------*- 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 // Implements a subset of C++ type traits. This is so we can avoid depending 10 // on system C++ headers. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef SANITIZER_TYPE_TRAITS_H 14 #define SANITIZER_TYPE_TRAITS_H 15 16 #include "sanitizer_common/sanitizer_internal_defs.h" 17 18 namespace __sanitizer { 19 20 struct true_type { 21 static const bool value = true; 22 }; 23 24 struct false_type { 25 static const bool value = false; 26 }; 27 28 // is_same<T, U> 29 // 30 // Type trait to compare if types are the same. 31 // E.g. 32 // 33 // ``` 34 // is_same<int,int>::value - True 35 // is_same<int,char>::value - False 36 // ``` 37 template <typename T, typename U> 38 struct is_same : public false_type {}; 39 40 template <typename T> 41 struct is_same<T, T> : public true_type {}; 42 43 // conditional<B, T, F> 44 // 45 // Defines type as T if B is true or as F otherwise. 46 // E.g. the following is true 47 // 48 // ``` 49 // is_same<int, conditional<true, int, double>::type>::value 50 // is_same<double, conditional<false, int, double>::type>::value 51 // ``` 52 template <bool B, class T, class F> 53 struct conditional { 54 using type = T; 55 }; 56 57 template <class T, class F> 58 struct conditional<false, T, F> { 59 using type = F; 60 }; 61 62 template <class T> 63 struct remove_reference { 64 using type = T; 65 }; 66 template <class T> 67 struct remove_reference<T&> { 68 using type = T; 69 }; 70 template <class T> 71 struct remove_reference<T&&> { 72 using type = T; 73 }; 74 75 template <class T> 76 WARN_UNUSED_RESULT inline typename remove_reference<T>::type&& move(T&& t) { 77 return static_cast<typename remove_reference<T>::type&&>(t); 78 } 79 80 template <class T> 81 WARN_UNUSED_RESULT inline constexpr T&& forward( 82 typename remove_reference<T>::type& t) { 83 return static_cast<T&&>(t); 84 } 85 86 template <class T> 87 WARN_UNUSED_RESULT inline constexpr T&& forward( 88 typename remove_reference<T>::type&& t) { 89 return static_cast<T&&>(t); 90 } 91 92 template <class T, T v> 93 struct integral_constant { 94 static constexpr const T value = v; 95 typedef T value_type; 96 typedef integral_constant type; 97 constexpr operator value_type() const { return value; } 98 constexpr value_type operator()() const { return value; } 99 }; 100 101 #ifndef __has_builtin 102 # define __has_builtin(x) 0 103 #endif 104 105 #if __has_builtin(__is_trivially_destructible) 106 107 template <class T> 108 struct is_trivially_destructible 109 : public integral_constant<bool, __is_trivially_destructible(T)> {}; 110 111 #elif __has_builtin(__has_trivial_destructor) 112 113 template <class T> 114 struct is_trivially_destructible 115 : public integral_constant<bool, __has_trivial_destructor(T)> {}; 116 117 #else 118 119 template <class T> 120 struct is_trivially_destructible 121 : public integral_constant<bool, /* less efficient fallback */ false> {}; 122 123 #endif 124 125 #if __has_builtin(__is_trivially_copyable) 126 127 template <class T> 128 struct is_trivially_copyable 129 : public integral_constant<bool, __is_trivially_copyable(T)> {}; 130 131 #else 132 133 template <class T> 134 struct is_trivially_copyable 135 : public integral_constant<bool, /* less efficient fallback */ false> {}; 136 137 #endif 138 139 } // namespace __sanitizer 140 141 #endif 142