158 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// <memory>10 11// template <class T> constexpr T* __to_address(T* p) noexcept;12// template <class Ptr> constexpr auto __to_address(const Ptr& p) noexcept;13 14#include <memory>15#include <cassert>16#include <utility>17 18#include "test_macros.h"19 20struct Irrelevant;21 22struct P1 {23 using element_type = Irrelevant;24 TEST_CONSTEXPR explicit P1(int *p) : p_(p) { }25 TEST_CONSTEXPR int *operator->() const { return p_; }26 int *p_;27};28 29struct P2 {30 using element_type = Irrelevant;31 TEST_CONSTEXPR explicit P2(int *p) : p_(p) { }32 TEST_CONSTEXPR P1 operator->() const { return p_; }33 P1 p_;34};35 36struct P3 {37 TEST_CONSTEXPR explicit P3(int *p) : p_(p) { }38 int *p_;39};40 41template<>42struct std::pointer_traits<P3> {43 static TEST_CONSTEXPR int *to_address(const P3& p) { return p.p_; }44};45 46struct P4 {47 TEST_CONSTEXPR explicit P4(int *p) : p_(p) { }48 int *operator->() const; // should never be called49 int *p_;50};51 52template<>53struct std::pointer_traits<P4> {54 static TEST_CONSTEXPR int *to_address(const P4& p) { return p.p_; }55};56 57struct P5 {58 using element_type = Irrelevant;59 int const* const& operator->() const;60};61 62struct P6 {};63 64template<>65struct std::pointer_traits<P6> {66 static int const* const& to_address(const P6&);67};68 69// Taken from a build breakage caused in Clang70namespace P7 {71 template<typename T> struct CanProxy;72 template<typename T>73 struct CanQual {74 CanProxy<T> operator->() const { return CanProxy<T>(); }75 };76 template<typename T>77 struct CanProxy {78 const CanProxy<T> *operator->() const { return nullptr; }79 };80} // namespace P781 82namespace P8 {83 template<class T>84 struct FancyPtrA {85 using element_type = Irrelevant;86 T *p_;87 TEST_CONSTEXPR FancyPtrA(T *p) : p_(p) {}88 T& operator*() const;89 TEST_CONSTEXPR T *operator->() const { return p_; }90 };91 template<class T>92 struct FancyPtrB {93 T *p_;94 TEST_CONSTEXPR FancyPtrB(T *p) : p_(p) {}95 T& operator*() const;96 };97} // namespace P898 99template<class T>100struct std::pointer_traits<P8::FancyPtrB<T> > {101 static TEST_CONSTEXPR T *to_address(const P8::FancyPtrB<T>& p) { return p.p_; }102};103 104struct Incomplete;105template<class T> struct Holder { T t; };106 107 108TEST_CONSTEXPR_CXX14 bool test() {109 int i = 0;110 ASSERT_NOEXCEPT(std::__to_address(&i));111 assert(std::__to_address(&i) == &i);112 P1 p1(&i);113 ASSERT_NOEXCEPT(std::__to_address(p1));114 assert(std::__to_address(p1) == &i);115 P2 p2(&i);116 ASSERT_NOEXCEPT(std::__to_address(p2));117 assert(std::__to_address(p2) == &i);118 P3 p3(&i);119 ASSERT_NOEXCEPT(std::__to_address(p3));120 assert(std::__to_address(p3) == &i);121 P4 p4(&i);122 ASSERT_NOEXCEPT(std::__to_address(p4));123 assert(std::__to_address(p4) == &i);124 125 ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<int const*>())), int const*);126 ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<P5>())), int const*);127 ASSERT_SAME_TYPE(decltype(std::__to_address(std::declval<P6>())), int const*);128 129 P7::CanQual<int>* p7 = nullptr;130 assert(std::__to_address(p7) == nullptr);131 ASSERT_SAME_TYPE(decltype(std::__to_address(p7)), P7::CanQual<int>*);132 133 Holder<Incomplete> *p8_nil = nullptr; // for C++03 compatibility134 P8::FancyPtrA<Holder<Incomplete> > p8a = p8_nil;135 assert(std::__to_address(p8a) == p8_nil);136 ASSERT_SAME_TYPE(decltype(std::__to_address(p8a)), decltype(p8_nil));137 138 P8::FancyPtrB<Holder<Incomplete> > p8b = p8_nil;139 assert(std::__to_address(p8b) == p8_nil);140 ASSERT_SAME_TYPE(decltype(std::__to_address(p8b)), decltype(p8_nil));141 142 int p9[2] = {};143 assert(std::__to_address(p9) == p9);144 ASSERT_SAME_TYPE(decltype(std::__to_address(p9)), int*);145 146 const int p10[2] = {};147 assert(std::__to_address(p10) == p10);148 ASSERT_SAME_TYPE(decltype(std::__to_address(p10)), const int*);149 150 return true;151}152 153int main(int, char**) {154 test();155 156 return 0;157}158