• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/*
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 <__assert> // all public C++ headers provide the assertion handler
111#include <__functional/operations.h>
112#include <__fwd/hash.h>
113#include <__type_traits/conditional.h>
114#include <__type_traits/decay.h>
115#include <__type_traits/enable_if.h>
116#include <__type_traits/is_array.h>
117#include <__type_traits/is_constructible.h>
118#include <__type_traits/is_convertible.h>
119#include <__type_traits/is_function.h>
120#include <__type_traits/is_pointer.h>
121#include <__type_traits/is_reference.h>
122#include <__type_traits/is_same.h>
123#include <__type_traits/is_swappable.h>
124#include <__type_traits/remove_cv.h>
125#include <__type_traits/remove_pointer.h>
126#include <__type_traits/remove_reference.h>
127#include <__utility/declval.h>
128#include <__utility/forward.h>
129#include <__utility/move.h>
130#include <__utility/swap.h>
131#include <cstddef>
132#include <experimental/__config>
133
134#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
135#  pragma GCC system_header
136#endif
137
138#if _LIBCPP_STD_VER >= 14
139
140_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
141
142template <class _Tp>
143class propagate_const;
144
145template <class _Up>
146inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
147const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
148
149template <class _Up>
150inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
151_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
152
153template <class _Tp>
154class propagate_const
155{
156public:
157  typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
158
159  static_assert(!is_array<_Tp>::value,
160      "Instantiation of propagate_const with an array type is ill-formed.");
161  static_assert(!is_reference<_Tp>::value,
162      "Instantiation of propagate_const with a reference type is ill-formed.");
163  static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value),
164      "Instantiation of propagate_const with a function-pointer type is ill-formed.");
165  static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value),
166      "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed.");
167
168private:
169  template <class _Up>
170  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
171  {
172    return __u;
173  }
174
175  template <class _Up>
176  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
177  {
178    return __get_pointer(__u.get());
179  }
180
181  template <class _Up>
182  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
183  {
184    return __u;
185  }
186
187  template <class _Up>
188  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
189  {
190    return __get_pointer(__u.get());
191  }
192
193  template <class _Up>
194  struct __is_propagate_const : false_type
195  {
196  };
197
198  template <class _Up>
199  struct __is_propagate_const<propagate_const<_Up>> : true_type
200  {
201  };
202
203  _Tp __t_;
204
205public:
206
207  template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
208  template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
209
210  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default;
211
212  propagate_const(const propagate_const&) = delete;
213
214  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
215
216  template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
217                                 is_constructible<_Tp, _Up&&>::value,bool> = true>
218  explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
219      : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
220  {
221  }
222
223  template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
224                                 is_constructible<_Tp, _Up&&>::value,bool> = false>
225  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
226      : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
227  {
228  }
229
230  template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
231                                 is_constructible<_Tp, _Up&&>::value &&
232                                 !__is_propagate_const<decay_t<_Up>>::value,bool> = true>
233  explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
234      : __t_(std::forward<_Up>(__u))
235  {
236  }
237
238  template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
239                                 is_constructible<_Tp, _Up&&>::value &&
240                                 !__is_propagate_const<decay_t<_Up>>::value,bool> = false>
241  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
242      : __t_(std::forward<_Up>(__u))
243  {
244  }
245
246  propagate_const& operator=(const propagate_const&) = delete;
247
248  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
249
250  template <class _Up>
251  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
252  {
253    __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
254    return *this;
255  }
256
257  template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
258  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
259  {
260    __t_ = std::forward<_Up>(__u);
261    return *this;
262  }
263
264  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const
265  {
266    return __get_pointer(__t_);
267  }
268
269  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get()
270  {
271    return __get_pointer(__t_);
272  }
273
274  _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const
275  {
276    return get() != nullptr;
277  }
278
279  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const
280  {
281    return get();
282  }
283
284  template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible<
285                                  const _Tp_, const element_type *>::value>>
286  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const {
287    return get();
288  }
289
290  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const
291  {
292    return *get();
293  }
294
295  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->()
296  {
297    return get();
298  }
299
300  template <class _Tp_ = _Tp, class _Up = enable_if_t<
301                                  is_convertible<_Tp_, element_type *>::value>>
302  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() {
303    return get();
304  }
305
306  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*()
307  {
308    return *get();
309  }
310
311  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt)
312      _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
313    using _VSTD::swap;
314    swap(__t_, __pt.__t_);
315  }
316};
317
318
319template <class _Tp>
320_LIBCPP_INLINE_VISIBILITY
321_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t)
322{
323  return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr;
324}
325
326template <class _Tp>
327_LIBCPP_INLINE_VISIBILITY
328_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt)
329{
330  return nullptr == _VSTD_LFTS_V2::get_underlying(__pt);
331}
332
333template <class _Tp>
334_LIBCPP_INLINE_VISIBILITY
335_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
336{
337  return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr;
338}
339
340template <class _Tp>
341_LIBCPP_INLINE_VISIBILITY
342_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt)
343{
344  return nullptr != _VSTD_LFTS_V2::get_underlying(__pt);
345}
346
347template <class _Tp, class _Up>
348_LIBCPP_INLINE_VISIBILITY
349_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt,
350                          const propagate_const<_Up>& __pu)
351{
352  return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu);
353}
354
355template <class _Tp, class _Up>
356_LIBCPP_INLINE_VISIBILITY
357_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt,
358                          const propagate_const<_Up>& __pu)
359{
360  return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu);
361}
362
363template <class _Tp, class _Up>
364_LIBCPP_INLINE_VISIBILITY
365_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt,
366                         const propagate_const<_Up>& __pu)
367{
368  return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu);
369}
370
371template <class _Tp, class _Up>
372_LIBCPP_INLINE_VISIBILITY
373_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt,
374                         const propagate_const<_Up>& __pu)
375{
376  return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu);
377}
378
379template <class _Tp, class _Up>
380_LIBCPP_INLINE_VISIBILITY
381_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt,
382                          const propagate_const<_Up>& __pu)
383{
384  return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu);
385}
386
387template <class _Tp, class _Up>
388_LIBCPP_INLINE_VISIBILITY
389_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt,
390                          const propagate_const<_Up>& __pu)
391{
392  return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu);
393}
394
395template <class _Tp, class _Up>
396_LIBCPP_INLINE_VISIBILITY
397_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
398{
399  return _VSTD_LFTS_V2::get_underlying(__pt) == __u;
400}
401
402template <class _Tp, class _Up>
403_LIBCPP_INLINE_VISIBILITY
404_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
405{
406  return _VSTD_LFTS_V2::get_underlying(__pt) != __u;
407}
408
409template <class _Tp, class _Up>
410_LIBCPP_INLINE_VISIBILITY
411_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
412{
413  return _VSTD_LFTS_V2::get_underlying(__pt) < __u;
414}
415
416template <class _Tp, class _Up>
417_LIBCPP_INLINE_VISIBILITY
418_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
419{
420  return _VSTD_LFTS_V2::get_underlying(__pt) > __u;
421}
422
423template <class _Tp, class _Up>
424_LIBCPP_INLINE_VISIBILITY
425_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
426{
427  return _VSTD_LFTS_V2::get_underlying(__pt) <= __u;
428}
429
430template <class _Tp, class _Up>
431_LIBCPP_INLINE_VISIBILITY
432_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
433{
434  return _VSTD_LFTS_V2::get_underlying(__pt) >= __u;
435}
436
437
438template <class _Tp, class _Up>
439_LIBCPP_INLINE_VISIBILITY
440_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
441{
442  return __t == _VSTD_LFTS_V2::get_underlying(__pu);
443}
444
445template <class _Tp, class _Up>
446_LIBCPP_INLINE_VISIBILITY
447_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
448{
449  return __t != _VSTD_LFTS_V2::get_underlying(__pu);
450}
451
452template <class _Tp, class _Up>
453_LIBCPP_INLINE_VISIBILITY
454_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
455{
456  return __t < _VSTD_LFTS_V2::get_underlying(__pu);
457}
458
459template <class _Tp, class _Up>
460_LIBCPP_INLINE_VISIBILITY
461_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
462{
463  return __t > _VSTD_LFTS_V2::get_underlying(__pu);
464}
465
466template <class _Tp, class _Up>
467_LIBCPP_INLINE_VISIBILITY
468_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
469{
470  return __t <= _VSTD_LFTS_V2::get_underlying(__pu);
471}
472
473template <class _Tp, class _Up>
474_LIBCPP_INLINE_VISIBILITY
475_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
476{
477  return __t >= _VSTD_LFTS_V2::get_underlying(__pu);
478}
479
480template <class _Tp>
481_LIBCPP_INLINE_VISIBILITY
482_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
483{
484  __pc1.swap(__pc2);
485}
486
487template <class _Tp>
488_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT
489{
490  return __pt.__t_;
491}
492
493template <class _Tp>
494_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT
495{
496  return __pt.__t_;
497}
498
499_LIBCPP_END_NAMESPACE_LFTS_V2
500
501_LIBCPP_BEGIN_NAMESPACE_STD
502
503template <class _Tp>
504struct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
505{
506  typedef size_t result_type;
507  typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
508
509  _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
510  {
511    return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
512  }
513};
514
515template <class _Tp>
516struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
517{
518  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
519  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
520
521  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
522      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
523  {
524    return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
525  }
526};
527
528template <class _Tp>
529struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
530{
531  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
532  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
533
534  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
535      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
536  {
537    return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
538  }
539};
540
541template <class _Tp>
542struct less<experimental::fundamentals_v2::propagate_const<_Tp>>
543{
544  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
545  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
546
547  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
548      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
549  {
550    return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
551  }
552};
553
554template <class _Tp>
555struct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
556{
557  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
558  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
559
560  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
561      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
562  {
563    return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
564  }
565};
566
567template <class _Tp>
568struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
569{
570  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
571  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
572
573  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
574      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
575  {
576    return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
577  }
578};
579
580template <class _Tp>
581struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
582{
583  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
584  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
585
586  _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
587      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
588  {
589    return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
590  }
591};
592
593_LIBCPP_END_NAMESPACE_STD
594
595#endif // _LIBCPP_STD_VER >= 14
596
597#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
598#  include <type_traits>
599#endif
600
601#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
602