Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Support/type_traits.h - Simplfied type traits -------*- 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. // This file provides useful additions to the standard type_traits library.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_SUPPORT_TYPE_TRAITS_H
  14. #define LLVM_SUPPORT_TYPE_TRAITS_H
  15.  
  16. #include "llvm/Support/Compiler.h"
  17. #include <type_traits>
  18. #include <utility>
  19.  
  20. namespace llvm {
  21.  
  22.  
  23. /// Metafunction that determines whether the given type is either an
  24. /// integral type or an enumeration type, including enum classes.
  25. ///
  26. /// Note that this accepts potentially more integral types than is_integral
  27. /// because it is based on being implicitly convertible to an integral type.
  28. /// Also note that enum classes aren't implicitly convertible to integral types,
  29. /// the value may therefore need to be explicitly converted before being used.
  30. template <typename T> class is_integral_or_enum {
  31.   using UnderlyingT = std::remove_reference_t<T>;
  32.  
  33. public:
  34.   static const bool value =
  35.       !std::is_class<UnderlyingT>::value && // Filter conversion operators.
  36.       !std::is_pointer<UnderlyingT>::value &&
  37.       !std::is_floating_point<UnderlyingT>::value &&
  38.       (std::is_enum<UnderlyingT>::value ||
  39.        std::is_convertible<UnderlyingT, unsigned long long>::value);
  40. };
  41.  
  42. /// If T is a pointer, just return it. If it is not, return T&.
  43. template<typename T, typename Enable = void>
  44. struct add_lvalue_reference_if_not_pointer { using type = T &; };
  45.  
  46. template <typename T>
  47. struct add_lvalue_reference_if_not_pointer<
  48.     T, std::enable_if_t<std::is_pointer<T>::value>> {
  49.   using type = T;
  50. };
  51.  
  52. /// If T is a pointer to X, return a pointer to const X. If it is not,
  53. /// return const T.
  54. template<typename T, typename Enable = void>
  55. struct add_const_past_pointer { using type = const T; };
  56.  
  57. template <typename T>
  58. struct add_const_past_pointer<T, std::enable_if_t<std::is_pointer<T>::value>> {
  59.   using type = const std::remove_pointer_t<T> *;
  60. };
  61.  
  62. template <typename T, typename Enable = void>
  63. struct const_pointer_or_const_ref {
  64.   using type = const T &;
  65. };
  66. template <typename T>
  67. struct const_pointer_or_const_ref<T,
  68.                                   std::enable_if_t<std::is_pointer<T>::value>> {
  69.   using type = typename add_const_past_pointer<T>::type;
  70. };
  71.  
  72. namespace detail {
  73. /// Internal utility to detect trivial copy construction.
  74. template<typename T> union copy_construction_triviality_helper {
  75.     T t;
  76.     copy_construction_triviality_helper() = default;
  77.     copy_construction_triviality_helper(const copy_construction_triviality_helper&) = default;
  78.     ~copy_construction_triviality_helper() = default;
  79. };
  80. /// Internal utility to detect trivial move construction.
  81. template<typename T> union move_construction_triviality_helper {
  82.     T t;
  83.     move_construction_triviality_helper() = default;
  84.     move_construction_triviality_helper(move_construction_triviality_helper&&) = default;
  85.     ~move_construction_triviality_helper() = default;
  86. };
  87.  
  88. template<class T>
  89. union trivial_helper {
  90.     T t;
  91. };
  92.  
  93. } // end namespace detail
  94.  
  95. /// An implementation of `std::is_trivially_copy_constructible` since we have
  96. /// users with STLs that don't yet include it.
  97. template <typename T>
  98. struct is_trivially_copy_constructible
  99.     : std::is_copy_constructible<
  100.           ::llvm::detail::copy_construction_triviality_helper<T>> {};
  101. template <typename T>
  102. struct is_trivially_copy_constructible<T &> : std::true_type {};
  103. template <typename T>
  104. struct is_trivially_copy_constructible<T &&> : std::false_type {};
  105.  
  106. /// An implementation of `std::is_trivially_move_constructible` since we have
  107. /// users with STLs that don't yet include it.
  108. template <typename T>
  109. struct is_trivially_move_constructible
  110.     : std::is_move_constructible<
  111.           ::llvm::detail::move_construction_triviality_helper<T>> {};
  112. template <typename T>
  113. struct is_trivially_move_constructible<T &> : std::true_type {};
  114. template <typename T>
  115. struct is_trivially_move_constructible<T &&> : std::true_type {};
  116.  
  117.  
  118. template <typename T>
  119. struct is_copy_assignable {
  120.   template<class F>
  121.     static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
  122.     static std::false_type get(...);
  123.     static constexpr bool value = decltype(get((T*)nullptr))::value;
  124. };
  125.  
  126. template <typename T>
  127. struct is_move_assignable {
  128.   template<class F>
  129.     static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
  130.     static std::false_type get(...);
  131.     static constexpr bool value = decltype(get((T*)nullptr))::value;
  132. };
  133.  
  134. } // end namespace llvm
  135.  
  136. #endif // LLVM_SUPPORT_TYPE_TRAITS_H
  137.