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