17c82a1ecSDimitry Andric// -*- C++ -*- 27c82a1ecSDimitry Andric//===------------------------ propagate_const -----------------------------===// 37c82a1ecSDimitry Andric// 47c82a1ecSDimitry Andric// The LLVM Compiler Infrastructure 57c82a1ecSDimitry Andric// 67c82a1ecSDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open 77c82a1ecSDimitry Andric// Source Licenses. See LICENSE.TXT for details. 87c82a1ecSDimitry Andric// 97c82a1ecSDimitry Andric//===----------------------------------------------------------------------===// 107c82a1ecSDimitry Andric 117c82a1ecSDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 127c82a1ecSDimitry Andric#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 137c82a1ecSDimitry Andric/* 147c82a1ecSDimitry Andric propagate_const synopsis 157c82a1ecSDimitry Andric 167c82a1ecSDimitry Andric namespace std { namespace experimental { inline namespace fundamentals_v2 { 177c82a1ecSDimitry Andric 187c82a1ecSDimitry Andric // [propagate_const] 197c82a1ecSDimitry Andric template <class T> class propagate_const; 207c82a1ecSDimitry Andric 217c82a1ecSDimitry Andric // [propagate_const.underlying], underlying pointer access 227c82a1ecSDimitry Andric constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept; 237c82a1ecSDimitry Andric constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept; 247c82a1ecSDimitry Andric 257c82a1ecSDimitry Andric // [propagate_const.relational], relational operators 267c82a1ecSDimitry Andric template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t); 277c82a1ecSDimitry Andric template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu); 287c82a1ecSDimitry Andric template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t); 297c82a1ecSDimitry Andric template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu); 307c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 317c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 327c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 337c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 347c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 357c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 367c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u); 377c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u); 387c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u); 397c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u); 407c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u); 417c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u); 427c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu); 437c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu); 447c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu); 457c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu); 467c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu); 477c82a1ecSDimitry Andric template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu); 487c82a1ecSDimitry Andric 497c82a1ecSDimitry Andric // [propagate_const.algorithms], specialized algorithms 507c82a1ecSDimitry Andric template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below); 517c82a1ecSDimitry Andric 527c82a1ecSDimitry Andric template <class T> 537c82a1ecSDimitry Andric class propagate_const 547c82a1ecSDimitry Andric { 557c82a1ecSDimitry Andric 567c82a1ecSDimitry Andric public: 577c82a1ecSDimitry Andric typedef remove_reference_t<decltype(*declval<T&>())> element_type; 587c82a1ecSDimitry Andric 597c82a1ecSDimitry Andric // [propagate_const.ctor], constructors 607c82a1ecSDimitry Andric constexpr propagate_const() = default; 617c82a1ecSDimitry Andric propagate_const(const propagate_const& p) = delete; 627c82a1ecSDimitry Andric constexpr propagate_const(propagate_const&& p) = default; 637c82a1ecSDimitry Andric template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below 647c82a1ecSDimitry Andric template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below 657c82a1ecSDimitry Andric 667c82a1ecSDimitry Andric // [propagate_const.assignment], assignment 677c82a1ecSDimitry Andric propagate_const& operator=(const propagate_const& p) = delete; 687c82a1ecSDimitry Andric constexpr propagate_const& operator=(propagate_const&& p) = default; 697c82a1ecSDimitry Andric template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); 707c82a1ecSDimitry Andric template <class U> constexpr propagate_const& operator=(U&& u); // see below 717c82a1ecSDimitry Andric 727c82a1ecSDimitry Andric // [propagate_const.const_observers], const observers 737c82a1ecSDimitry Andric explicit constexpr operator bool() const; 747c82a1ecSDimitry Andric constexpr const element_type* operator->() const; 757c82a1ecSDimitry Andric constexpr operator const element_type*() const; // Not always defined 767c82a1ecSDimitry Andric constexpr const element_type& operator*() const; 777c82a1ecSDimitry Andric constexpr const element_type* get() const; 787c82a1ecSDimitry Andric 797c82a1ecSDimitry Andric // [propagate_const.non_const_observers], non-const observers 807c82a1ecSDimitry Andric constexpr element_type* operator->(); 817c82a1ecSDimitry Andric constexpr operator element_type*(); // Not always defined 827c82a1ecSDimitry Andric constexpr element_type& operator*(); 837c82a1ecSDimitry Andric constexpr element_type* get(); 847c82a1ecSDimitry Andric 857c82a1ecSDimitry Andric // [propagate_const.modifiers], modifiers 867c82a1ecSDimitry Andric constexpr void swap(propagate_const& pt) noexcept(see below) 877c82a1ecSDimitry Andric 887c82a1ecSDimitry Andric private: 897c82a1ecSDimitry Andric T t_; // exposition only 907c82a1ecSDimitry Andric }; 917c82a1ecSDimitry Andric 927c82a1ecSDimitry Andric } // namespace fundamentals_v2 937c82a1ecSDimitry Andric } // namespace experimental 947c82a1ecSDimitry Andric 957c82a1ecSDimitry Andric // [propagate_const.hash], hash support 967c82a1ecSDimitry Andric template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; 977c82a1ecSDimitry Andric 987c82a1ecSDimitry Andric // [propagate_const.comparison_function_objects], comparison function objects 997c82a1ecSDimitry Andric template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; 1007c82a1ecSDimitry Andric template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; 1017c82a1ecSDimitry Andric template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; 1027c82a1ecSDimitry Andric template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; 1037c82a1ecSDimitry Andric template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; 1047c82a1ecSDimitry Andric template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; 1057c82a1ecSDimitry Andric 1067c82a1ecSDimitry Andric} // namespace std 1077c82a1ecSDimitry Andric 1087c82a1ecSDimitry Andric*/ 1097c82a1ecSDimitry Andric 1107c82a1ecSDimitry Andric#include <experimental/__config> 1117c82a1ecSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1127c82a1ecSDimitry Andric#pragma GCC system_header 1137c82a1ecSDimitry Andric#endif 1147c82a1ecSDimitry Andric 1157c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 11 1167c82a1ecSDimitry Andric 1177c82a1ecSDimitry Andric#include <type_traits> 1187c82a1ecSDimitry Andric#include <utility> 1197c82a1ecSDimitry Andric#include <functional> 1207c82a1ecSDimitry Andric 1217c82a1ecSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 1227c82a1ecSDimitry Andric 1237c82a1ecSDimitry Andric 1247c82a1ecSDimitry Andrictemplate <class _Tp> 1257c82a1ecSDimitry Andricclass propagate_const; 126aed8d94eSDimitry Andric 127aed8d94eSDimitry Andrictemplate <class _Up> 128aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 129aed8d94eSDimitry Andricconst _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 130aed8d94eSDimitry Andric 131aed8d94eSDimitry Andrictemplate <class _Up> 132aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 133aed8d94eSDimitry Andric_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1347c82a1ecSDimitry Andric 1357c82a1ecSDimitry Andrictemplate <class _Tp> 1367c82a1ecSDimitry Andricclass propagate_const 1377c82a1ecSDimitry Andric{ 1387c82a1ecSDimitry Andricpublic: 1397c82a1ecSDimitry Andric typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type; 1407c82a1ecSDimitry Andric 1417c82a1ecSDimitry Andric static_assert(!is_array<_Tp>::value, 1427c82a1ecSDimitry Andric "Instantiation of propagate_const with an array type is ill-formed."); 1437c82a1ecSDimitry Andric static_assert(!is_reference<_Tp>::value, 1447c82a1ecSDimitry Andric "Instantiation of propagate_const with a reference type is ill-formed."); 1457c82a1ecSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value), 1467c82a1ecSDimitry Andric "Instantiation of propagate_const with a function-pointer type is ill-formed."); 1477c82a1ecSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value), 1487c82a1ecSDimitry Andric "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 1497c82a1ecSDimitry Andric 1507c82a1ecSDimitry Andricprivate: 1517c82a1ecSDimitry Andric template <class _Up> 1527c82a1ecSDimitry Andric static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) 1537c82a1ecSDimitry Andric { 1547c82a1ecSDimitry Andric return __u; 1557c82a1ecSDimitry Andric } 1567c82a1ecSDimitry Andric 1577c82a1ecSDimitry Andric template <class _Up> 1587c82a1ecSDimitry Andric static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) 1597c82a1ecSDimitry Andric { 1607c82a1ecSDimitry Andric return __get_pointer(__u.get()); 1617c82a1ecSDimitry Andric } 1627c82a1ecSDimitry Andric 1637c82a1ecSDimitry Andric template <class _Up> 1647c82a1ecSDimitry Andric static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) 1657c82a1ecSDimitry Andric { 1667c82a1ecSDimitry Andric return __u; 1677c82a1ecSDimitry Andric } 1687c82a1ecSDimitry Andric 1697c82a1ecSDimitry Andric template <class _Up> 1707c82a1ecSDimitry Andric static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) 1717c82a1ecSDimitry Andric { 1727c82a1ecSDimitry Andric return __get_pointer(__u.get()); 1737c82a1ecSDimitry Andric } 1747c82a1ecSDimitry Andric 1757c82a1ecSDimitry Andric template <class _Up> 1767c82a1ecSDimitry Andric struct __is_propagate_const : false_type 1777c82a1ecSDimitry Andric { 1787c82a1ecSDimitry Andric }; 1797c82a1ecSDimitry Andric 1807c82a1ecSDimitry Andric template <class _Up> 1817c82a1ecSDimitry Andric struct __is_propagate_const<propagate_const<_Up>> : true_type 1827c82a1ecSDimitry Andric { 1837c82a1ecSDimitry Andric }; 1847c82a1ecSDimitry Andric 1857c82a1ecSDimitry Andric _Tp __t_; 1867c82a1ecSDimitry Andric 1877c82a1ecSDimitry Andricpublic: 1887c82a1ecSDimitry Andric 1897c82a1ecSDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 1907c82a1ecSDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1917c82a1ecSDimitry Andric 1927c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const() = default; 1937c82a1ecSDimitry Andric 1947c82a1ecSDimitry Andric propagate_const(const propagate_const&) = delete; 1957c82a1ecSDimitry Andric 1967c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; 1977c82a1ecSDimitry Andric 1987c82a1ecSDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && 1997c82a1ecSDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = true> 2007c82a1ecSDimitry Andric explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 2017c82a1ecSDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2027c82a1ecSDimitry Andric { 2037c82a1ecSDimitry Andric } 2047c82a1ecSDimitry Andric 2057c82a1ecSDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2067c82a1ecSDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = false> 2077c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 2087c82a1ecSDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2097c82a1ecSDimitry Andric { 2107c82a1ecSDimitry Andric } 2117c82a1ecSDimitry Andric 2127c82a1ecSDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && 2137c82a1ecSDimitry Andric is_constructible<_Tp, _Up&&>::value && 2147c82a1ecSDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = true> 2157c82a1ecSDimitry Andric explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2167c82a1ecSDimitry Andric : __t_(std::forward<_Up>(__u)) 2177c82a1ecSDimitry Andric { 2187c82a1ecSDimitry Andric } 2197c82a1ecSDimitry Andric 2207c82a1ecSDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2217c82a1ecSDimitry Andric is_constructible<_Tp, _Up&&>::value && 2227c82a1ecSDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = false> 2237c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2247c82a1ecSDimitry Andric : __t_(std::forward<_Up>(__u)) 2257c82a1ecSDimitry Andric { 2267c82a1ecSDimitry Andric } 2277c82a1ecSDimitry Andric 2287c82a1ecSDimitry Andric propagate_const& operator=(const propagate_const&) = delete; 2297c82a1ecSDimitry Andric 2307c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; 2317c82a1ecSDimitry Andric 2327c82a1ecSDimitry Andric template <class _Up> 2337c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) 2347c82a1ecSDimitry Andric { 2357c82a1ecSDimitry Andric __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); 2367c82a1ecSDimitry Andric return *this; 2377c82a1ecSDimitry Andric } 2387c82a1ecSDimitry Andric 2397c82a1ecSDimitry Andric template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> 2407c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) 2417c82a1ecSDimitry Andric { 2427c82a1ecSDimitry Andric __t_ = std::forward<_Up>(__u); 2437c82a1ecSDimitry Andric return *this; 2447c82a1ecSDimitry Andric } 2457c82a1ecSDimitry Andric 2467c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR const element_type* get() const 2477c82a1ecSDimitry Andric { 2487c82a1ecSDimitry Andric return __get_pointer(__t_); 2497c82a1ecSDimitry Andric } 2507c82a1ecSDimitry Andric 2517c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR element_type* get() 2527c82a1ecSDimitry Andric { 2537c82a1ecSDimitry Andric return __get_pointer(__t_); 2547c82a1ecSDimitry Andric } 2557c82a1ecSDimitry Andric 2567c82a1ecSDimitry Andric explicit _LIBCPP_CONSTEXPR operator bool() const 2577c82a1ecSDimitry Andric { 2587c82a1ecSDimitry Andric return get() != nullptr; 2597c82a1ecSDimitry Andric } 2607c82a1ecSDimitry Andric 2617c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR const element_type* operator->() const 2627c82a1ecSDimitry Andric { 2637c82a1ecSDimitry Andric return get(); 2647c82a1ecSDimitry Andric } 2657c82a1ecSDimitry Andric 2667c82a1ecSDimitry Andric template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< 2677c82a1ecSDimitry Andric const _Tp_, const element_type *>::value>> 2687c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR operator const element_type *() const { 2697c82a1ecSDimitry Andric return get(); 2707c82a1ecSDimitry Andric } 2717c82a1ecSDimitry Andric 2727c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR const element_type& operator*() const 2737c82a1ecSDimitry Andric { 2747c82a1ecSDimitry Andric return *get(); 2757c82a1ecSDimitry Andric } 2767c82a1ecSDimitry Andric 2777c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR element_type* operator->() 2787c82a1ecSDimitry Andric { 2797c82a1ecSDimitry Andric return get(); 2807c82a1ecSDimitry Andric } 2817c82a1ecSDimitry Andric 2827c82a1ecSDimitry Andric template <class _Tp_ = _Tp, class _Up = enable_if_t< 2837c82a1ecSDimitry Andric is_convertible<_Tp_, element_type *>::value>> 2847c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR operator element_type *() { 2857c82a1ecSDimitry Andric return get(); 2867c82a1ecSDimitry Andric } 2877c82a1ecSDimitry Andric 2887c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR element_type& operator*() 2897c82a1ecSDimitry Andric { 2907c82a1ecSDimitry Andric return *get(); 2917c82a1ecSDimitry Andric } 2927c82a1ecSDimitry Andric 2937c82a1ecSDimitry Andric _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 2947c82a1ecSDimitry Andric { 2957c82a1ecSDimitry Andric using _VSTD::swap; 2967c82a1ecSDimitry Andric swap(__t_, __pt.__t_); 2977c82a1ecSDimitry Andric } 2987c82a1ecSDimitry Andric}; 2997c82a1ecSDimitry Andric 3007c82a1ecSDimitry Andric 3017c82a1ecSDimitry Andrictemplate <class _Tp> 3027c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3037c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) 3047c82a1ecSDimitry Andric{ 3057c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; 3067c82a1ecSDimitry Andric} 3077c82a1ecSDimitry Andric 3087c82a1ecSDimitry Andrictemplate <class _Tp> 3097c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3107c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) 3117c82a1ecSDimitry Andric{ 3127c82a1ecSDimitry Andric return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); 3137c82a1ecSDimitry Andric} 3147c82a1ecSDimitry Andric 3157c82a1ecSDimitry Andrictemplate <class _Tp> 3167c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3177c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) 3187c82a1ecSDimitry Andric{ 3197c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; 3207c82a1ecSDimitry Andric} 3217c82a1ecSDimitry Andric 3227c82a1ecSDimitry Andrictemplate <class _Tp> 3237c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3247c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) 3257c82a1ecSDimitry Andric{ 3267c82a1ecSDimitry Andric return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); 3277c82a1ecSDimitry Andric} 3287c82a1ecSDimitry Andric 3297c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3307c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3317c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, 3327c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3337c82a1ecSDimitry Andric{ 3347c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); 3357c82a1ecSDimitry Andric} 3367c82a1ecSDimitry Andric 3377c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3387c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3397c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, 3407c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3417c82a1ecSDimitry Andric{ 3427c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); 3437c82a1ecSDimitry Andric} 3447c82a1ecSDimitry Andric 3457c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3467c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3477c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, 3487c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3497c82a1ecSDimitry Andric{ 3507c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); 3517c82a1ecSDimitry Andric} 3527c82a1ecSDimitry Andric 3537c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3547c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3557c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, 3567c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3577c82a1ecSDimitry Andric{ 3587c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); 3597c82a1ecSDimitry Andric} 3607c82a1ecSDimitry Andric 3617c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3627c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3637c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, 3647c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3657c82a1ecSDimitry Andric{ 3667c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); 3677c82a1ecSDimitry Andric} 3687c82a1ecSDimitry Andric 3697c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3707c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3717c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, 3727c82a1ecSDimitry Andric const propagate_const<_Up>& __pu) 3737c82a1ecSDimitry Andric{ 3747c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); 3757c82a1ecSDimitry Andric} 3767c82a1ecSDimitry Andric 3777c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3787c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3797c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) 3807c82a1ecSDimitry Andric{ 3817c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == __u; 3827c82a1ecSDimitry Andric} 3837c82a1ecSDimitry Andric 3847c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3857c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3867c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) 3877c82a1ecSDimitry Andric{ 3887c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != __u; 3897c82a1ecSDimitry Andric} 3907c82a1ecSDimitry Andric 3917c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3927c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 3937c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) 3947c82a1ecSDimitry Andric{ 3957c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < __u; 3967c82a1ecSDimitry Andric} 3977c82a1ecSDimitry Andric 3987c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 3997c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4007c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) 4017c82a1ecSDimitry Andric{ 4027c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > __u; 4037c82a1ecSDimitry Andric} 4047c82a1ecSDimitry Andric 4057c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4067c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4077c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) 4087c82a1ecSDimitry Andric{ 4097c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; 4107c82a1ecSDimitry Andric} 4117c82a1ecSDimitry Andric 4127c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4137c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4147c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) 4157c82a1ecSDimitry Andric{ 4167c82a1ecSDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; 4177c82a1ecSDimitry Andric} 4187c82a1ecSDimitry Andric 4197c82a1ecSDimitry Andric 4207c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4217c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4227c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) 4237c82a1ecSDimitry Andric{ 4247c82a1ecSDimitry Andric return __t == _VSTD_LFTS_V2::get_underlying(__pu); 4257c82a1ecSDimitry Andric} 4267c82a1ecSDimitry Andric 4277c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4287c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4297c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) 4307c82a1ecSDimitry Andric{ 4317c82a1ecSDimitry Andric return __t != _VSTD_LFTS_V2::get_underlying(__pu); 4327c82a1ecSDimitry Andric} 4337c82a1ecSDimitry Andric 4347c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4357c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4367c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) 4377c82a1ecSDimitry Andric{ 4387c82a1ecSDimitry Andric return __t < _VSTD_LFTS_V2::get_underlying(__pu); 4397c82a1ecSDimitry Andric} 4407c82a1ecSDimitry Andric 4417c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4427c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4437c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) 4447c82a1ecSDimitry Andric{ 4457c82a1ecSDimitry Andric return __t > _VSTD_LFTS_V2::get_underlying(__pu); 4467c82a1ecSDimitry Andric} 4477c82a1ecSDimitry Andric 4487c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4497c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4507c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) 4517c82a1ecSDimitry Andric{ 4527c82a1ecSDimitry Andric return __t <= _VSTD_LFTS_V2::get_underlying(__pu); 4537c82a1ecSDimitry Andric} 4547c82a1ecSDimitry Andric 4557c82a1ecSDimitry Andrictemplate <class _Tp, class _Up> 4567c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4577c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) 4587c82a1ecSDimitry Andric{ 4597c82a1ecSDimitry Andric return __t >= _VSTD_LFTS_V2::get_underlying(__pu); 4607c82a1ecSDimitry Andric} 4617c82a1ecSDimitry Andric 4627c82a1ecSDimitry Andrictemplate <class _Tp> 4637c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY 4647c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 4657c82a1ecSDimitry Andric{ 466*4ba319b5SDimitry Andric __pc1.swap(__pc2); 4677c82a1ecSDimitry Andric} 4687c82a1ecSDimitry Andric 4697c82a1ecSDimitry Andrictemplate <class _Tp> 4707c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT 4717c82a1ecSDimitry Andric{ 4727c82a1ecSDimitry Andric return __pt.__t_; 4737c82a1ecSDimitry Andric} 4747c82a1ecSDimitry Andric 4757c82a1ecSDimitry Andrictemplate <class _Tp> 4767c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT 4777c82a1ecSDimitry Andric{ 4787c82a1ecSDimitry Andric return __pt.__t_; 4797c82a1ecSDimitry Andric} 4807c82a1ecSDimitry Andric 4817c82a1ecSDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2 4827c82a1ecSDimitry Andric 4837c82a1ecSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 4847c82a1ecSDimitry Andric 4857c82a1ecSDimitry Andrictemplate <class _Tp> 4867c82a1ecSDimitry Andricstruct hash<experimental::fundamentals_v2::propagate_const<_Tp>> 4877c82a1ecSDimitry Andric{ 4887c82a1ecSDimitry Andric typedef size_t result_type; 4897c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; 4907c82a1ecSDimitry Andric 4917c82a1ecSDimitry Andric size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const 4927c82a1ecSDimitry Andric { 4937c82a1ecSDimitry Andric return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); 4947c82a1ecSDimitry Andric } 4957c82a1ecSDimitry Andric}; 4967c82a1ecSDimitry Andric 4977c82a1ecSDimitry Andrictemplate <class _Tp> 4987c82a1ecSDimitry Andricstruct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 4997c82a1ecSDimitry Andric{ 5007c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5017c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5027c82a1ecSDimitry Andric 5037c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5047c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5057c82a1ecSDimitry Andric { 5067c82a1ecSDimitry Andric return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5077c82a1ecSDimitry Andric } 5087c82a1ecSDimitry Andric}; 5097c82a1ecSDimitry Andric 5107c82a1ecSDimitry Andrictemplate <class _Tp> 5117c82a1ecSDimitry Andricstruct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 5127c82a1ecSDimitry Andric{ 5137c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5147c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5157c82a1ecSDimitry Andric 5167c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5177c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5187c82a1ecSDimitry Andric { 5197c82a1ecSDimitry Andric return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5207c82a1ecSDimitry Andric } 5217c82a1ecSDimitry Andric}; 5227c82a1ecSDimitry Andric 5237c82a1ecSDimitry Andrictemplate <class _Tp> 5247c82a1ecSDimitry Andricstruct less<experimental::fundamentals_v2::propagate_const<_Tp>> 5257c82a1ecSDimitry Andric{ 5267c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5277c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5287c82a1ecSDimitry Andric 5297c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5307c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5317c82a1ecSDimitry Andric { 5327c82a1ecSDimitry Andric return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5337c82a1ecSDimitry Andric } 5347c82a1ecSDimitry Andric}; 5357c82a1ecSDimitry Andric 5367c82a1ecSDimitry Andrictemplate <class _Tp> 5377c82a1ecSDimitry Andricstruct greater<experimental::fundamentals_v2::propagate_const<_Tp>> 5387c82a1ecSDimitry Andric{ 5397c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5407c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5417c82a1ecSDimitry Andric 5427c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5437c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5447c82a1ecSDimitry Andric { 5457c82a1ecSDimitry Andric return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5467c82a1ecSDimitry Andric } 5477c82a1ecSDimitry Andric}; 5487c82a1ecSDimitry Andric 5497c82a1ecSDimitry Andrictemplate <class _Tp> 5507c82a1ecSDimitry Andricstruct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5517c82a1ecSDimitry Andric{ 5527c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5537c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5547c82a1ecSDimitry Andric 5557c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5567c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5577c82a1ecSDimitry Andric { 5587c82a1ecSDimitry Andric return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5597c82a1ecSDimitry Andric } 5607c82a1ecSDimitry Andric}; 5617c82a1ecSDimitry Andric 5627c82a1ecSDimitry Andrictemplate <class _Tp> 5637c82a1ecSDimitry Andricstruct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5647c82a1ecSDimitry Andric{ 5657c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5667c82a1ecSDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5677c82a1ecSDimitry Andric 5687c82a1ecSDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5697c82a1ecSDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5707c82a1ecSDimitry Andric { 5717c82a1ecSDimitry Andric return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5727c82a1ecSDimitry Andric } 5737c82a1ecSDimitry Andric}; 5747c82a1ecSDimitry Andric 5757c82a1ecSDimitry Andric_LIBCPP_END_NAMESPACE_STD 5767c82a1ecSDimitry Andric 5777c82a1ecSDimitry Andric#endif // _LIBCPP_STD_VER > 11 5787c82a1ecSDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 5797c82a1ecSDimitry Andric 580