]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/experimental/propagate_const
Merge libc++ r291274, and update the library Makefile.
[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   using _VSTD::swap;
467   swap(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
468 }
469
470 template <class _Tp>
471 _LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT
472 {
473   return __pt.__t_;
474 }
475
476 template <class _Tp>
477 _LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT
478 {
479   return __pt.__t_;
480 }
481
482 _LIBCPP_END_NAMESPACE_LFTS_V2
483
484 _LIBCPP_BEGIN_NAMESPACE_STD
485
486 template <class _Tp>
487 struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
488 {
489   typedef size_t result_type;
490   typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
491
492   size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
493   {
494     return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
495   }
496 };
497
498 template <class _Tp>
499 struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
500 {
501   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
502   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
503
504   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
505       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
506   {
507     return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
508   }
509 };
510
511 template <class _Tp>
512 struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
513 {
514   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
515   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
516
517   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
518       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
519   {
520     return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
521   }
522 };
523
524 template <class _Tp>
525 struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
526 {
527   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
528   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
529
530   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
531       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
532   {
533     return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
534   }
535 };
536
537 template <class _Tp>
538 struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
539 {
540   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
541   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
542
543   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
544       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
545   {
546     return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
547   }
548 };
549
550 template <class _Tp>
551 struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
552 {
553   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
554   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
555
556   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
557       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
558   {
559     return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
560   }
561 };
562
563 template <class _Tp>
564 struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
565 {
566   typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
567   typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
568
569   bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
570       const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
571   {
572     return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
573   }
574 };
575
576 _LIBCPP_END_NAMESPACE_STD
577
578 #endif // _LIBCPP_STD_VER > 11
579 #endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
580