Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:34

0001 //===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provides useful additions to the standard type_traits library.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_SUPPORT_TYPE_TRAITS_H
0014 #define LLVM_SUPPORT_TYPE_TRAITS_H
0015 
0016 #include "llvm/Support/Compiler.h"
0017 #include <type_traits>
0018 #include <utility>
0019 
0020 namespace llvm {
0021 
0022 
0023 /// Metafunction that determines whether the given type is either an
0024 /// integral type or an enumeration type, including enum classes.
0025 ///
0026 /// Note that this accepts potentially more integral types than is_integral
0027 /// because it is based on being implicitly convertible to an integral type.
0028 /// Also note that enum classes aren't implicitly convertible to integral types,
0029 /// the value may therefore need to be explicitly converted before being used.
0030 template <typename T> class is_integral_or_enum {
0031   using UnderlyingT = std::remove_reference_t<T>;
0032 
0033 public:
0034   static const bool value =
0035       !std::is_class_v<UnderlyingT> && // Filter conversion operators.
0036       !std::is_pointer_v<UnderlyingT> &&
0037       !std::is_floating_point_v<UnderlyingT> &&
0038       (std::is_enum_v<UnderlyingT> ||
0039        std::is_convertible_v<UnderlyingT, unsigned long long>);
0040 };
0041 
0042 /// If T is a pointer, just return it. If it is not, return T&.
0043 template<typename T, typename Enable = void>
0044 struct add_lvalue_reference_if_not_pointer { using type = T &; };
0045 
0046 template <typename T>
0047 struct add_lvalue_reference_if_not_pointer<
0048     T, std::enable_if_t<std::is_pointer_v<T>>> {
0049   using type = T;
0050 };
0051 
0052 /// If T is a pointer to X, return a pointer to const X. If it is not,
0053 /// return const T.
0054 template<typename T, typename Enable = void>
0055 struct add_const_past_pointer { using type = const T; };
0056 
0057 template <typename T>
0058 struct add_const_past_pointer<T, std::enable_if_t<std::is_pointer_v<T>>> {
0059   using type = const std::remove_pointer_t<T> *;
0060 };
0061 
0062 template <typename T, typename Enable = void>
0063 struct const_pointer_or_const_ref {
0064   using type = const T &;
0065 };
0066 template <typename T>
0067 struct const_pointer_or_const_ref<T, std::enable_if_t<std::is_pointer_v<T>>> {
0068   using type = typename add_const_past_pointer<T>::type;
0069 };
0070 
0071 namespace detail {
0072 template<class T>
0073 union trivial_helper {
0074     T t;
0075 };
0076 
0077 } // end namespace detail
0078 
0079 template <typename T>
0080 struct is_copy_assignable {
0081   template<class F>
0082     static auto get(F*) -> decltype(std::declval<F &>() = std::declval<const F &>(), std::true_type{});
0083     static std::false_type get(...);
0084     static constexpr bool value = decltype(get((T*)nullptr))::value;
0085 };
0086 
0087 template <typename T>
0088 struct is_move_assignable {
0089   template<class F>
0090     static auto get(F*) -> decltype(std::declval<F &>() = std::declval<F &&>(), std::true_type{});
0091     static std::false_type get(...);
0092     static constexpr bool value = decltype(get((T*)nullptr))::value;
0093 };
0094 
0095 } // end namespace llvm
0096 
0097 #endif // LLVM_SUPPORT_TYPE_TRAITS_H