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