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 18namespace __sanitizer { 19 20struct true_type { 21 static const bool value = true; 22}; 23 24struct 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// ``` 37template <typename T, typename U> 38struct is_same : public false_type {}; 39 40template <typename T> 41struct 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// ``` 52template <bool B, class T, class F> 53struct conditional { 54 using type = T; 55}; 56 57template <class T, class F> 58struct conditional<false, T, F> { 59 using type = F; 60}; 61 62template <class T> 63struct remove_reference { 64 using type = T; 65}; 66template <class T> 67struct remove_reference<T&> { 68 using type = T; 69}; 70template <class T> 71struct remove_reference<T&&> { 72 using type = T; 73}; 74 75template <class T> 76WARN_UNUSED_RESULT inline typename remove_reference<T>::type&& move(T&& t) { 77 return static_cast<typename remove_reference<T>::type&&>(t); 78} 79 80template <class T> 81WARN_UNUSED_RESULT inline constexpr T&& forward( 82 typename remove_reference<T>::type& t) { 83 return static_cast<T&&>(t); 84} 85 86template <class T> 87WARN_UNUSED_RESULT inline constexpr T&& forward( 88 typename remove_reference<T>::type&& t) { 89 return static_cast<T&&>(t); 90} 91 92template <class T, T v> 93struct 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 107template <class T> 108struct is_trivially_destructible 109 : public integral_constant<bool, __is_trivially_destructible(T)> {}; 110 111#elif __has_builtin(__has_trivial_destructor) 112 113template <class T> 114struct is_trivially_destructible 115 : public integral_constant<bool, __has_trivial_destructor(T)> {}; 116 117#else 118 119template <class T> 120struct is_trivially_destructible 121 : public integral_constant<bool, /* less efficient fallback */ false> {}; 122 123#endif 124 125#if __has_builtin(__is_trivially_copyable) 126 127template <class T> 128struct is_trivially_copyable 129 : public integral_constant<bool, __is_trivially_copyable(T)> {}; 130 131#else 132 133template <class T> 134struct is_trivially_copyable 135 : public integral_constant<bool, /* less efficient fallback */ false> {}; 136 137#endif 138 139} // namespace __sanitizer 140 141#endif 142