From 06a52ce65151c6de4046283f718589d42197e8fe Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Mon, 17 May 2021 20:26:59 -0700 Subject: [PATCH] Revert "[ADT] Add new type traits for type pack indexes" This reverts commit a6d3987b8ef3b7616f0835b89515c4264f2a7a64. --- include/llvm/ADT/PointerUnion.h | 25 ++++++++++++--- include/llvm/ADT/STLExtras.h | 54 --------------------------------- unittests/ADT/STLExtrasTest.cpp | 36 ---------------------- 3 files changed, 20 insertions(+), 95 deletions(-) diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 5c3ef01f1b0..c39691061b7 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -64,6 +64,21 @@ namespace pointer_union_detail { return std::min({PointerLikeTypeTraits::NumLowBitsAvailable...}); } + /// Find the index of a type in a list of types. TypeIndex::Index + /// is the index of T in Us, or sizeof...(Us) if T does not appear in the + /// list. + template struct TypeIndex; + template struct TypeIndex { + static constexpr int Index = 0; + }; + template + struct TypeIndex { + static constexpr int Index = 1 + TypeIndex::Index; + }; + template struct TypeIndex { + static constexpr int Index = 0; + }; + /// Find the first type in a list of types. template struct GetFirstType { using type = T; @@ -130,7 +145,6 @@ namespace pointer_union_detail { /// P = (float*)0; /// Y = P.get(); // ok. /// X = P.get(); // runtime assertion failure. -/// PointerUnion Q; // compile time failure. template class PointerUnion : public pointer_union_detail::PointerUnionMembers< @@ -139,14 +153,12 @@ class PointerUnion void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, pointer_union_detail::PointerUnionUIntTraits>, 0, PTs...> { - static_assert(TypesAreDistinct(), - "PointerUnion alternative types cannot be repeated"); // The first type is special because we want to directly cast a pointer to a // default-initialized union to a pointer to the first type. But we don't // want PointerUnion to be a 'template ' // because it's much more convenient to have a name for the whole pack. So // split off the first type here. - using First = TypeAtIndex<0, PTs...>; + using First = typename pointer_union_detail::GetFirstType::type; using Base = typename PointerUnion::PointerUnionMembers; public: @@ -163,7 +175,10 @@ public: /// Test if the Union currently holds the type matching T. template bool is() const { - return this->Val.getInt() == FirstIndexOfType{}; + constexpr int Index = pointer_union_detail::TypeIndex::Index; + static_assert(Index < sizeof...(PTs), + "PointerUnion::is given type not in the union"); + return this->Val.getInt() == Index; } /// Returns the value of the specified pointer type. diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index fad62a5f7c9..182451c25e3 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -144,60 +144,6 @@ template struct function_traits : public function_traits {}; -namespace detail { -template -constexpr size_t getFirstIndexOfTypeImpl() { - constexpr bool Matches[] = {false, std::is_same{}...}; - // TODO: use llvm::find once it's constexpr (std::find is constexpr in C++20) - for (size_t I = 1; I <= sizeof...(Ts); ++I) - if (Matches[I]) - return I - 1; - return sizeof...(Ts); -} -template constexpr size_t getFirstIndexOfType() { - constexpr size_t Index = getFirstIndexOfTypeImpl(); - static_assert(Index != sizeof...(Ts), - "type T is not present in type pack Ts"); - return Index; -} -template static constexpr bool areTypesDistinct() { - constexpr size_t IndexOf[] = {0, getFirstIndexOfType()...}; - // TODO: use llvm::find once it's constexpr (std::find is constexpr in C++20) - for (size_t I = 1; I <= sizeof...(Ts); ++I) - if (I - 1 != IndexOf[I]) - return false; - return true; -} -} // namespace detail - -/// Determine if all types in Ts are distinct. -/// -/// Useful to statically assert when Ts is intended to describe a non-multi set -/// of types. -template -using TypesAreDistinct = - std::integral_constant()>; - -/// Find the first index where a type appears in a list of types. -/// -/// FirstIndexOfType::value is the first index of T in Ts. -/// -/// Typically only meaningful when it is otherwise statically known that the -/// type pack has no duplicate types. This should be guaranteed explicitly with -/// static_assert(TypesAreDistinct{}). -/// -/// It is a compile-time error to instantiate when T is not present in Ts, i.e. -/// if is_one_of::value is false. -template -using FirstIndexOfType = - std::integral_constant()>; - -/// Find the type at a given index in a list of types. -/// -/// TypeAtIndex is the type at index I in Ts. -template -using TypeAtIndex = std::tuple_element_t>; - //===----------------------------------------------------------------------===// // Extra additions to //===----------------------------------------------------------------------===// diff --git a/unittests/ADT/STLExtrasTest.cpp b/unittests/ADT/STLExtrasTest.cpp index a80c6ce7730..86265305541 100644 --- a/unittests/ADT/STLExtrasTest.cpp +++ b/unittests/ADT/STLExtrasTest.cpp @@ -711,40 +711,4 @@ TEST(STLExtras, MoveRange) { EXPECT_EQ(V4.size(), 4U); EXPECT_TRUE(llvm::all_of(V4, HasVal)); } - -TEST(STLExtrasTest, TypesAreDistinct) { - EXPECT_TRUE((llvm::TypesAreDistinct<>::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_FALSE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_FALSE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_FALSE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); - EXPECT_TRUE((llvm::TypesAreDistinct::value)); -} - -TEST(STLExtrasTest, FirstIndexOfType) { - EXPECT_EQ((llvm::FirstIndexOfType::value), 0u); - EXPECT_EQ((llvm::FirstIndexOfType::value), 0u); - EXPECT_EQ((llvm::FirstIndexOfType::value), 1u); - EXPECT_EQ((llvm::FirstIndexOfType::value), - 2u); -} - -TEST(STLExtrasTest, TypeAtIndex) { - EXPECT_TRUE((std::is_same>::value)); - EXPECT_TRUE((std::is_same>::value)); - EXPECT_TRUE((std::is_same>::value)); - EXPECT_TRUE( - (std::is_same>::value)); - EXPECT_TRUE( - (std::is_same>::value)); - EXPECT_TRUE( - (std::is_same>::value)); -} - } // namespace