[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / include / __memory / pointer_traits.h
blob07bb6d437d7ec625b630de35ad7788105ad496dd
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___MEMORY_POINTER_TRAITS_H
11 #define _LIBCPP___MEMORY_POINTER_TRAITS_H
13 #include <__config>
14 #include <__memory/addressof.h>
15 #include <type_traits>
17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18 #pragma GCC system_header
19 #endif
21 _LIBCPP_BEGIN_NAMESPACE_STD
23 template <class _Tp, class = void>
24 struct __has_element_type : false_type {};
26 template <class _Tp>
27 struct __has_element_type<_Tp,
28 typename __void_t<typename _Tp::element_type>::type> : true_type {};
30 template <class _Ptr, bool = __has_element_type<_Ptr>::value>
31 struct __pointer_traits_element_type;
33 template <class _Ptr>
34 struct __pointer_traits_element_type<_Ptr, true>
36 typedef _LIBCPP_NODEBUG typename _Ptr::element_type type;
39 template <template <class, class...> class _Sp, class _Tp, class ..._Args>
40 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
42 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::element_type type;
45 template <template <class, class...> class _Sp, class _Tp, class ..._Args>
46 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
48 typedef _LIBCPP_NODEBUG _Tp type;
51 template <class _Tp, class = void>
52 struct __has_difference_type : false_type {};
54 template <class _Tp>
55 struct __has_difference_type<_Tp,
56 typename __void_t<typename _Tp::difference_type>::type> : true_type {};
58 template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
59 struct __pointer_traits_difference_type
61 typedef _LIBCPP_NODEBUG ptrdiff_t type;
64 template <class _Ptr>
65 struct __pointer_traits_difference_type<_Ptr, true>
67 typedef _LIBCPP_NODEBUG typename _Ptr::difference_type type;
70 template <class _Tp, class _Up>
71 struct __has_rebind
73 private:
74 struct __two {char __lx; char __lxx;};
75 template <class _Xp> static __two __test(...);
76 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
77 template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
78 _LIBCPP_SUPPRESS_DEPRECATED_POP
79 public:
80 static const bool value = sizeof(__test<_Tp>(0)) == 1;
83 template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
84 struct __pointer_traits_rebind
86 #ifndef _LIBCPP_CXX03_LANG
87 typedef _LIBCPP_NODEBUG typename _Tp::template rebind<_Up> type;
88 #else
89 typedef _LIBCPP_NODEBUG typename _Tp::template rebind<_Up>::other type;
90 #endif
93 template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
94 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
96 #ifndef _LIBCPP_CXX03_LANG
97 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
98 #else
99 typedef _LIBCPP_NODEBUG typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
100 #endif
103 template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
104 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
106 typedef _Sp<_Up, _Args...> type;
109 template <class _Ptr>
110 struct _LIBCPP_TEMPLATE_VIS pointer_traits
112 typedef _Ptr pointer;
113 typedef typename __pointer_traits_element_type<pointer>::type element_type;
114 typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
116 #ifndef _LIBCPP_CXX03_LANG
117 template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
118 #else
119 template <class _Up> struct rebind
120 {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
121 #endif // _LIBCPP_CXX03_LANG
123 private:
124 struct __nat {};
125 public:
126 _LIBCPP_INLINE_VISIBILITY
127 static pointer pointer_to(typename conditional<is_void<element_type>::value,
128 __nat, element_type>::type& __r)
129 {return pointer::pointer_to(__r);}
132 template <class _Tp>
133 struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
135 typedef _Tp* pointer;
136 typedef _Tp element_type;
137 typedef ptrdiff_t difference_type;
139 #ifndef _LIBCPP_CXX03_LANG
140 template <class _Up> using rebind = _Up*;
141 #else
142 template <class _Up> struct rebind {typedef _Up* other;};
143 #endif
145 private:
146 struct __nat {};
147 public:
148 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
149 static pointer pointer_to(typename conditional<is_void<element_type>::value,
150 __nat, element_type>::type& __r) _NOEXCEPT
151 {return _VSTD::addressof(__r);}
154 template <class _From, class _To>
155 struct __rebind_pointer {
156 #ifndef _LIBCPP_CXX03_LANG
157 typedef typename pointer_traits<_From>::template rebind<_To> type;
158 #else
159 typedef typename pointer_traits<_From>::template rebind<_To>::other type;
160 #endif
163 // to_address
165 template <class _Pointer, class = void>
166 struct __to_address_helper;
168 template <class _Tp>
169 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
170 _Tp* __to_address(_Tp* __p) _NOEXCEPT {
171 static_assert(!is_function<_Tp>::value, "_Tp is a function type");
172 return __p;
175 // enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers
176 template <class _Pointer, class = __enable_if_t<
177 !is_pointer<_Pointer>::value && !is_array<_Pointer>::value && !is_function<_Pointer>::value
179 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
180 typename decay<decltype(__to_address_helper<_Pointer>::__call(declval<const _Pointer&>()))>::type
181 __to_address(const _Pointer& __p) _NOEXCEPT {
182 return __to_address_helper<_Pointer>::__call(__p);
185 template <class _Pointer, class>
186 struct __to_address_helper {
187 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
188 static decltype(_VSTD::__to_address(declval<const _Pointer&>().operator->()))
189 __call(const _Pointer& __p) _NOEXCEPT {
190 return _VSTD::__to_address(__p.operator->());
194 template <class _Pointer>
195 struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))> {
196 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
197 static decltype(pointer_traits<_Pointer>::to_address(declval<const _Pointer&>()))
198 __call(const _Pointer& __p) _NOEXCEPT {
199 return pointer_traits<_Pointer>::to_address(__p);
203 #if _LIBCPP_STD_VER > 17
204 template <class _Tp>
205 inline _LIBCPP_INLINE_VISIBILITY constexpr
206 auto to_address(_Tp *__p) noexcept {
207 return _VSTD::__to_address(__p);
210 template <class _Pointer>
211 inline _LIBCPP_INLINE_VISIBILITY constexpr
212 auto to_address(const _Pointer& __p) noexcept {
213 return _VSTD::__to_address(__p);
215 #endif
217 _LIBCPP_END_NAMESPACE_STD
219 #endif // _LIBCPP___MEMORY_POINTER_TRAITS_H