memory 5.9 KB

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