File: to_address.pass.cpp

package info (click to toggle)
llvm-toolchain-13 1%3A13.0.1-6~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,418,812 kB
  • sloc: cpp: 5,290,827; ansic: 996,570; asm: 544,593; python: 188,212; objc: 72,027; lisp: 30,291; f90: 25,395; sh: 24,900; javascript: 9,780; pascal: 9,398; perl: 7,484; ml: 5,432; awk: 3,523; makefile: 2,892; xml: 953; cs: 573; fortran: 539
file content (149 lines) | stat: -rw-r--r-- 4,045 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <memory>

// UNSUPPORTED: c++03, c++11, c++14, c++17

// template <class T> constexpr T* to_address(T* p) noexcept;
// template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept;

#include <memory>
#include <cassert>
#include "test_macros.h"

struct Irrelevant;

struct P1 {
    using element_type = Irrelevant;
    constexpr explicit P1(int *p) : p_(p) { }
    constexpr int *operator->() const { return p_; }
    int *p_;
};

struct P2 {
    using element_type = Irrelevant;
    constexpr explicit P2(int *p) : p_(p) { }
    constexpr P1 operator->() const { return p_; }
    P1 p_;
};

struct P3 {
    constexpr explicit P3(int *p) : p_(p) { }
    int *p_;
};

template<>
struct std::pointer_traits<P3> {
    static constexpr int *to_address(const P3& p) { return p.p_; }
};

struct P4 {
    constexpr explicit P4(int *p) : p_(p) { }
    int *operator->() const;  // should never be called
    int *p_;
};

template<>
struct std::pointer_traits<P4> {
    static constexpr int *to_address(const P4& p) { return p.p_; }
};

struct P5 {
    using element_type = Irrelevant;
    int const* const& operator->() const;
};

struct P6 {};

template<>
struct std::pointer_traits<P6> {
    static int const* const& to_address(const P6&);
};

// Taken from a build breakage caused in Clang
namespace P7 {
    template<typename T> struct CanProxy;
    template<typename T>
    struct CanQual {
        CanProxy<T> operator->() const { return CanProxy<T>(); }
    };
    template<typename T>
    struct CanProxy {
        const CanProxy<T> *operator->() const { return nullptr; }
    };
} // namespace P7

namespace P8 {
    template<class T>
    struct FancyPtrA {
        using element_type = Irrelevant;
        T *p_;
        TEST_CONSTEXPR FancyPtrA(T *p) : p_(p) {}
        T& operator*() const;
        TEST_CONSTEXPR T *operator->() const { return p_; }
    };
    template<class T>
    struct FancyPtrB {
        T *p_;
        TEST_CONSTEXPR FancyPtrB(T *p) : p_(p) {}
        T& operator*() const;
    };
} // namespace P8

template<class T>
struct std::pointer_traits<P8::FancyPtrB<T> > {
    static TEST_CONSTEXPR T *to_address(const P8::FancyPtrB<T>& p) { return p.p_; }
};

struct Incomplete;
template<class T> struct Holder { T t; };


constexpr bool test() {
    int i = 0;
    ASSERT_NOEXCEPT(std::to_address(&i));
    assert(std::to_address(&i) == &i);
    P1 p1(&i);
    ASSERT_NOEXCEPT(std::to_address(p1));
    assert(std::to_address(p1) == &i);
    P2 p2(&i);
    ASSERT_NOEXCEPT(std::to_address(p2));
    assert(std::to_address(p2) == &i);
    P3 p3(&i);
    ASSERT_NOEXCEPT(std::to_address(p3));
    assert(std::to_address(p3) == &i);
    P4 p4(&i);
    ASSERT_NOEXCEPT(std::to_address(p4));
    assert(std::to_address(p4) == &i);

    ASSERT_SAME_TYPE(decltype(std::to_address(std::declval<int const*>())), int const*);
    ASSERT_SAME_TYPE(decltype(std::to_address(std::declval<P5>())), int const*);
    ASSERT_SAME_TYPE(decltype(std::to_address(std::declval<P6>())), int const*);

    P7::CanQual<int>* p7 = nullptr;
    assert(std::to_address(p7) == nullptr);
    ASSERT_SAME_TYPE(decltype(std::to_address(p7)), P7::CanQual<int>*);

    Holder<Incomplete> *p8_nil = nullptr;  // for C++03 compatibility
    P8::FancyPtrA<Holder<Incomplete> > p8a = p8_nil;
    assert(std::to_address(p8a) == p8_nil);
    ASSERT_SAME_TYPE(decltype(std::to_address(p8a)), decltype(p8_nil));

    P8::FancyPtrB<Holder<Incomplete> > p8b = p8_nil;
    assert(std::to_address(p8b) == p8_nil);
    ASSERT_SAME_TYPE(decltype(std::to_address(p8b)), decltype(p8_nil));

    return true;
}

int main(int, char**) {
    test();
    static_assert(test());
    return 0;
}