Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

216 lines
6.6KB

  1. // Pointer Traits -*- C++ -*-
  2. // Copyright (C) 2011-2020 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file bits/ptr_traits.h
  21. * This is an internal header file, included by other library headers.
  22. * Do not attempt to use it directly. @headername{memory}
  23. */
  24. #ifndef _PTR_TRAITS_H
  25. #define _PTR_TRAITS_H 1
  26. #if __cplusplus >= 201103L
  27. #include <bits/move.h>
  28. #if __cplusplus > 201703L
  29. #define __cpp_lib_constexpr_memory 201811L
  30. namespace __gnu_debug { struct _Safe_iterator_base; }
  31. #endif
  32. namespace std _GLIBCXX_VISIBILITY(default)
  33. {
  34. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  35. class __undefined;
  36. // Given Template<T, ...> return T, otherwise invalid.
  37. template<typename _Tp>
  38. struct __get_first_arg
  39. { using type = __undefined; };
  40. template<template<typename, typename...> class _Template, typename _Tp,
  41. typename... _Types>
  42. struct __get_first_arg<_Template<_Tp, _Types...>>
  43. { using type = _Tp; };
  44. template<typename _Tp>
  45. using __get_first_arg_t = typename __get_first_arg<_Tp>::type;
  46. // Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
  47. template<typename _Tp, typename _Up>
  48. struct __replace_first_arg
  49. { };
  50. template<template<typename, typename...> class _Template, typename _Up,
  51. typename _Tp, typename... _Types>
  52. struct __replace_first_arg<_Template<_Tp, _Types...>, _Up>
  53. { using type = _Template<_Up, _Types...>; };
  54. template<typename _Tp, typename _Up>
  55. using __replace_first_arg_t = typename __replace_first_arg<_Tp, _Up>::type;
  56. template<typename _Tp>
  57. using __make_not_void
  58. = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;
  59. /**
  60. * @brief Uniform interface to all pointer-like types
  61. * @ingroup pointer_abstractions
  62. */
  63. template<typename _Ptr>
  64. struct pointer_traits
  65. {
  66. private:
  67. template<typename _Tp>
  68. using __element_type = typename _Tp::element_type;
  69. template<typename _Tp>
  70. using __difference_type = typename _Tp::difference_type;
  71. template<typename _Tp, typename _Up, typename = void>
  72. struct __rebind : __replace_first_arg<_Tp, _Up> { };
  73. template<typename _Tp, typename _Up>
  74. struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
  75. { using type = typename _Tp::template rebind<_Up>; };
  76. public:
  77. /// The pointer type.
  78. using pointer = _Ptr;
  79. /// The type pointed to.
  80. using element_type
  81. = __detected_or_t<__get_first_arg_t<_Ptr>, __element_type, _Ptr>;
  82. /// The type used to represent the difference between two pointers.
  83. using difference_type
  84. = __detected_or_t<ptrdiff_t, __difference_type, _Ptr>;
  85. /// A pointer to a different type.
  86. template<typename _Up>
  87. using rebind = typename __rebind<_Ptr, _Up>::type;
  88. static _Ptr
  89. pointer_to(__make_not_void<element_type>& __e)
  90. { return _Ptr::pointer_to(__e); }
  91. static_assert(!is_same<element_type, __undefined>::value,
  92. "pointer type defines element_type or is like SomePointer<T, Args>");
  93. };
  94. /**
  95. * @brief Partial specialization for built-in pointers.
  96. * @ingroup pointer_abstractions
  97. */
  98. template<typename _Tp>
  99. struct pointer_traits<_Tp*>
  100. {
  101. /// The pointer type
  102. typedef _Tp* pointer;
  103. /// The type pointed to
  104. typedef _Tp element_type;
  105. /// Type used to represent the difference between two pointers
  106. typedef ptrdiff_t difference_type;
  107. template<typename _Up>
  108. using rebind = _Up*;
  109. /**
  110. * @brief Obtain a pointer to an object
  111. * @param __r A reference to an object of type @c element_type
  112. * @return @c addressof(__r)
  113. */
  114. static _GLIBCXX20_CONSTEXPR pointer
  115. pointer_to(__make_not_void<element_type>& __r) noexcept
  116. { return std::addressof(__r); }
  117. };
  118. /// Convenience alias for rebinding pointers.
  119. template<typename _Ptr, typename _Tp>
  120. using __ptr_rebind = typename pointer_traits<_Ptr>::template rebind<_Tp>;
  121. template<typename _Tp>
  122. constexpr _Tp*
  123. __to_address(_Tp* __ptr) noexcept
  124. {
  125. static_assert(!std::is_function<_Tp>::value, "not a function pointer");
  126. return __ptr;
  127. }
  128. #if __cplusplus <= 201703L
  129. template<typename _Ptr>
  130. constexpr typename std::pointer_traits<_Ptr>::element_type*
  131. __to_address(const _Ptr& __ptr)
  132. { return std::__to_address(__ptr.operator->()); }
  133. #else
  134. template<typename _Ptr>
  135. constexpr auto
  136. __to_address(const _Ptr& __ptr) noexcept
  137. -> decltype(std::pointer_traits<_Ptr>::to_address(__ptr))
  138. { return std::pointer_traits<_Ptr>::to_address(__ptr); }
  139. template<typename _Ptr, typename... _None>
  140. constexpr auto
  141. __to_address(const _Ptr& __ptr, _None...) noexcept
  142. {
  143. if constexpr (is_base_of_v<__gnu_debug::_Safe_iterator_base, _Ptr>)
  144. return std::__to_address(__ptr.base().operator->());
  145. else
  146. return std::__to_address(__ptr.operator->());
  147. }
  148. #define __cpp_lib_to_address 201711L
  149. /**
  150. * @brief Obtain address referenced by a pointer to an object
  151. * @param __ptr A pointer to an object
  152. * @return @c __ptr
  153. * @ingroup pointer_abstractions
  154. */
  155. template<typename _Tp>
  156. constexpr _Tp*
  157. to_address(_Tp* __ptr) noexcept
  158. { return std::__to_address(__ptr); }
  159. /**
  160. * @brief Obtain address referenced by a pointer to an object
  161. * @param __ptr A pointer to an object
  162. * @return @c pointer_traits<_Ptr>::to_address(__ptr) if that expression is
  163. well-formed, otherwise @c to_address(__ptr.operator->())
  164. * @ingroup pointer_abstractions
  165. */
  166. template<typename _Ptr>
  167. constexpr auto
  168. to_address(const _Ptr& __ptr) noexcept
  169. { return std::__to_address(__ptr); }
  170. #endif // C++2a
  171. _GLIBCXX_END_NAMESPACE_VERSION
  172. } // namespace std
  173. #endif
  174. #endif