1//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file provides useful additions to the standard type_traits library. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_SUPPORT_TYPE_TRAITS_H 15#define LLVM_SUPPORT_TYPE_TRAITS_H 16 17#include <type_traits> 18#include <utility> 19 20#include "llvm/Support/Compiler.h" 21 22#ifndef __has_feature 23#define LLVM_DEFINED_HAS_FEATURE 24#define __has_feature(x) 0 25#endif 26 27namespace llvm { 28 29/// isPodLike - This is a type trait that is used to determine whether a given 30/// type can be copied around with memcpy instead of running ctors etc. 31template <typename T> 32struct isPodLike { 33 // std::is_trivially_copyable is available in libc++ with clang, libstdc++ 34 // that comes with GCC 5. 35#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \ 36 (defined(__GNUC__) && __GNUC__ >= 5) 37 // If the compiler supports the is_trivially_copyable trait use it, as it 38 // matches the definition of isPodLike closely. 39 static const bool value = std::is_trivially_copyable<T>::value; 40#elif __has_feature(is_trivially_copyable) 41 // Use the internal name if the compiler supports is_trivially_copyable but we 42 // don't know if the standard library does. This is the case for clang in 43 // conjunction with libstdc++ from GCC 4.x. 44 static const bool value = __is_trivially_copyable(T); 45#else 46 // If we don't know anything else, we can (at least) assume that all non-class 47 // types are PODs. 48 static const bool value = !std::is_class<T>::value; 49#endif 50}; 51 52// std::pair's are pod-like if their elements are. 53template<typename T, typename U> 54struct isPodLike<std::pair<T, U> > { 55 static const bool value = isPodLike<T>::value && isPodLike<U>::value; 56}; 57 58/// \brief Metafunction that determines whether the given type is either an 59/// integral type or an enumeration type, including enum classes. 60/// 61/// Note that this accepts potentially more integral types than is_integral 62/// because it is based on being implicitly convertible to an integral type. 63/// Also note that enum classes aren't implicitly convertible to integral types, 64/// the value may therefore need to be explicitly converted before being used. 65template <typename T> class is_integral_or_enum { 66 typedef typename std::remove_reference<T>::type UnderlyingT; 67 68public: 69 static const bool value = 70 !std::is_class<UnderlyingT>::value && // Filter conversion operators. 71 !std::is_pointer<UnderlyingT>::value && 72 !std::is_floating_point<UnderlyingT>::value && 73 (std::is_enum<UnderlyingT>::value || 74 std::is_convertible<UnderlyingT, unsigned long long>::value); 75}; 76 77/// \brief If T is a pointer, just return it. If it is not, return T&. 78template<typename T, typename Enable = void> 79struct add_lvalue_reference_if_not_pointer { typedef T &type; }; 80 81template <typename T> 82struct add_lvalue_reference_if_not_pointer< 83 T, typename std::enable_if<std::is_pointer<T>::value>::type> { 84 typedef T type; 85}; 86 87/// \brief If T is a pointer to X, return a pointer to const X. If it is not, 88/// return const T. 89template<typename T, typename Enable = void> 90struct add_const_past_pointer { typedef const T type; }; 91 92template <typename T> 93struct add_const_past_pointer< 94 T, typename std::enable_if<std::is_pointer<T>::value>::type> { 95 typedef const typename std::remove_pointer<T>::type *type; 96}; 97 98} 99 100// If the compiler supports detecting whether a class is final, define 101// an LLVM_IS_FINAL macro. If it cannot be defined properly, this 102// macro will be left undefined. 103#if __cplusplus >= 201402L 104#define LLVM_IS_FINAL(Ty) std::is_final<Ty>() 105#elif __has_feature(is_final) || LLVM_GNUC_PREREQ(4, 7, 0) 106#define LLVM_IS_FINAL(Ty) __is_final(Ty) 107#endif 108 109#ifdef LLVM_DEFINED_HAS_FEATURE 110#undef __has_feature 111#endif 112 113#endif 114