1303237Sdim// -*- C++ -*- 2303237Sdim//===------------------------ propagate_const -----------------------------===// 3303237Sdim// 4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5353358Sdim// See https://llvm.org/LICENSE.txt for license information. 6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7303237Sdim// 8303237Sdim//===----------------------------------------------------------------------===// 9303237Sdim 10303237Sdim#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 11303237Sdim#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 12303237Sdim/* 13303237Sdim propagate_const synopsis 14303237Sdim 15303237Sdim namespace std { namespace experimental { inline namespace fundamentals_v2 { 16303237Sdim 17303237Sdim // [propagate_const] 18303237Sdim template <class T> class propagate_const; 19303237Sdim 20303237Sdim // [propagate_const.underlying], underlying pointer access 21303237Sdim constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept; 22303237Sdim constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept; 23303237Sdim 24303237Sdim // [propagate_const.relational], relational operators 25303237Sdim template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t); 26303237Sdim template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu); 27303237Sdim template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t); 28303237Sdim template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu); 29303237Sdim template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 30303237Sdim template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 31303237Sdim template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 32303237Sdim template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 33303237Sdim template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 34303237Sdim template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 35303237Sdim template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u); 36303237Sdim template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u); 37303237Sdim template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u); 38303237Sdim template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u); 39303237Sdim template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u); 40303237Sdim template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u); 41303237Sdim template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu); 42303237Sdim template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu); 43303237Sdim template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu); 44303237Sdim template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu); 45303237Sdim template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu); 46303237Sdim template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu); 47303237Sdim 48303237Sdim // [propagate_const.algorithms], specialized algorithms 49303237Sdim template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below); 50303237Sdim 51303237Sdim template <class T> 52303237Sdim class propagate_const 53303237Sdim { 54303237Sdim 55303237Sdim public: 56303237Sdim typedef remove_reference_t<decltype(*declval<T&>())> element_type; 57303237Sdim 58303237Sdim // [propagate_const.ctor], constructors 59303237Sdim constexpr propagate_const() = default; 60303237Sdim propagate_const(const propagate_const& p) = delete; 61303237Sdim constexpr propagate_const(propagate_const&& p) = default; 62303237Sdim template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below 63303237Sdim template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below 64303237Sdim 65303237Sdim // [propagate_const.assignment], assignment 66303237Sdim propagate_const& operator=(const propagate_const& p) = delete; 67303237Sdim constexpr propagate_const& operator=(propagate_const&& p) = default; 68303237Sdim template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); 69303237Sdim template <class U> constexpr propagate_const& operator=(U&& u); // see below 70303237Sdim 71303237Sdim // [propagate_const.const_observers], const observers 72303237Sdim explicit constexpr operator bool() const; 73303237Sdim constexpr const element_type* operator->() const; 74303237Sdim constexpr operator const element_type*() const; // Not always defined 75303237Sdim constexpr const element_type& operator*() const; 76303237Sdim constexpr const element_type* get() const; 77303237Sdim 78303237Sdim // [propagate_const.non_const_observers], non-const observers 79303237Sdim constexpr element_type* operator->(); 80303237Sdim constexpr operator element_type*(); // Not always defined 81303237Sdim constexpr element_type& operator*(); 82303237Sdim constexpr element_type* get(); 83303237Sdim 84303237Sdim // [propagate_const.modifiers], modifiers 85303237Sdim constexpr void swap(propagate_const& pt) noexcept(see below) 86303237Sdim 87303237Sdim private: 88303237Sdim T t_; // exposition only 89303237Sdim }; 90303237Sdim 91303237Sdim } // namespace fundamentals_v2 92303237Sdim } // namespace experimental 93303237Sdim 94303237Sdim // [propagate_const.hash], hash support 95303237Sdim template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; 96303237Sdim 97303237Sdim // [propagate_const.comparison_function_objects], comparison function objects 98303237Sdim template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; 99303237Sdim template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; 100303237Sdim template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; 101303237Sdim template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; 102303237Sdim template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; 103303237Sdim template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; 104303237Sdim 105303237Sdim} // namespace std 106303237Sdim 107303237Sdim*/ 108303237Sdim 109303237Sdim#include <experimental/__config> 110303237Sdim#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 111303237Sdim#pragma GCC system_header 112303237Sdim#endif 113303237Sdim 114303237Sdim#if _LIBCPP_STD_VER > 11 115303237Sdim 116303237Sdim#include <type_traits> 117303237Sdim#include <utility> 118303237Sdim#include <functional> 119303237Sdim 120303237Sdim_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 121303237Sdim 122303237Sdim 123303237Sdimtemplate <class _Tp> 124303237Sdimclass propagate_const; 125303237Sdim 126314564Sdimtemplate <class _Up> 127314564Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 128314564Sdimconst _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 129314564Sdim 130314564Sdimtemplate <class _Up> 131314564Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 132314564Sdim_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 133314564Sdim 134303237Sdimtemplate <class _Tp> 135303237Sdimclass propagate_const 136303237Sdim{ 137303237Sdimpublic: 138303237Sdim typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type; 139303237Sdim 140303237Sdim static_assert(!is_array<_Tp>::value, 141303237Sdim "Instantiation of propagate_const with an array type is ill-formed."); 142303237Sdim static_assert(!is_reference<_Tp>::value, 143303237Sdim "Instantiation of propagate_const with a reference type is ill-formed."); 144303237Sdim static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value), 145303237Sdim "Instantiation of propagate_const with a function-pointer type is ill-formed."); 146303237Sdim static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value), 147303237Sdim "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 148303237Sdim 149303237Sdimprivate: 150303237Sdim template <class _Up> 151303237Sdim static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) 152303237Sdim { 153303237Sdim return __u; 154303237Sdim } 155303237Sdim 156303237Sdim template <class _Up> 157303237Sdim static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) 158303237Sdim { 159303237Sdim return __get_pointer(__u.get()); 160303237Sdim } 161303237Sdim 162303237Sdim template <class _Up> 163303237Sdim static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) 164303237Sdim { 165303237Sdim return __u; 166303237Sdim } 167303237Sdim 168303237Sdim template <class _Up> 169303237Sdim static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) 170303237Sdim { 171303237Sdim return __get_pointer(__u.get()); 172303237Sdim } 173303237Sdim 174303237Sdim template <class _Up> 175303237Sdim struct __is_propagate_const : false_type 176303237Sdim { 177303237Sdim }; 178303237Sdim 179303237Sdim template <class _Up> 180303237Sdim struct __is_propagate_const<propagate_const<_Up>> : true_type 181303237Sdim { 182303237Sdim }; 183303237Sdim 184303237Sdim _Tp __t_; 185303237Sdim 186303237Sdimpublic: 187303237Sdim 188303237Sdim template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 189303237Sdim template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 190303237Sdim 191303237Sdim _LIBCPP_CONSTEXPR propagate_const() = default; 192303237Sdim 193303237Sdim propagate_const(const propagate_const&) = delete; 194303237Sdim 195303237Sdim _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; 196303237Sdim 197303237Sdim template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && 198303237Sdim is_constructible<_Tp, _Up&&>::value,bool> = true> 199303237Sdim explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 200303237Sdim : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 201303237Sdim { 202303237Sdim } 203303237Sdim 204303237Sdim template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 205303237Sdim is_constructible<_Tp, _Up&&>::value,bool> = false> 206303237Sdim _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 207303237Sdim : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 208303237Sdim { 209303237Sdim } 210303237Sdim 211303237Sdim template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && 212303237Sdim is_constructible<_Tp, _Up&&>::value && 213303237Sdim !__is_propagate_const<decay_t<_Up>>::value,bool> = true> 214303237Sdim explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 215303237Sdim : __t_(std::forward<_Up>(__u)) 216303237Sdim { 217303237Sdim } 218303237Sdim 219303237Sdim template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 220303237Sdim is_constructible<_Tp, _Up&&>::value && 221303237Sdim !__is_propagate_const<decay_t<_Up>>::value,bool> = false> 222303237Sdim _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 223303237Sdim : __t_(std::forward<_Up>(__u)) 224303237Sdim { 225303237Sdim } 226303237Sdim 227303237Sdim propagate_const& operator=(const propagate_const&) = delete; 228303237Sdim 229303237Sdim _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; 230303237Sdim 231303237Sdim template <class _Up> 232303237Sdim _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) 233303237Sdim { 234303237Sdim __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); 235303237Sdim return *this; 236303237Sdim } 237303237Sdim 238303237Sdim template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> 239303237Sdim _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) 240303237Sdim { 241303237Sdim __t_ = std::forward<_Up>(__u); 242303237Sdim return *this; 243303237Sdim } 244303237Sdim 245303237Sdim _LIBCPP_CONSTEXPR const element_type* get() const 246303237Sdim { 247303237Sdim return __get_pointer(__t_); 248303237Sdim } 249303237Sdim 250303237Sdim _LIBCPP_CONSTEXPR element_type* get() 251303237Sdim { 252303237Sdim return __get_pointer(__t_); 253303237Sdim } 254303237Sdim 255303237Sdim explicit _LIBCPP_CONSTEXPR operator bool() const 256303237Sdim { 257303237Sdim return get() != nullptr; 258303237Sdim } 259303237Sdim 260303237Sdim _LIBCPP_CONSTEXPR const element_type* operator->() const 261303237Sdim { 262303237Sdim return get(); 263303237Sdim } 264303237Sdim 265303237Sdim template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< 266303237Sdim const _Tp_, const element_type *>::value>> 267303237Sdim _LIBCPP_CONSTEXPR operator const element_type *() const { 268303237Sdim return get(); 269303237Sdim } 270303237Sdim 271303237Sdim _LIBCPP_CONSTEXPR const element_type& operator*() const 272303237Sdim { 273303237Sdim return *get(); 274303237Sdim } 275303237Sdim 276303237Sdim _LIBCPP_CONSTEXPR element_type* operator->() 277303237Sdim { 278303237Sdim return get(); 279303237Sdim } 280303237Sdim 281303237Sdim template <class _Tp_ = _Tp, class _Up = enable_if_t< 282303237Sdim is_convertible<_Tp_, element_type *>::value>> 283303237Sdim _LIBCPP_CONSTEXPR operator element_type *() { 284303237Sdim return get(); 285303237Sdim } 286303237Sdim 287303237Sdim _LIBCPP_CONSTEXPR element_type& operator*() 288303237Sdim { 289303237Sdim return *get(); 290303237Sdim } 291303237Sdim 292303237Sdim _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 293303237Sdim { 294303237Sdim using _VSTD::swap; 295303237Sdim swap(__t_, __pt.__t_); 296303237Sdim } 297303237Sdim}; 298303237Sdim 299303237Sdim 300303237Sdimtemplate <class _Tp> 301303237Sdim_LIBCPP_INLINE_VISIBILITY 302303237Sdim_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) 303303237Sdim{ 304303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; 305303237Sdim} 306303237Sdim 307303237Sdimtemplate <class _Tp> 308303237Sdim_LIBCPP_INLINE_VISIBILITY 309303237Sdim_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) 310303237Sdim{ 311303237Sdim return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); 312303237Sdim} 313303237Sdim 314303237Sdimtemplate <class _Tp> 315303237Sdim_LIBCPP_INLINE_VISIBILITY 316303237Sdim_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) 317303237Sdim{ 318303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; 319303237Sdim} 320303237Sdim 321303237Sdimtemplate <class _Tp> 322303237Sdim_LIBCPP_INLINE_VISIBILITY 323303237Sdim_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) 324303237Sdim{ 325303237Sdim return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); 326303237Sdim} 327303237Sdim 328303237Sdimtemplate <class _Tp, class _Up> 329303237Sdim_LIBCPP_INLINE_VISIBILITY 330303237Sdim_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, 331303237Sdim const propagate_const<_Up>& __pu) 332303237Sdim{ 333303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); 334303237Sdim} 335303237Sdim 336303237Sdimtemplate <class _Tp, class _Up> 337303237Sdim_LIBCPP_INLINE_VISIBILITY 338303237Sdim_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, 339303237Sdim const propagate_const<_Up>& __pu) 340303237Sdim{ 341303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); 342303237Sdim} 343303237Sdim 344303237Sdimtemplate <class _Tp, class _Up> 345303237Sdim_LIBCPP_INLINE_VISIBILITY 346303237Sdim_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, 347303237Sdim const propagate_const<_Up>& __pu) 348303237Sdim{ 349303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); 350303237Sdim} 351303237Sdim 352303237Sdimtemplate <class _Tp, class _Up> 353303237Sdim_LIBCPP_INLINE_VISIBILITY 354303237Sdim_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, 355303237Sdim const propagate_const<_Up>& __pu) 356303237Sdim{ 357303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); 358303237Sdim} 359303237Sdim 360303237Sdimtemplate <class _Tp, class _Up> 361303237Sdim_LIBCPP_INLINE_VISIBILITY 362303237Sdim_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, 363303237Sdim const propagate_const<_Up>& __pu) 364303237Sdim{ 365303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); 366303237Sdim} 367303237Sdim 368303237Sdimtemplate <class _Tp, class _Up> 369303237Sdim_LIBCPP_INLINE_VISIBILITY 370303237Sdim_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, 371303237Sdim const propagate_const<_Up>& __pu) 372303237Sdim{ 373303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); 374303237Sdim} 375303237Sdim 376303237Sdimtemplate <class _Tp, class _Up> 377303237Sdim_LIBCPP_INLINE_VISIBILITY 378303237Sdim_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) 379303237Sdim{ 380303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) == __u; 381303237Sdim} 382303237Sdim 383303237Sdimtemplate <class _Tp, class _Up> 384303237Sdim_LIBCPP_INLINE_VISIBILITY 385303237Sdim_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) 386303237Sdim{ 387303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) != __u; 388303237Sdim} 389303237Sdim 390303237Sdimtemplate <class _Tp, class _Up> 391303237Sdim_LIBCPP_INLINE_VISIBILITY 392303237Sdim_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) 393303237Sdim{ 394303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) < __u; 395303237Sdim} 396303237Sdim 397303237Sdimtemplate <class _Tp, class _Up> 398303237Sdim_LIBCPP_INLINE_VISIBILITY 399303237Sdim_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) 400303237Sdim{ 401303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) > __u; 402303237Sdim} 403303237Sdim 404303237Sdimtemplate <class _Tp, class _Up> 405303237Sdim_LIBCPP_INLINE_VISIBILITY 406303237Sdim_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) 407303237Sdim{ 408303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; 409303237Sdim} 410303237Sdim 411303237Sdimtemplate <class _Tp, class _Up> 412303237Sdim_LIBCPP_INLINE_VISIBILITY 413303237Sdim_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) 414303237Sdim{ 415303237Sdim return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; 416303237Sdim} 417303237Sdim 418303237Sdim 419303237Sdimtemplate <class _Tp, class _Up> 420303237Sdim_LIBCPP_INLINE_VISIBILITY 421303237Sdim_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) 422303237Sdim{ 423303237Sdim return __t == _VSTD_LFTS_V2::get_underlying(__pu); 424303237Sdim} 425303237Sdim 426303237Sdimtemplate <class _Tp, class _Up> 427303237Sdim_LIBCPP_INLINE_VISIBILITY 428303237Sdim_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) 429303237Sdim{ 430303237Sdim return __t != _VSTD_LFTS_V2::get_underlying(__pu); 431303237Sdim} 432303237Sdim 433303237Sdimtemplate <class _Tp, class _Up> 434303237Sdim_LIBCPP_INLINE_VISIBILITY 435303237Sdim_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) 436303237Sdim{ 437303237Sdim return __t < _VSTD_LFTS_V2::get_underlying(__pu); 438303237Sdim} 439303237Sdim 440303237Sdimtemplate <class _Tp, class _Up> 441303237Sdim_LIBCPP_INLINE_VISIBILITY 442303237Sdim_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) 443303237Sdim{ 444303237Sdim return __t > _VSTD_LFTS_V2::get_underlying(__pu); 445303237Sdim} 446303237Sdim 447303237Sdimtemplate <class _Tp, class _Up> 448303237Sdim_LIBCPP_INLINE_VISIBILITY 449303237Sdim_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) 450303237Sdim{ 451303237Sdim return __t <= _VSTD_LFTS_V2::get_underlying(__pu); 452303237Sdim} 453303237Sdim 454303237Sdimtemplate <class _Tp, class _Up> 455303237Sdim_LIBCPP_INLINE_VISIBILITY 456303237Sdim_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) 457303237Sdim{ 458303237Sdim return __t >= _VSTD_LFTS_V2::get_underlying(__pu); 459303237Sdim} 460303237Sdim 461303237Sdimtemplate <class _Tp> 462303237Sdim_LIBCPP_INLINE_VISIBILITY 463303237Sdim_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 464303237Sdim{ 465341825Sdim __pc1.swap(__pc2); 466303237Sdim} 467303237Sdim 468303237Sdimtemplate <class _Tp> 469303237Sdim_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT 470303237Sdim{ 471303237Sdim return __pt.__t_; 472303237Sdim} 473303237Sdim 474303237Sdimtemplate <class _Tp> 475303237Sdim_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT 476303237Sdim{ 477303237Sdim return __pt.__t_; 478303237Sdim} 479303237Sdim 480303237Sdim_LIBCPP_END_NAMESPACE_LFTS_V2 481303237Sdim 482303237Sdim_LIBCPP_BEGIN_NAMESPACE_STD 483303237Sdim 484303237Sdimtemplate <class _Tp> 485303237Sdimstruct hash<experimental::fundamentals_v2::propagate_const<_Tp>> 486303237Sdim{ 487303237Sdim typedef size_t result_type; 488303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; 489303237Sdim 490303237Sdim size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const 491303237Sdim { 492303237Sdim return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); 493303237Sdim } 494303237Sdim}; 495303237Sdim 496303237Sdimtemplate <class _Tp> 497303237Sdimstruct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 498303237Sdim{ 499303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 500303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 501303237Sdim 502303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 503303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 504303237Sdim { 505303237Sdim return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 506303237Sdim } 507303237Sdim}; 508303237Sdim 509303237Sdimtemplate <class _Tp> 510303237Sdimstruct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 511303237Sdim{ 512303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 513303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 514303237Sdim 515303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 516303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 517303237Sdim { 518303237Sdim return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 519303237Sdim } 520303237Sdim}; 521303237Sdim 522303237Sdimtemplate <class _Tp> 523303237Sdimstruct less<experimental::fundamentals_v2::propagate_const<_Tp>> 524303237Sdim{ 525303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 526303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 527303237Sdim 528303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 529303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 530303237Sdim { 531303237Sdim return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 532303237Sdim } 533303237Sdim}; 534303237Sdim 535303237Sdimtemplate <class _Tp> 536303237Sdimstruct greater<experimental::fundamentals_v2::propagate_const<_Tp>> 537303237Sdim{ 538303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 539303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 540303237Sdim 541303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 542303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 543303237Sdim { 544303237Sdim return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 545303237Sdim } 546303237Sdim}; 547303237Sdim 548303237Sdimtemplate <class _Tp> 549303237Sdimstruct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 550303237Sdim{ 551303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 552303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 553303237Sdim 554303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 555303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 556303237Sdim { 557303237Sdim return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 558303237Sdim } 559303237Sdim}; 560303237Sdim 561303237Sdimtemplate <class _Tp> 562303237Sdimstruct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 563303237Sdim{ 564303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 565303237Sdim typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 566303237Sdim 567303237Sdim bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 568303237Sdim const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 569303237Sdim { 570303237Sdim return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 571303237Sdim } 572303237Sdim}; 573303237Sdim 574303237Sdim_LIBCPP_END_NAMESPACE_STD 575303237Sdim 576303237Sdim#endif // _LIBCPP_STD_VER > 11 577303237Sdim#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 578