propagate_const 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
  10. #define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
  11. /*
  12. propagate_const synopsis
  13. namespace std { namespace experimental { inline namespace fundamentals_v2 {
  14. // [propagate_const]
  15. template <class T> class propagate_const;
  16. // [propagate_const.underlying], underlying pointer access
  17. constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept;
  18. constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept;
  19. // [propagate_const.relational], relational operators
  20. template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t);
  21. template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu);
  22. template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t);
  23. template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu);
  24. template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  25. template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  26. template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  27. template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  28. template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  29. template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
  30. template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u);
  31. template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u);
  32. template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u);
  33. template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u);
  34. template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u);
  35. template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u);
  36. template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu);
  37. template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu);
  38. template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu);
  39. template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu);
  40. template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu);
  41. template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu);
  42. // [propagate_const.algorithms], specialized algorithms
  43. template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below);
  44. template <class T>
  45. class propagate_const
  46. {
  47. public:
  48. typedef remove_reference_t<decltype(*declval<T&>())> element_type;
  49. // [propagate_const.ctor], constructors
  50. constexpr propagate_const() = default;
  51. propagate_const(const propagate_const& p) = delete;
  52. constexpr propagate_const(propagate_const&& p) = default;
  53. template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below
  54. template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below
  55. // [propagate_const.assignment], assignment
  56. propagate_const& operator=(const propagate_const& p) = delete;
  57. constexpr propagate_const& operator=(propagate_const&& p) = default;
  58. template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
  59. template <class U> constexpr propagate_const& operator=(U&& u); // see below
  60. // [propagate_const.const_observers], const observers
  61. explicit constexpr operator bool() const;
  62. constexpr const element_type* operator->() const;
  63. constexpr operator const element_type*() const; // Not always defined
  64. constexpr const element_type& operator*() const;
  65. constexpr const element_type* get() const;
  66. // [propagate_const.non_const_observers], non-const observers
  67. constexpr element_type* operator->();
  68. constexpr operator element_type*(); // Not always defined
  69. constexpr element_type& operator*();
  70. constexpr element_type* get();
  71. // [propagate_const.modifiers], modifiers
  72. constexpr void swap(propagate_const& pt) noexcept(see below)
  73. private:
  74. T t_; // exposition only
  75. };
  76. } // namespace fundamentals_v2
  77. } // namespace experimental
  78. // [propagate_const.hash], hash support
  79. template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>;
  80. // [propagate_const.comparison_function_objects], comparison function objects
  81. template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>;
  82. template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>;
  83. template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>;
  84. template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>;
  85. template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>;
  86. template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>;
  87. } // namespace std
  88. */
  89. #include <__assert> // all public C++ headers provide the assertion handler
  90. #include <__functional/operations.h>
  91. #include <__fwd/hash.h>
  92. #include <__type_traits/conditional.h>
  93. #include <__type_traits/decay.h>
  94. #include <__type_traits/enable_if.h>
  95. #include <__type_traits/is_array.h>
  96. #include <__type_traits/is_constructible.h>
  97. #include <__type_traits/is_convertible.h>
  98. #include <__type_traits/is_function.h>
  99. #include <__type_traits/is_pointer.h>
  100. #include <__type_traits/is_reference.h>
  101. #include <__type_traits/is_same.h>
  102. #include <__type_traits/is_swappable.h>
  103. #include <__type_traits/remove_cv.h>
  104. #include <__type_traits/remove_pointer.h>
  105. #include <__type_traits/remove_reference.h>
  106. #include <__utility/declval.h>
  107. #include <__utility/forward.h>
  108. #include <__utility/move.h>
  109. #include <__utility/swap.h>
  110. #include <cstddef>
  111. #include <experimental/__config>
  112. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  113. # pragma GCC system_header
  114. #endif
  115. _LIBCPP_PUSH_MACROS
  116. #include <__undef_macros>
  117. #if _LIBCPP_STD_VER >= 14
  118. _LIBCPP_BEGIN_NAMESPACE_LFTS_V2
  119. template <class _Tp>
  120. class propagate_const;
  121. template <class _Up>
  122. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  123. const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
  124. template <class _Up>
  125. inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
  126. _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
  127. template <class _Tp>
  128. class propagate_const
  129. {
  130. public:
  131. typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
  132. static_assert(!is_array<_Tp>::value,
  133. "Instantiation of propagate_const with an array type is ill-formed.");
  134. static_assert(!is_reference<_Tp>::value,
  135. "Instantiation of propagate_const with a reference type is ill-formed.");
  136. static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value),
  137. "Instantiation of propagate_const with a function-pointer type is ill-formed.");
  138. static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value),
  139. "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed.");
  140. private:
  141. template <class _Up>
  142. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
  143. {
  144. return __u;
  145. }
  146. template <class _Up>
  147. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
  148. {
  149. return __get_pointer(__u.get());
  150. }
  151. template <class _Up>
  152. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
  153. {
  154. return __u;
  155. }
  156. template <class _Up>
  157. static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
  158. {
  159. return __get_pointer(__u.get());
  160. }
  161. template <class _Up>
  162. struct __is_propagate_const : false_type
  163. {
  164. };
  165. template <class _Up>
  166. struct __is_propagate_const<propagate_const<_Up>> : true_type
  167. {
  168. };
  169. _Tp __t_;
  170. public:
  171. template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
  172. template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
  173. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default;
  174. propagate_const(const propagate_const&) = delete;
  175. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
  176. template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
  177. is_constructible<_Tp, _Up&&>::value,bool> = true>
  178. explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
  179. : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
  180. {
  181. }
  182. template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
  183. is_constructible<_Tp, _Up&&>::value,bool> = false>
  184. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
  185. : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
  186. {
  187. }
  188. template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
  189. is_constructible<_Tp, _Up&&>::value &&
  190. !__is_propagate_const<decay_t<_Up>>::value,bool> = true>
  191. explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
  192. : __t_(std::forward<_Up>(__u))
  193. {
  194. }
  195. template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
  196. is_constructible<_Tp, _Up&&>::value &&
  197. !__is_propagate_const<decay_t<_Up>>::value,bool> = false>
  198. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
  199. : __t_(std::forward<_Up>(__u))
  200. {
  201. }
  202. propagate_const& operator=(const propagate_const&) = delete;
  203. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
  204. template <class _Up>
  205. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
  206. {
  207. __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
  208. return *this;
  209. }
  210. template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
  211. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
  212. {
  213. __t_ = std::forward<_Up>(__u);
  214. return *this;
  215. }
  216. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const
  217. {
  218. return __get_pointer(__t_);
  219. }
  220. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get()
  221. {
  222. return __get_pointer(__t_);
  223. }
  224. _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const
  225. {
  226. return get() != nullptr;
  227. }
  228. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const
  229. {
  230. return get();
  231. }
  232. template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible<
  233. const _Dummy, const element_type *>::value>>
  234. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const {
  235. return get();
  236. }
  237. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const
  238. {
  239. return *get();
  240. }
  241. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->()
  242. {
  243. return get();
  244. }
  245. template <class _Dummy = _Tp, class _Up = enable_if_t<
  246. is_convertible<_Dummy, element_type *>::value>>
  247. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() {
  248. return get();
  249. }
  250. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*()
  251. {
  252. return *get();
  253. }
  254. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt)
  255. _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
  256. using _VSTD::swap;
  257. swap(__t_, __pt.__t_);
  258. }
  259. };
  260. template <class _Tp>
  261. _LIBCPP_INLINE_VISIBILITY
  262. _LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t)
  263. {
  264. return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr;
  265. }
  266. template <class _Tp>
  267. _LIBCPP_INLINE_VISIBILITY
  268. _LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt)
  269. {
  270. return nullptr == _VSTD_LFTS_V2::get_underlying(__pt);
  271. }
  272. template <class _Tp>
  273. _LIBCPP_INLINE_VISIBILITY
  274. _LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
  275. {
  276. return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr;
  277. }
  278. template <class _Tp>
  279. _LIBCPP_INLINE_VISIBILITY
  280. _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt)
  281. {
  282. return nullptr != _VSTD_LFTS_V2::get_underlying(__pt);
  283. }
  284. template <class _Tp, class _Up>
  285. _LIBCPP_INLINE_VISIBILITY
  286. _LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt,
  287. const propagate_const<_Up>& __pu)
  288. {
  289. return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu);
  290. }
  291. template <class _Tp, class _Up>
  292. _LIBCPP_INLINE_VISIBILITY
  293. _LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt,
  294. const propagate_const<_Up>& __pu)
  295. {
  296. return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu);
  297. }
  298. template <class _Tp, class _Up>
  299. _LIBCPP_INLINE_VISIBILITY
  300. _LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt,
  301. const propagate_const<_Up>& __pu)
  302. {
  303. return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu);
  304. }
  305. template <class _Tp, class _Up>
  306. _LIBCPP_INLINE_VISIBILITY
  307. _LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt,
  308. const propagate_const<_Up>& __pu)
  309. {
  310. return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu);
  311. }
  312. template <class _Tp, class _Up>
  313. _LIBCPP_INLINE_VISIBILITY
  314. _LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt,
  315. const propagate_const<_Up>& __pu)
  316. {
  317. return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu);
  318. }
  319. template <class _Tp, class _Up>
  320. _LIBCPP_INLINE_VISIBILITY
  321. _LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt,
  322. const propagate_const<_Up>& __pu)
  323. {
  324. return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu);
  325. }
  326. template <class _Tp, class _Up>
  327. _LIBCPP_INLINE_VISIBILITY
  328. _LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
  329. {
  330. return _VSTD_LFTS_V2::get_underlying(__pt) == __u;
  331. }
  332. template <class _Tp, class _Up>
  333. _LIBCPP_INLINE_VISIBILITY
  334. _LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
  335. {
  336. return _VSTD_LFTS_V2::get_underlying(__pt) != __u;
  337. }
  338. template <class _Tp, class _Up>
  339. _LIBCPP_INLINE_VISIBILITY
  340. _LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
  341. {
  342. return _VSTD_LFTS_V2::get_underlying(__pt) < __u;
  343. }
  344. template <class _Tp, class _Up>
  345. _LIBCPP_INLINE_VISIBILITY
  346. _LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
  347. {
  348. return _VSTD_LFTS_V2::get_underlying(__pt) > __u;
  349. }
  350. template <class _Tp, class _Up>
  351. _LIBCPP_INLINE_VISIBILITY
  352. _LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
  353. {
  354. return _VSTD_LFTS_V2::get_underlying(__pt) <= __u;
  355. }
  356. template <class _Tp, class _Up>
  357. _LIBCPP_INLINE_VISIBILITY
  358. _LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
  359. {
  360. return _VSTD_LFTS_V2::get_underlying(__pt) >= __u;
  361. }
  362. template <class _Tp, class _Up>
  363. _LIBCPP_INLINE_VISIBILITY
  364. _LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
  365. {
  366. return __t == _VSTD_LFTS_V2::get_underlying(__pu);
  367. }
  368. template <class _Tp, class _Up>
  369. _LIBCPP_INLINE_VISIBILITY
  370. _LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
  371. {
  372. return __t != _VSTD_LFTS_V2::get_underlying(__pu);
  373. }
  374. template <class _Tp, class _Up>
  375. _LIBCPP_INLINE_VISIBILITY
  376. _LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
  377. {
  378. return __t < _VSTD_LFTS_V2::get_underlying(__pu);
  379. }
  380. template <class _Tp, class _Up>
  381. _LIBCPP_INLINE_VISIBILITY
  382. _LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
  383. {
  384. return __t > _VSTD_LFTS_V2::get_underlying(__pu);
  385. }
  386. template <class _Tp, class _Up>
  387. _LIBCPP_INLINE_VISIBILITY
  388. _LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
  389. {
  390. return __t <= _VSTD_LFTS_V2::get_underlying(__pu);
  391. }
  392. template <class _Tp, class _Up>
  393. _LIBCPP_INLINE_VISIBILITY
  394. _LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
  395. {
  396. return __t >= _VSTD_LFTS_V2::get_underlying(__pu);
  397. }
  398. template <class _Tp>
  399. _LIBCPP_INLINE_VISIBILITY
  400. _LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
  401. {
  402. __pc1.swap(__pc2);
  403. }
  404. template <class _Tp>
  405. _LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT
  406. {
  407. return __pt.__t_;
  408. }
  409. template <class _Tp>
  410. _LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT
  411. {
  412. return __pt.__t_;
  413. }
  414. _LIBCPP_END_NAMESPACE_LFTS_V2
  415. _LIBCPP_BEGIN_NAMESPACE_STD
  416. template <class _Tp>
  417. struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
  418. {
  419. typedef size_t result_type;
  420. typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
  421. _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
  422. {
  423. return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
  424. }
  425. };
  426. template <class _Tp>
  427. struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
  428. {
  429. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  430. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  431. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  432. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  433. {
  434. return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  435. }
  436. };
  437. template <class _Tp>
  438. struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
  439. {
  440. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  441. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  442. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  443. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  444. {
  445. return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  446. }
  447. };
  448. template <class _Tp>
  449. struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
  450. {
  451. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  452. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  453. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  454. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  455. {
  456. return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  457. }
  458. };
  459. template <class _Tp>
  460. struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
  461. {
  462. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  463. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  464. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  465. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  466. {
  467. return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  468. }
  469. };
  470. template <class _Tp>
  471. struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
  472. {
  473. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  474. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  475. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  476. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  477. {
  478. return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  479. }
  480. };
  481. template <class _Tp>
  482. struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
  483. {
  484. typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
  485. typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
  486. _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
  487. const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
  488. {
  489. return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
  490. }
  491. };
  492. _LIBCPP_END_NAMESPACE_STD
  493. #endif // _LIBCPP_STD_VER >= 14
  494. _LIBCPP_POP_MACROS
  495. #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
  496. # include <type_traits>
  497. #endif
  498. #endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST