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& get_underlying(const propagate_const<T>& pt) noexcept; 23 constexpr T& 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::propagate_const<T>>; 97 98 // [propagate_const.comparison_function_objects], comparison function objects 99 template <class T> struct equal_to<experimental::propagate_const<T>>; 100 template <class T> struct not_equal_to<experimental::propagate_const<T>>; 101 template <class T> struct less<experimental::propagate_const<T>>; 102 template <class T> struct greater<experimental::propagate_const<T>>; 103 template <class T> struct less_equal<experimental::propagate_const<T>>; 104 template <class T> struct greater_equal<experimental::propagate_const<T>>; 105 106} // namespace std 107 108*/ 109 110#include <__functional/operations.h> 111#include <__fwd/functional.h> 112#include <__type_traits/conditional.h> 113#include <__type_traits/decay.h> 114#include <__type_traits/enable_if.h> 115#include <__type_traits/is_array.h> 116#include <__type_traits/is_constructible.h> 117#include <__type_traits/is_convertible.h> 118#include <__type_traits/is_function.h> 119#include <__type_traits/is_pointer.h> 120#include <__type_traits/is_reference.h> 121#include <__type_traits/is_same.h> 122#include <__type_traits/is_swappable.h> 123#include <__type_traits/remove_cv.h> 124#include <__type_traits/remove_pointer.h> 125#include <__type_traits/remove_reference.h> 126#include <__utility/declval.h> 127#include <__utility/forward.h> 128#include <__utility/move.h> 129#include <__utility/swap.h> 130#include <cstddef> 131#include <experimental/__config> 132 133#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 134# pragma GCC system_header 135#endif 136 137_LIBCPP_PUSH_MACROS 138#include <__undef_macros> 139 140#if _LIBCPP_STD_VER >= 14 141 142_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 143 144template <class _Tp> 145class propagate_const; 146 147template <class _Up> 148inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 149 150template <class _Up> 151inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 152 153template <class _Tp> 154class propagate_const { 155public: 156 typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type; 157 158 static_assert(!is_array<_Tp>::value, "Instantiation of propagate_const with an array type is ill-formed."); 159 static_assert(!is_reference<_Tp>::value, "Instantiation of propagate_const with a reference type is ill-formed."); 160 static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value), 161 "Instantiation of propagate_const with a function-pointer type is ill-formed."); 162 static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value), 163 "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 164 165private: 166 template <class _Up> 167 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) { 168 return __u; 169 } 170 171 template <class _Up> 172 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) { 173 return __get_pointer(__u.get()); 174 } 175 176 template <class _Up> 177 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) { 178 return __u; 179 } 180 181 template <class _Up> 182 static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) { 183 return __get_pointer(__u.get()); 184 } 185 186 template <class _Up> 187 struct __is_propagate_const : false_type {}; 188 189 template <class _Up> 190 struct __is_propagate_const<propagate_const<_Up>> : true_type {}; 191 192 _Tp __t_; 193 194public: 195 template <class _Up> 196 friend _LIBCPP_CONSTEXPR const _Up& 197 experimental::fundamentals_v2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 198 template <class _Up> 199 friend _LIBCPP_CONSTEXPR _Up& experimental::fundamentals_v2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 200 201 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default; 202 203 propagate_const(const propagate_const&) = delete; 204 205 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; 206 207 template <class _Up, 208 enable_if_t<!is_convertible<_Up, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = true> 209 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 210 : __t_(std::move(experimental::get_underlying(__pu))) {} 211 212 template <class _Up, 213 enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = false> 214 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 215 : __t_(std::move(experimental::get_underlying(__pu))) {} 216 217 template <class _Up, 218 enable_if_t<!is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value && 219 !__is_propagate_const<decay_t<_Up>>::value, 220 bool> = true> 221 explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {} 222 223 template <class _Up, 224 enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value && 225 !__is_propagate_const<decay_t<_Up>>::value, 226 bool> = false> 227 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {} 228 229 propagate_const& operator=(const propagate_const&) = delete; 230 231 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; 232 233 template <class _Up> 234 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) { 235 __t_ = std::move(experimental::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_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) { 241 __t_ = std::forward<_Up>(__u); 242 return *this; 243 } 244 245 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const { return __get_pointer(__t_); } 246 247 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get() { return __get_pointer(__t_); } 248 249 _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const { return get() != nullptr; } 250 251 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const { return get(); } 252 253 template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible< const _Dummy, const element_type*>::value>> 254 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type*() const { 255 return get(); 256 } 257 258 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const { return *get(); } 259 260 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->() { return get(); } 261 262 template <class _Dummy = _Tp, class _Up = enable_if_t< is_convertible<_Dummy, element_type*>::value>> 263 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type*() { 264 return get(); 265 } 266 267 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*() { return *get(); } 268 269 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) 270 _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { 271 using std::swap; 272 swap(__t_, __pt.__t_); 273 } 274}; 275 276template <class _Tp> 277_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) { 278 return experimental::get_underlying(__pt) == nullptr; 279} 280 281template <class _Tp> 282_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) { 283 return nullptr == experimental::get_underlying(__pt); 284} 285 286template <class _Tp> 287_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) { 288 return experimental::get_underlying(__pt) != nullptr; 289} 290 291template <class _Tp> 292_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) { 293 return nullptr != experimental::get_underlying(__pt); 294} 295 296template <class _Tp, class _Up> 297_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 298operator==(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 299 return experimental::get_underlying(__pt) == experimental::get_underlying(__pu); 300} 301 302template <class _Tp, class _Up> 303_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 304operator!=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 305 return experimental::get_underlying(__pt) != experimental::get_underlying(__pu); 306} 307 308template <class _Tp, class _Up> 309_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 310operator<(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 311 return experimental::get_underlying(__pt) < experimental::get_underlying(__pu); 312} 313 314template <class _Tp, class _Up> 315_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 316operator>(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 317 return experimental::get_underlying(__pt) > experimental::get_underlying(__pu); 318} 319 320template <class _Tp, class _Up> 321_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 322operator<=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 323 return experimental::get_underlying(__pt) <= experimental::get_underlying(__pu); 324} 325 326template <class _Tp, class _Up> 327_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool 328operator>=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 329 return experimental::get_underlying(__pt) >= experimental::get_underlying(__pu); 330} 331 332template <class _Tp, class _Up> 333_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) { 334 return experimental::get_underlying(__pt) == __u; 335} 336 337template <class _Tp, class _Up> 338_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) { 339 return experimental::get_underlying(__pt) != __u; 340} 341 342template <class _Tp, class _Up> 343_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) { 344 return experimental::get_underlying(__pt) < __u; 345} 346 347template <class _Tp, class _Up> 348_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) { 349 return experimental::get_underlying(__pt) > __u; 350} 351 352template <class _Tp, class _Up> 353_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) { 354 return experimental::get_underlying(__pt) <= __u; 355} 356 357template <class _Tp, class _Up> 358_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) { 359 return experimental::get_underlying(__pt) >= __u; 360} 361 362template <class _Tp, class _Up> 363_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) { 364 return __t == experimental::get_underlying(__pu); 365} 366 367template <class _Tp, class _Up> 368_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) { 369 return __t != experimental::get_underlying(__pu); 370} 371 372template <class _Tp, class _Up> 373_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) { 374 return __t < experimental::get_underlying(__pu); 375} 376 377template <class _Tp, class _Up> 378_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) { 379 return __t > experimental::get_underlying(__pu); 380} 381 382template <class _Tp, class _Up> 383_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) { 384 return __t <= experimental::get_underlying(__pu); 385} 386 387template <class _Tp, class _Up> 388_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) { 389 return __t >= experimental::get_underlying(__pu); 390} 391 392template <class _Tp> 393_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) 394 _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { 395 __pc1.swap(__pc2); 396} 397 398template <class _Tp> 399_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT { 400 return __pt.__t_; 401} 402 403template <class _Tp> 404_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT { 405 return __pt.__t_; 406} 407 408_LIBCPP_END_NAMESPACE_LFTS_V2 409 410_LIBCPP_BEGIN_NAMESPACE_STD 411 412template <class _Tp> 413struct hash<experimental::propagate_const<_Tp>> { 414 typedef size_t result_type; 415 typedef experimental::propagate_const<_Tp> argument_type; 416 417 _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::propagate_const<_Tp>& __pc1) const { 418 return std::hash<_Tp>()(experimental::get_underlying(__pc1)); 419 } 420}; 421 422template <class _Tp> 423struct equal_to<experimental::propagate_const<_Tp>> { 424 typedef experimental::propagate_const<_Tp> first_argument_type; 425 typedef experimental::propagate_const<_Tp> second_argument_type; 426 427 _LIBCPP_HIDE_FROM_ABI bool 428 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 429 return std::equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 430 } 431}; 432 433template <class _Tp> 434struct not_equal_to<experimental::propagate_const<_Tp>> { 435 typedef experimental::propagate_const<_Tp> first_argument_type; 436 typedef experimental::propagate_const<_Tp> second_argument_type; 437 438 _LIBCPP_HIDE_FROM_ABI bool 439 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 440 return std::not_equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 441 } 442}; 443 444template <class _Tp> 445struct less<experimental::propagate_const<_Tp>> { 446 typedef experimental::propagate_const<_Tp> first_argument_type; 447 typedef experimental::propagate_const<_Tp> second_argument_type; 448 449 _LIBCPP_HIDE_FROM_ABI bool 450 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 451 return std::less<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 452 } 453}; 454 455template <class _Tp> 456struct greater<experimental::propagate_const<_Tp>> { 457 typedef experimental::propagate_const<_Tp> first_argument_type; 458 typedef experimental::propagate_const<_Tp> second_argument_type; 459 460 _LIBCPP_HIDE_FROM_ABI bool 461 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 462 return std::greater<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 463 } 464}; 465 466template <class _Tp> 467struct less_equal<experimental::propagate_const<_Tp>> { 468 typedef experimental::propagate_const<_Tp> first_argument_type; 469 typedef experimental::propagate_const<_Tp> second_argument_type; 470 471 _LIBCPP_HIDE_FROM_ABI bool 472 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 473 return std::less_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 474 } 475}; 476 477template <class _Tp> 478struct greater_equal<experimental::propagate_const<_Tp>> { 479 typedef experimental::propagate_const<_Tp> first_argument_type; 480 typedef experimental::propagate_const<_Tp> second_argument_type; 481 482 _LIBCPP_HIDE_FROM_ABI bool 483 operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 484 return std::greater_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 485 } 486}; 487 488_LIBCPP_END_NAMESPACE_STD 489 490#endif // _LIBCPP_STD_VER >= 14 491 492_LIBCPP_POP_MACROS 493 494#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 495# include <type_traits> 496#endif 497 498#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 499