brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · f6df5db Raw
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