brintos

brintos / llvm-project-archived public Read only

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