[libcxx-commits] [libcxx] [libc++][type_traits] P2674R1: A trait for implicit lifetime types (PR #106870)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Sep 8 06:30:58 PDT 2024


================
@@ -0,0 +1,279 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// These compilers don't support __builtin_is_implicit_lifetime yet.
+// UNSUPPORTED: clang-17, clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16
+
+// <type_traits>
+
+// template<class T> struct is_implicit_lifetime;
+
+#include <cassert>
+#include <cstddef>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+enum Enum { EV };
+enum SignedEnum : signed int {};
+enum UnsignedEnum : unsigned int {};
+
+enum class EnumClass { EV };
+enum class SignedEnumClass : signed int {};
+enum class UnsignedEnumClass : unsigned int {};
+
+struct EmptyStruct {};
+struct IncompleteStruct;
+
+struct NoEligibleTrivialContructor {
+  NoEligibleTrivialContructor() {};
+  NoEligibleTrivialContructor(const NoEligibleTrivialContructor&) {}
+  NoEligibleTrivialContructor(NoEligibleTrivialContructor&&) {}
+};
+
+struct OnlyDefaultConstructorIsTrivial {
+  OnlyDefaultConstructorIsTrivial() = default;
+  OnlyDefaultConstructorIsTrivial(const OnlyDefaultConstructorIsTrivial&) {}
+  OnlyDefaultConstructorIsTrivial(OnlyDefaultConstructorIsTrivial&&) {}
+};
+
+struct AllContstructorsAreTrivial {
+  AllContstructorsAreTrivial()                                  = default;
+  AllContstructorsAreTrivial(const AllContstructorsAreTrivial&) = default;
+  AllContstructorsAreTrivial(AllContstructorsAreTrivial&&)      = default;
+};
+
+struct InheritedNoEligibleTrivialConstructor : NoEligibleTrivialContructor {
+  using NoEligibleTrivialContructor::NoEligibleTrivialContructor;
+};
+
+struct InheritedOnlyDefaultConstructorIsTrivial : OnlyDefaultConstructorIsTrivial {
+  using OnlyDefaultConstructorIsTrivial::OnlyDefaultConstructorIsTrivial;
+};
+
+struct InheritedAllContstructorsAreTrivial : AllContstructorsAreTrivial {
+  using AllContstructorsAreTrivial::AllContstructorsAreTrivial;
+};
+
+struct UserDeclaredDestructor {
+  ~UserDeclaredDestructor() = default;
+};
+
+struct UserProvidedDestructor {
+  ~UserProvidedDestructor() {}
+};
+
+struct UserDeletedDestructorInAggregate {
+  ~UserDeletedDestructorInAggregate() = delete;
+};
+
+struct UserDeletedDestructorInNonAggregate {
+  virtual void NonAggregate();
+  ~UserDeletedDestructorInNonAggregate() = delete;
+};
+
+struct DeletedDestructorViaBaseInAggregate : UserDeletedDestructorInAggregate {};
+struct DeletedDestructorViaBaseInNonAggregate : UserDeletedDestructorInNonAggregate {};
+
+template <bool B>
+struct ConstrainedUserDeclaredDefaultConstructor {
+  ConstrainedUserDeclaredDefaultConstructor()
+    requires B
+  = default;
+  ConstrainedUserDeclaredDefaultConstructor(const ConstrainedUserDeclaredDefaultConstructor&) {}
+};
+
+template <bool B>
+struct ConstrainedUserProvidedDestructor {
+  ~ConstrainedUserProvidedDestructor() = default;
+  ~ConstrainedUserProvidedDestructor()
+    requires B
+  {}
+};
+
+struct StructWithFlexibleArrayMember {
+  int arr[];
+};
+
+struct StructWithZeroSizedArray {
+  int arr[0];
+};
+
+// Test implicit-lifetime type
+template <typename T, bool Expected>
+constexpr void test_is_implicit_lifetime() {
+  assert(std::is_implicit_lifetime<T>::value == Expected);
+  assert(std::is_implicit_lifetime_v<T> == Expected);
+}
+
+// Test pointer, reference, array, etc. types
+template <typename T>
+constexpr void test_is_implicit_lifetime() {
+  test_is_implicit_lifetime<T, true>();
+
+  // cv-qualified
+  test_is_implicit_lifetime<const T, true>();
+  test_is_implicit_lifetime<volatile T, true>();
+
+  test_is_implicit_lifetime<T&, false>();
+  test_is_implicit_lifetime<T&&, false>();
+
+  // Pointer types
+  test_is_implicit_lifetime<T*, true>();
+  test_is_implicit_lifetime<T* __restrict, true>();
+
+  // Arrays
+  test_is_implicit_lifetime<T[], true>();
+  test_is_implicit_lifetime<T[94], true>();
+}
+
+constexpr bool test() {
+  // Standard fundamental C++ types
+
+  test_is_implicit_lifetime<decltype(nullptr), true>();
+  test_is_implicit_lifetime<std::nullptr_t, true>();
----------------
philnik777 wrote:

These two are the same type. No need to check it twice.

https://github.com/llvm/llvm-project/pull/106870


More information about the libcxx-commits mailing list