Home | History | Annotate | Download | only in experimental
      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 
    581