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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // <memory> |
10 | |
11 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
12 | |
13 | // template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; |
14 | // Should not require a specialization of pointer_traits for Ptr. |
15 | |
16 | #include <memory> |
17 | #include <type_traits> |
18 | #include <utility> |
19 | |
20 | struct IntPtr { |
21 | constexpr int* operator->() const { return ptr; } |
22 | |
23 | int* ptr; |
24 | }; |
25 | |
26 | template <class T, bool> |
27 | struct TemplatedPtr { |
28 | constexpr T* operator->() const { return ptr; } |
29 | |
30 | T* ptr; |
31 | }; |
32 | |
33 | template <template <class...> class Templ, class Ignore, class... Args> |
34 | struct is_valid_expansion_impl : std::false_type {}; |
35 | |
36 | template <template <class...> class Templ, class... Args> |
37 | struct is_valid_expansion_impl<Templ, decltype((void)Templ<Args...>{}, 0), Args...> : std::true_type {}; |
38 | |
39 | template <template <class...> class Templ, class... Args> |
40 | using is_valid_expansion = is_valid_expansion_impl<Templ, int, Args...>; |
41 | |
42 | template <class Ptr> |
43 | using TestToAddressCall = decltype(std::to_address(std::declval<Ptr>())); |
44 | |
45 | constexpr bool test() { |
46 | int i = 0; |
47 | |
48 | static_assert(std::to_address(IntPtr{nullptr}) == nullptr); |
49 | static_assert(std::to_address(IntPtr{&i}) == &i); |
50 | |
51 | bool b = false; |
52 | |
53 | static_assert(std::to_address(TemplatedPtr<bool, true>{nullptr}) == nullptr); |
54 | static_assert(std::to_address(TemplatedPtr<bool, true>{&b}) == &b); |
55 | |
56 | static_assert(!is_valid_expansion<TestToAddressCall, int>::value); |
57 | static_assert(is_valid_expansion<TestToAddressCall, IntPtr>::value); |
58 | static_assert(is_valid_expansion<TestToAddressCall, TemplatedPtr<bool, true>>::value); |
59 | |
60 | return true; |
61 | } |
62 | |
63 | int main(int, char**) { |
64 | static_assert(test()); |
65 | return 0; |
66 | } |
67 | |