From 9daa37762d928c7ee76ef877aa7ab2f3d7d783ec Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 20 Feb 2019 18:08:48 +0000 Subject: [PATCH] Add partial implementation of std::to_address() as llvm::to_address() Summary: Following on from the review for D58088, this patch provides the prerequisite to_address() implementation that's needed to have pointer_iterator support unique_ptr. The late bound return should be removed once we move to C++14 to better align with the C++20 declaration. Also, this implementation can be removed once we move to C++20 where it's defined as std::to_addres() The std::pointer_traits<>::to_address(p) variations of these overloads has not been implemented. Reviewers: dblaikie, paquette Reviewed By: dblaikie Subscribers: dexonsmith, kristina, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58421 llvm-svn: 354491 --- include/llvm/ADT/STLExtras.h | 13 +++++++++++++ unittests/ADT/STLExtrasTest.cpp | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 9a891d193e6..abc23b71d51 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -1576,6 +1576,19 @@ bool hasNItemsOrMore( return true; } +/// Returns a raw pointer that represents the same address as the argument. +/// +/// The late bound return should be removed once we move to C++14 to better +/// align with the C++20 declaration. Also, this implementation can be removed +/// once we move to C++20 where it's defined as std::to_addres() +/// +/// The std::pointer_traits<>::to_address(p) variations of these overloads has +/// not been implemented. +template auto to_address(const Ptr &P) -> decltype(P.operator->()) { + return P.operator->(); +} +template constexpr T *to_address(T *P) { return P; } + } // end namespace llvm #endif // LLVM_ADT_STLEXTRAS_H diff --git a/unittests/ADT/STLExtrasTest.cpp b/unittests/ADT/STLExtrasTest.cpp index 1db1d58870d..26196fb27ea 100644 --- a/unittests/ADT/STLExtrasTest.cpp +++ b/unittests/ADT/STLExtrasTest.cpp @@ -446,4 +446,27 @@ TEST(STLExtrasTest, splat) { EXPECT_FALSE(is_splat(V)); } +TEST(STLExtrasTest, to_address) { + int *V1 = new int; + EXPECT_EQ(V1, to_address(V1)); + + // Check fancy pointer overload for unique_ptr + std::unique_ptr V2 = make_unique(0); + EXPECT_EQ(V2.get(), to_address(V2)); + + V2.reset(V1); + EXPECT_EQ(V1, to_address(V2)); + V2.release(); + + // Check fancy pointer overload for shared_ptr + std::shared_ptr V3 = std::make_shared(0); + std::shared_ptr V4 = V3; + EXPECT_EQ(V3.get(), V4.get()); + EXPECT_EQ(V3.get(), to_address(V3)); + EXPECT_EQ(V4.get(), to_address(V4)); + + V3.reset(V1); + EXPECT_EQ(V1, to_address(V3)); +} + } // namespace