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