You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
5.9KB

  1. // <experimental/memory> -*- C++ -*-
  2. // Copyright (C) 2015-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 experimental/memory
  21. * This is a TS C++ Library header.
  22. * @ingroup libfund-ts
  23. */
  24. //
  25. // N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2
  26. //
  27. #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY
  28. #define _GLIBCXX_EXPERIMENTAL_MEMORY 1
  29. #pragma GCC system_header
  30. #if __cplusplus >= 201402L
  31. #include <memory>
  32. #include <type_traits>
  33. #include <utility>
  34. #include <experimental/bits/shared_ptr.h>
  35. #include <bits/functional_hash.h>
  36. namespace std _GLIBCXX_VISIBILITY(default)
  37. {
  38. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  39. namespace experimental
  40. {
  41. inline namespace fundamentals_v2
  42. {
  43. #define __cpp_lib_experimental_observer_ptr 201411
  44. template <typename _Tp>
  45. class observer_ptr
  46. {
  47. public:
  48. // publish our template parameter and variations thereof
  49. using element_type = _Tp;
  50. using __pointer = add_pointer_t<_Tp>; // exposition-only
  51. using __reference = add_lvalue_reference_t<_Tp>; // exposition-only
  52. // 3.2.2, observer_ptr constructors
  53. // default c'tor
  54. constexpr observer_ptr() noexcept
  55. : __t()
  56. { }
  57. // pointer-accepting c'tors
  58. constexpr observer_ptr(nullptr_t) noexcept
  59. : __t()
  60. { }
  61. constexpr explicit observer_ptr(__pointer __p) noexcept
  62. : __t(__p)
  63. { }
  64. // copying c'tors (in addition to compiler-generated copy c'tor)
  65. template <typename _Up,
  66. typename = typename enable_if<
  67. is_convertible<typename add_pointer<_Up>::type, __pointer
  68. >::value
  69. >::type>
  70. constexpr observer_ptr(observer_ptr<_Up> __p) noexcept
  71. : __t(__p.get())
  72. {
  73. }
  74. // 3.2.3, observer_ptr observers
  75. constexpr __pointer
  76. get() const noexcept
  77. {
  78. return __t;
  79. }
  80. constexpr __reference
  81. operator*() const
  82. {
  83. return *get();
  84. }
  85. constexpr __pointer
  86. operator->() const noexcept
  87. {
  88. return get();
  89. }
  90. constexpr explicit operator bool() const noexcept
  91. {
  92. return get() != nullptr;
  93. }
  94. // 3.2.4, observer_ptr conversions
  95. constexpr explicit operator __pointer() const noexcept
  96. {
  97. return get();
  98. }
  99. // 3.2.5, observer_ptr modifiers
  100. constexpr __pointer
  101. release() noexcept
  102. {
  103. __pointer __tmp = get();
  104. reset();
  105. return __tmp;
  106. }
  107. constexpr void
  108. reset(__pointer __p = nullptr) noexcept
  109. {
  110. __t = __p;
  111. }
  112. constexpr void
  113. swap(observer_ptr& __p) noexcept
  114. {
  115. std::swap(__t, __p.__t);
  116. }
  117. private:
  118. __pointer __t;
  119. }; // observer_ptr<>
  120. template<typename _Tp>
  121. void
  122. swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
  123. {
  124. __p1.swap(__p2);
  125. }
  126. template<typename _Tp>
  127. observer_ptr<_Tp>
  128. make_observer(_Tp* __p) noexcept
  129. {
  130. return observer_ptr<_Tp>(__p);
  131. }
  132. template<typename _Tp, typename _Up>
  133. bool
  134. operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  135. {
  136. return __p1.get() == __p2.get();
  137. }
  138. template<typename _Tp, typename _Up>
  139. bool
  140. operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  141. {
  142. return !(__p1 == __p2);
  143. }
  144. template<typename _Tp>
  145. bool
  146. operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
  147. {
  148. return !__p;
  149. }
  150. template<typename _Tp>
  151. bool
  152. operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
  153. {
  154. return !__p;
  155. }
  156. template<typename _Tp>
  157. bool
  158. operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept
  159. {
  160. return bool(__p);
  161. }
  162. template<typename _Tp>
  163. bool
  164. operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
  165. {
  166. return bool(__p);
  167. }
  168. template<typename _Tp, typename _Up>
  169. bool
  170. operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  171. {
  172. return std::less<typename common_type<typename add_pointer<_Tp>::type,
  173. typename add_pointer<_Up>::type
  174. >::type
  175. >{}(__p1.get(), __p2.get());
  176. }
  177. template<typename _Tp, typename _Up>
  178. bool
  179. operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  180. {
  181. return __p2 < __p1;
  182. }
  183. template<typename _Tp, typename _Up>
  184. bool
  185. operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  186. {
  187. return !(__p2 < __p1);
  188. }
  189. template<typename _Tp, typename _Up>
  190. bool
  191. operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
  192. {
  193. return !(__p1 < __p2);
  194. }
  195. } // namespace fundamentals_v2
  196. } // namespace experimental
  197. template <typename _Tp>
  198. struct hash<experimental::observer_ptr<_Tp>>
  199. {
  200. using result_type = size_t;
  201. using argument_type = experimental::observer_ptr<_Tp>;
  202. size_t
  203. operator()(const experimental::observer_ptr<_Tp>& __t) const
  204. noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get())))
  205. {
  206. return hash<typename add_pointer<_Tp>::type> {}(__t.get());
  207. }
  208. };
  209. _GLIBCXX_END_NAMESPACE_VERSION
  210. } // namespace std
  211. #endif // __cplusplus <= 201103L
  212. #endif // _GLIBCXX_EXPERIMENTAL_MEMORY