10b57cec5SDimitry Andric //===-- sanitizer_type_traits.h ---------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Implements a subset of C++ type traits. This is so we can avoid depending 100b57cec5SDimitry Andric // on system C++ headers. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric #ifndef SANITIZER_TYPE_TRAITS_H 140b57cec5SDimitry Andric #define SANITIZER_TYPE_TRAITS_H 150b57cec5SDimitry Andric 16349cc55cSDimitry Andric #include "sanitizer_common/sanitizer_internal_defs.h" 17349cc55cSDimitry Andric 180b57cec5SDimitry Andric namespace __sanitizer { 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric struct true_type { 210b57cec5SDimitry Andric static const bool value = true; 220b57cec5SDimitry Andric }; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric struct false_type { 250b57cec5SDimitry Andric static const bool value = false; 260b57cec5SDimitry Andric }; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric // is_same<T, U> 290b57cec5SDimitry Andric // 300b57cec5SDimitry Andric // Type trait to compare if types are the same. 310b57cec5SDimitry Andric // E.g. 320b57cec5SDimitry Andric // 330b57cec5SDimitry Andric // ``` 340b57cec5SDimitry Andric // is_same<int,int>::value - True 350b57cec5SDimitry Andric // is_same<int,char>::value - False 360b57cec5SDimitry Andric // ``` 370b57cec5SDimitry Andric template <typename T, typename U> 380b57cec5SDimitry Andric struct is_same : public false_type {}; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric template <typename T> 410b57cec5SDimitry Andric struct is_same<T, T> : public true_type {}; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // conditional<B, T, F> 440b57cec5SDimitry Andric // 450b57cec5SDimitry Andric // Defines type as T if B is true or as F otherwise. 460b57cec5SDimitry Andric // E.g. the following is true 470b57cec5SDimitry Andric // 480b57cec5SDimitry Andric // ``` 490b57cec5SDimitry Andric // is_same<int, conditional<true, int, double>::type>::value 500b57cec5SDimitry Andric // is_same<double, conditional<false, int, double>::type>::value 510b57cec5SDimitry Andric // ``` 520b57cec5SDimitry Andric template <bool B, class T, class F> 530b57cec5SDimitry Andric struct conditional { 540b57cec5SDimitry Andric using type = T; 550b57cec5SDimitry Andric }; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric template <class T, class F> 580b57cec5SDimitry Andric struct conditional<false, T, F> { 590b57cec5SDimitry Andric using type = F; 600b57cec5SDimitry Andric }; 610b57cec5SDimitry Andric 62349cc55cSDimitry Andric template <class T> 63349cc55cSDimitry Andric struct remove_reference { 64349cc55cSDimitry Andric using type = T; 65349cc55cSDimitry Andric }; 66349cc55cSDimitry Andric template <class T> 67349cc55cSDimitry Andric struct remove_reference<T&> { 68349cc55cSDimitry Andric using type = T; 69349cc55cSDimitry Andric }; 70349cc55cSDimitry Andric template <class T> 71349cc55cSDimitry Andric struct remove_reference<T&&> { 72349cc55cSDimitry Andric using type = T; 73349cc55cSDimitry Andric }; 74349cc55cSDimitry Andric 75349cc55cSDimitry Andric template <class T> 76349cc55cSDimitry Andric WARN_UNUSED_RESULT inline typename remove_reference<T>::type&& move(T&& t) { 77349cc55cSDimitry Andric return static_cast<typename remove_reference<T>::type&&>(t); 78349cc55cSDimitry Andric } 79349cc55cSDimitry Andric 80349cc55cSDimitry Andric template <class T> 81349cc55cSDimitry Andric WARN_UNUSED_RESULT inline constexpr T&& forward( 82349cc55cSDimitry Andric typename remove_reference<T>::type& t) { 83349cc55cSDimitry Andric return static_cast<T&&>(t); 84349cc55cSDimitry Andric } 85349cc55cSDimitry Andric 86349cc55cSDimitry Andric template <class T> 87349cc55cSDimitry Andric WARN_UNUSED_RESULT inline constexpr T&& forward( 88349cc55cSDimitry Andric typename remove_reference<T>::type&& t) { 89349cc55cSDimitry Andric return static_cast<T&&>(t); 90349cc55cSDimitry Andric } 91349cc55cSDimitry Andric 92349cc55cSDimitry Andric template <class T, T v> 93349cc55cSDimitry Andric struct integral_constant { 94349cc55cSDimitry Andric static constexpr const T value = v; 95349cc55cSDimitry Andric typedef T value_type; 96349cc55cSDimitry Andric typedef integral_constant type; 97349cc55cSDimitry Andric constexpr operator value_type() const { return value; } 98349cc55cSDimitry Andric constexpr value_type operator()() const { return value; } 99349cc55cSDimitry Andric }; 100349cc55cSDimitry Andric 101349cc55cSDimitry Andric #ifndef __has_builtin 102349cc55cSDimitry Andric # define __has_builtin(x) 0 103349cc55cSDimitry Andric #endif 104349cc55cSDimitry Andric 105349cc55cSDimitry Andric #if __has_builtin(__is_trivially_destructible) 106349cc55cSDimitry Andric 107349cc55cSDimitry Andric template <class T> 108349cc55cSDimitry Andric struct is_trivially_destructible 109349cc55cSDimitry Andric : public integral_constant<bool, __is_trivially_destructible(T)> {}; 110349cc55cSDimitry Andric 111349cc55cSDimitry Andric #elif __has_builtin(__has_trivial_destructor) 112349cc55cSDimitry Andric 113349cc55cSDimitry Andric template <class T> 114349cc55cSDimitry Andric struct is_trivially_destructible 115349cc55cSDimitry Andric : public integral_constant<bool, __has_trivial_destructor(T)> {}; 116349cc55cSDimitry Andric 117349cc55cSDimitry Andric #else 118349cc55cSDimitry Andric 119349cc55cSDimitry Andric template <class T> 120349cc55cSDimitry Andric struct is_trivially_destructible 121349cc55cSDimitry Andric : public integral_constant<bool, /* less efficient fallback */ false> {}; 122349cc55cSDimitry Andric 123349cc55cSDimitry Andric #endif 124349cc55cSDimitry Andric 125349cc55cSDimitry Andric #if __has_builtin(__is_trivially_copyable) 126349cc55cSDimitry Andric 127349cc55cSDimitry Andric template <class T> 128349cc55cSDimitry Andric struct is_trivially_copyable 129349cc55cSDimitry Andric : public integral_constant<bool, __is_trivially_copyable(T)> {}; 130349cc55cSDimitry Andric 131349cc55cSDimitry Andric #else 132349cc55cSDimitry Andric 133349cc55cSDimitry Andric template <class T> 134349cc55cSDimitry Andric struct is_trivially_copyable 135349cc55cSDimitry Andric : public integral_constant<bool, /* less efficient fallback */ false> {}; 136349cc55cSDimitry Andric 137349cc55cSDimitry Andric #endif 138349cc55cSDimitry Andric 1390b57cec5SDimitry Andric } // namespace __sanitizer 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric #endif 142