brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 1c9d72e Raw
244 lines · cpp
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: std-at-least-c++2310 11// These compilers don't support __builtin_is_implicit_lifetime yet.12// UNSUPPORTED: clang-19, gcc-15, apple-clang-1713 14// <type_traits>15 16// template<class T> struct is_implicit_lifetime;17 18#include <cassert>19#include <cstddef>20#include <expected>21#include <optional>22#include <tuple>23#include <type_traits>24#include <utility>25#include <variant>26 27#include "test_macros.h"28#include "type_algorithms.h"29 30enum Enum { EV };31enum SignedEnum : signed int {};32enum UnsignedEnum : unsigned int {};33 34enum class EnumClass { EV };35enum class SignedEnumClass : signed int {};36enum class UnsignedEnumClass : unsigned int {};37 38struct EmptyStruct {};39struct IncompleteStruct;40 41struct NoEligibleTrivialConstructor {42  NoEligibleTrivialConstructor() {};43  NoEligibleTrivialConstructor(const NoEligibleTrivialConstructor&) {}44  NoEligibleTrivialConstructor(NoEligibleTrivialConstructor&&) {}45};46 47struct OnlyDefaultConstructorIsTrivial {48  OnlyDefaultConstructorIsTrivial() = default;49  OnlyDefaultConstructorIsTrivial(const OnlyDefaultConstructorIsTrivial&) {}50  OnlyDefaultConstructorIsTrivial(OnlyDefaultConstructorIsTrivial&&) {}51};52 53struct AllConstructorsAreTrivial {54  AllConstructorsAreTrivial()                                 = default;55  AllConstructorsAreTrivial(const AllConstructorsAreTrivial&) = default;56  AllConstructorsAreTrivial(AllConstructorsAreTrivial&&)      = default;57};58 59struct InheritedNoEligibleTrivialConstructor : NoEligibleTrivialConstructor {60  using NoEligibleTrivialConstructor::NoEligibleTrivialConstructor;61};62 63struct InheritedOnlyDefaultConstructorIsTrivial : OnlyDefaultConstructorIsTrivial {64  using OnlyDefaultConstructorIsTrivial::OnlyDefaultConstructorIsTrivial;65};66 67struct InheritedAllConstructorsAreTrivial : AllConstructorsAreTrivial {68  using AllConstructorsAreTrivial::AllConstructorsAreTrivial;69};70 71struct UserDeclaredDestructor {72  ~UserDeclaredDestructor() = default;73};74 75struct UserProvidedDestructor {76  ~UserProvidedDestructor() {}77};78 79struct UserDeletedDestructorInAggregate {80  ~UserDeletedDestructorInAggregate() = delete;81};82 83struct UserDeletedDestructorInNonAggregate {84  virtual void NonAggregate();85  ~UserDeletedDestructorInNonAggregate() = delete;86};87 88struct DeletedDestructorViaBaseInAggregate : UserDeletedDestructorInAggregate {};89struct DeletedDestructorViaBaseInNonAggregate : UserDeletedDestructorInNonAggregate {};90 91template <bool B>92struct ConstrainedUserDeclaredDefaultConstructor {93  ConstrainedUserDeclaredDefaultConstructor()94    requires B95  = default;96  ConstrainedUserDeclaredDefaultConstructor(const ConstrainedUserDeclaredDefaultConstructor&) {}97};98 99template <bool B>100struct ConstrainedUserProvidedDestructor {101  ~ConstrainedUserProvidedDestructor() = default;102  ~ConstrainedUserProvidedDestructor()103    requires B104  {}105};106 107struct StructWithFlexibleArrayMember {108  int arr[];109};110 111struct StructWithZeroSizedArray {112  int arr[0];113};114 115// Test implicit-lifetime type116template <typename T, bool Expected>117constexpr void test_is_implicit_lifetime() {118  assert(std::is_implicit_lifetime<T>::value == Expected);119  assert(std::is_implicit_lifetime_v<T> == Expected);120}121 122// Test pointer, reference, array, etc. types123template <typename T>124constexpr void test_is_implicit_lifetime() {125  test_is_implicit_lifetime<T, true>();126 127  // cv-qualified128  test_is_implicit_lifetime<const T, true>();129  test_is_implicit_lifetime<volatile T, true>();130 131  test_is_implicit_lifetime<T&, false>();132  test_is_implicit_lifetime<T&&, false>();133 134  // Pointer types135  test_is_implicit_lifetime<T*, true>();136 137  // Arrays138  test_is_implicit_lifetime<T[], true>();139  test_is_implicit_lifetime<T[94], true>();140}141 142constexpr bool test() {143  // Standard fundamental C++ types144 145  test_is_implicit_lifetime<std::nullptr_t, true>();146 147  test_is_implicit_lifetime<void, false>();148  test_is_implicit_lifetime<const void, false>();149  test_is_implicit_lifetime<volatile void, false>();150 151  types::for_each(types::arithmetic_types(), []<typename T> { test_is_implicit_lifetime<T>(); });152 153  test_is_implicit_lifetime<Enum>();154  test_is_implicit_lifetime<SignedEnum>();155  test_is_implicit_lifetime<UnsignedEnum>();156 157  test_is_implicit_lifetime<EnumClass>();158  test_is_implicit_lifetime<SignedEnumClass>();159  test_is_implicit_lifetime<UnsignedEnumClass>();160 161  test_is_implicit_lifetime<void(), false>();162  test_is_implicit_lifetime<void()&, false>();163  test_is_implicit_lifetime<void() const, false>();164  test_is_implicit_lifetime<void (&)(), false>();165  test_is_implicit_lifetime<void (*)(), true>();166 167  // Implicit-lifetime class types168 169  test_is_implicit_lifetime<EmptyStruct>();170  test_is_implicit_lifetime<int EmptyStruct::*, true>(); // Pointer-to-member171  test_is_implicit_lifetime<int (EmptyStruct::*)(), true>();172  test_is_implicit_lifetime<int (EmptyStruct::*)() const, true>();173  test_is_implicit_lifetime<int (EmptyStruct::*)()&, true>();174  test_is_implicit_lifetime<int (EmptyStruct::*)()&&, true>();175 176  test_is_implicit_lifetime<IncompleteStruct[], true>();177  test_is_implicit_lifetime<IncompleteStruct[82], true>();178 179  test_is_implicit_lifetime<UserDeclaredDestructor>();180 181  test_is_implicit_lifetime<UserProvidedDestructor, false>();182 183  test_is_implicit_lifetime<NoEligibleTrivialConstructor, false>();184 185  test_is_implicit_lifetime<OnlyDefaultConstructorIsTrivial, true>();186 187  test_is_implicit_lifetime<AllConstructorsAreTrivial, true>();188 189  test_is_implicit_lifetime<InheritedNoEligibleTrivialConstructor, false>();190 191  test_is_implicit_lifetime<InheritedOnlyDefaultConstructorIsTrivial, true>();192 193  test_is_implicit_lifetime<InheritedAllConstructorsAreTrivial, true>();194 195  test_is_implicit_lifetime<UserDeletedDestructorInAggregate, true>();196 197  test_is_implicit_lifetime<UserDeletedDestructorInNonAggregate, false>();198 199  test_is_implicit_lifetime<DeletedDestructorViaBaseInAggregate, true>();200 201  test_is_implicit_lifetime<DeletedDestructorViaBaseInNonAggregate, false>();202 203  test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<true>, true>();204  test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<false>, false>();205 206  test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<true>, false>();207  test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<false>, true>();208 209  test_is_implicit_lifetime<StructWithFlexibleArrayMember, true>();210 211  test_is_implicit_lifetime<StructWithZeroSizedArray, true>();212 213  // C++ standard library types214 215  // These types are guaranteed to be implicit-lifetime.216  test_is_implicit_lifetime<std::expected<int, float>>();217  test_is_implicit_lifetime<std::optional<float>>();218  test_is_implicit_lifetime<std::variant<float, int>>();219 220#ifdef _LIBCPP_VERSION221  // These types should be implicit-lifetime, but they are not guaranteed to be so.222#  ifndef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR223  test_is_implicit_lifetime<std::pair<int, float>>();224#  endif225  test_is_implicit_lifetime<std::tuple<int, float>>();226#endif227 228  // Standard C23 types229 230#ifdef TEST_COMPILER_CLANG231  test_is_implicit_lifetime<_BitInt(8)>();232  test_is_implicit_lifetime<_BitInt(128)>();233#endif234 235  return true;236}237 238int main(int, char**) {239  test();240  static_assert(test());241 242  return 0;243}244