Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:56

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___MEMORY_POINTER_TRAITS_H
0011 #define _LIBCPP___MEMORY_POINTER_TRAITS_H
0012 
0013 #include <__config>
0014 #include <__cstddef/ptrdiff_t.h>
0015 #include <__memory/addressof.h>
0016 #include <__type_traits/conditional.h>
0017 #include <__type_traits/conjunction.h>
0018 #include <__type_traits/decay.h>
0019 #include <__type_traits/enable_if.h>
0020 #include <__type_traits/integral_constant.h>
0021 #include <__type_traits/is_class.h>
0022 #include <__type_traits/is_function.h>
0023 #include <__type_traits/is_void.h>
0024 #include <__type_traits/void_t.h>
0025 #include <__utility/declval.h>
0026 #include <__utility/forward.h>
0027 
0028 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0029 #  pragma GCC system_header
0030 #endif
0031 
0032 _LIBCPP_PUSH_MACROS
0033 #include <__undef_macros>
0034 
0035 _LIBCPP_BEGIN_NAMESPACE_STD
0036 
0037 // clang-format off
0038 #define _LIBCPP_CLASS_TRAITS_HAS_XXX(NAME, PROPERTY)                                                                   \
0039   template <class _Tp, class = void>                                                                                   \
0040   struct NAME : false_type {};                                                                                         \
0041   template <class _Tp>                                                                                                 \
0042   struct NAME<_Tp, __void_t<typename _Tp::PROPERTY> > : true_type {}
0043 // clang-format on
0044 
0045 _LIBCPP_CLASS_TRAITS_HAS_XXX(__has_pointer, pointer);
0046 _LIBCPP_CLASS_TRAITS_HAS_XXX(__has_element_type, element_type);
0047 
0048 template <class _Ptr, bool = __has_element_type<_Ptr>::value>
0049 struct __pointer_traits_element_type {};
0050 
0051 template <class _Ptr>
0052 struct __pointer_traits_element_type<_Ptr, true> {
0053   using type _LIBCPP_NODEBUG = typename _Ptr::element_type;
0054 };
0055 
0056 template <template <class, class...> class _Sp, class _Tp, class... _Args>
0057 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true> {
0058   using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::element_type;
0059 };
0060 
0061 template <template <class, class...> class _Sp, class _Tp, class... _Args>
0062 struct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false> {
0063   using type _LIBCPP_NODEBUG = _Tp;
0064 };
0065 
0066 template <class _Tp, class = void>
0067 struct __has_difference_type : false_type {};
0068 
0069 template <class _Tp>
0070 struct __has_difference_type<_Tp, __void_t<typename _Tp::difference_type> > : true_type {};
0071 
0072 template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
0073 struct __pointer_traits_difference_type {
0074   using type _LIBCPP_NODEBUG = ptrdiff_t;
0075 };
0076 
0077 template <class _Ptr>
0078 struct __pointer_traits_difference_type<_Ptr, true> {
0079   using type _LIBCPP_NODEBUG = typename _Ptr::difference_type;
0080 };
0081 
0082 template <class _Tp, class _Up>
0083 struct __has_rebind {
0084 private:
0085   template <class _Xp>
0086   static false_type __test(...);
0087   _LIBCPP_SUPPRESS_DEPRECATED_PUSH
0088   template <class _Xp>
0089   static true_type __test(typename _Xp::template rebind<_Up>* = 0);
0090   _LIBCPP_SUPPRESS_DEPRECATED_POP
0091 
0092 public:
0093   static const bool value = decltype(__test<_Tp>(0))::value;
0094 };
0095 
0096 template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
0097 struct __pointer_traits_rebind {
0098 #ifndef _LIBCPP_CXX03_LANG
0099   using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>;
0100 #else
0101   using type _LIBCPP_NODEBUG = typename _Tp::template rebind<_Up>::other;
0102 #endif
0103 };
0104 
0105 template <template <class, class...> class _Sp, class _Tp, class... _Args, class _Up>
0106 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true> {
0107 #ifndef _LIBCPP_CXX03_LANG
0108   using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::template rebind<_Up>;
0109 #else
0110   using type _LIBCPP_NODEBUG = typename _Sp<_Tp, _Args...>::template rebind<_Up>::other;
0111 #endif
0112 };
0113 
0114 template <template <class, class...> class _Sp, class _Tp, class... _Args, class _Up>
0115 struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false> {
0116   typedef _Sp<_Up, _Args...> type;
0117 };
0118 
0119 template <class _Ptr, class = void>
0120 struct __pointer_traits_impl {};
0121 
0122 template <class _Ptr>
0123 struct __pointer_traits_impl<_Ptr, __void_t<typename __pointer_traits_element_type<_Ptr>::type> > {
0124   typedef _Ptr pointer;
0125   typedef typename __pointer_traits_element_type<pointer>::type element_type;
0126   typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
0127 
0128 #ifndef _LIBCPP_CXX03_LANG
0129   template <class _Up>
0130   using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
0131 #else
0132   template <class _Up>
0133   struct rebind {
0134     typedef typename __pointer_traits_rebind<pointer, _Up>::type other;
0135   };
0136 #endif // _LIBCPP_CXX03_LANG
0137 
0138 private:
0139   struct __nat {};
0140 
0141 public:
0142   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
0143   pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) {
0144     return pointer::pointer_to(__r);
0145   }
0146 };
0147 
0148 template <class _Ptr>
0149 struct _LIBCPP_TEMPLATE_VIS pointer_traits : __pointer_traits_impl<_Ptr> {};
0150 
0151 template <class _Tp>
0152 struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*> {
0153   typedef _Tp* pointer;
0154   typedef _Tp element_type;
0155   typedef ptrdiff_t difference_type;
0156 
0157 #ifndef _LIBCPP_CXX03_LANG
0158   template <class _Up>
0159   using rebind = _Up*;
0160 #else
0161   template <class _Up>
0162   struct rebind {
0163     typedef _Up* other;
0164   };
0165 #endif
0166 
0167 private:
0168   struct __nat {};
0169 
0170 public:
0171   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static pointer
0172   pointer_to(__conditional_t<is_void<element_type>::value, __nat, element_type>& __r) _NOEXCEPT {
0173     return std::addressof(__r);
0174   }
0175 };
0176 
0177 #ifndef _LIBCPP_CXX03_LANG
0178 template <class _From, class _To>
0179 using __rebind_pointer_t _LIBCPP_NODEBUG = typename pointer_traits<_From>::template rebind<_To>;
0180 #else
0181 template <class _From, class _To>
0182 using __rebind_pointer_t _LIBCPP_NODEBUG = typename pointer_traits<_From>::template rebind<_To>::other;
0183 #endif
0184 
0185 // to_address
0186 
0187 template <class _Pointer, class = void>
0188 struct __to_address_helper;
0189 
0190 template <class _Tp>
0191 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __to_address(_Tp* __p) _NOEXCEPT {
0192   static_assert(!is_function<_Tp>::value, "_Tp is a function type");
0193   return __p;
0194 }
0195 
0196 template <class _Pointer, class = void>
0197 struct _HasToAddress : false_type {};
0198 
0199 template <class _Pointer>
0200 struct _HasToAddress<_Pointer, decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>())) >
0201     : true_type {};
0202 
0203 template <class _Pointer, class = void>
0204 struct _HasArrow : false_type {};
0205 
0206 template <class _Pointer>
0207 struct _HasArrow<_Pointer, decltype((void)std::declval<const _Pointer&>().operator->()) > : true_type {};
0208 
0209 template <class _Pointer>
0210 struct _IsFancyPointer {
0211   static const bool value = _HasArrow<_Pointer>::value || _HasToAddress<_Pointer>::value;
0212 };
0213 
0214 // enable_if is needed here to avoid instantiating checks for fancy pointers on raw pointers
0215 template <class _Pointer, __enable_if_t< _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value, int> = 0>
0216 _LIBCPP_HIDE_FROM_ABI
0217 _LIBCPP_CONSTEXPR __decay_t<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>
0218 __to_address(const _Pointer& __p) _NOEXCEPT {
0219   return __to_address_helper<_Pointer>::__call(__p);
0220 }
0221 
0222 template <class _Pointer, class>
0223 struct __to_address_helper {
0224   _LIBCPP_HIDE_FROM_ABI
0225   _LIBCPP_CONSTEXPR static decltype(std::__to_address(std::declval<const _Pointer&>().operator->()))
0226   __call(const _Pointer& __p) _NOEXCEPT {
0227     return std::__to_address(__p.operator->());
0228   }
0229 };
0230 
0231 template <class _Pointer>
0232 struct __to_address_helper<_Pointer,
0233                            decltype((void)pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))> {
0234   _LIBCPP_HIDE_FROM_ABI
0235   _LIBCPP_CONSTEXPR static decltype(pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()))
0236   __call(const _Pointer& __p) _NOEXCEPT {
0237     return pointer_traits<_Pointer>::to_address(__p);
0238   }
0239 };
0240 
0241 #if _LIBCPP_STD_VER >= 20
0242 template <class _Tp>
0243 inline _LIBCPP_HIDE_FROM_ABI constexpr auto to_address(_Tp* __p) noexcept {
0244   return std::__to_address(__p);
0245 }
0246 
0247 template <class _Pointer>
0248 inline _LIBCPP_HIDE_FROM_ABI constexpr auto
0249 to_address(const _Pointer& __p) noexcept -> decltype(std::__to_address(__p)) {
0250   return std::__to_address(__p);
0251 }
0252 #endif
0253 
0254 #if _LIBCPP_STD_VER >= 23
0255 
0256 template <class _Tp>
0257 struct __pointer_of {};
0258 
0259 template <class _Tp>
0260   requires(__has_pointer<_Tp>::value)
0261 struct __pointer_of<_Tp> {
0262   using type = typename _Tp::pointer;
0263 };
0264 
0265 template <class _Tp>
0266   requires(!__has_pointer<_Tp>::value && __has_element_type<_Tp>::value)
0267 struct __pointer_of<_Tp> {
0268   using type = typename _Tp::element_type*;
0269 };
0270 
0271 template <class _Tp>
0272   requires(!__has_pointer<_Tp>::value && !__has_element_type<_Tp>::value &&
0273            __has_element_type<pointer_traits<_Tp>>::value)
0274 struct __pointer_of<_Tp> {
0275   using type = typename pointer_traits<_Tp>::element_type*;
0276 };
0277 
0278 template <typename _Tp>
0279 using __pointer_of_t _LIBCPP_NODEBUG = typename __pointer_of<_Tp>::type;
0280 
0281 template <class _Tp, class _Up>
0282 struct __pointer_of_or {
0283   using type _LIBCPP_NODEBUG = _Up;
0284 };
0285 
0286 template <class _Tp, class _Up>
0287   requires requires { typename __pointer_of_t<_Tp>; }
0288 struct __pointer_of_or<_Tp, _Up> {
0289   using type _LIBCPP_NODEBUG = __pointer_of_t<_Tp>;
0290 };
0291 
0292 template <typename _Tp, typename _Up>
0293 using __pointer_of_or_t _LIBCPP_NODEBUG = typename __pointer_of_or<_Tp, _Up>::type;
0294 
0295 template <class _Smart>
0296 concept __resettable_smart_pointer = requires(_Smart __s) { __s.reset(); };
0297 
0298 template <class _Smart, class _Pointer, class... _Args>
0299 concept __resettable_smart_pointer_with_args = requires(_Smart __s, _Pointer __p, _Args... __args) {
0300   __s.reset(static_cast<__pointer_of_or_t<_Smart, _Pointer>>(__p), std::forward<_Args>(__args)...);
0301 };
0302 
0303 #endif
0304 
0305 _LIBCPP_END_NAMESPACE_STD
0306 
0307 _LIBCPP_POP_MACROS
0308 
0309 #endif // _LIBCPP___MEMORY_POINTER_TRAITS_H