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