10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 110b57cec5SDimitry Andric#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 120b57cec5SDimitry Andric/* 130b57cec5SDimitry Andric propagate_const synopsis 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric namespace std { namespace experimental { inline namespace fundamentals_v2 { 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric // [propagate_const] 180b57cec5SDimitry Andric template <class T> class propagate_const; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric // [propagate_const.underlying], underlying pointer access 210b57cec5SDimitry Andric constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept; 220b57cec5SDimitry Andric constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // [propagate_const.relational], relational operators 250b57cec5SDimitry Andric template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t); 260b57cec5SDimitry Andric template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu); 270b57cec5SDimitry Andric template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t); 280b57cec5SDimitry Andric template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu); 290b57cec5SDimitry Andric template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 300b57cec5SDimitry Andric template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 310b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 320b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 330b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 340b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); 350b57cec5SDimitry Andric template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u); 360b57cec5SDimitry Andric template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u); 370b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u); 380b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u); 390b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u); 400b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u); 410b57cec5SDimitry Andric template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu); 420b57cec5SDimitry Andric template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu); 430b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu); 440b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu); 450b57cec5SDimitry Andric template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu); 460b57cec5SDimitry Andric template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric // [propagate_const.algorithms], specialized algorithms 490b57cec5SDimitry Andric template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric template <class T> 520b57cec5SDimitry Andric class propagate_const 530b57cec5SDimitry Andric { 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric public: 560b57cec5SDimitry Andric typedef remove_reference_t<decltype(*declval<T&>())> element_type; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric // [propagate_const.ctor], constructors 590b57cec5SDimitry Andric constexpr propagate_const() = default; 600b57cec5SDimitry Andric propagate_const(const propagate_const& p) = delete; 610b57cec5SDimitry Andric constexpr propagate_const(propagate_const&& p) = default; 620b57cec5SDimitry Andric template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below 630b57cec5SDimitry Andric template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric // [propagate_const.assignment], assignment 660b57cec5SDimitry Andric propagate_const& operator=(const propagate_const& p) = delete; 670b57cec5SDimitry Andric constexpr propagate_const& operator=(propagate_const&& p) = default; 680b57cec5SDimitry Andric template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); 690b57cec5SDimitry Andric template <class U> constexpr propagate_const& operator=(U&& u); // see below 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // [propagate_const.const_observers], const observers 720b57cec5SDimitry Andric explicit constexpr operator bool() const; 730b57cec5SDimitry Andric constexpr const element_type* operator->() const; 740b57cec5SDimitry Andric constexpr operator const element_type*() const; // Not always defined 750b57cec5SDimitry Andric constexpr const element_type& operator*() const; 760b57cec5SDimitry Andric constexpr const element_type* get() const; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric // [propagate_const.non_const_observers], non-const observers 790b57cec5SDimitry Andric constexpr element_type* operator->(); 800b57cec5SDimitry Andric constexpr operator element_type*(); // Not always defined 810b57cec5SDimitry Andric constexpr element_type& operator*(); 820b57cec5SDimitry Andric constexpr element_type* get(); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // [propagate_const.modifiers], modifiers 850b57cec5SDimitry Andric constexpr void swap(propagate_const& pt) noexcept(see below) 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric private: 880b57cec5SDimitry Andric T t_; // exposition only 890b57cec5SDimitry Andric }; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric } // namespace fundamentals_v2 920b57cec5SDimitry Andric } // namespace experimental 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // [propagate_const.hash], hash support 950b57cec5SDimitry Andric template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric // [propagate_const.comparison_function_objects], comparison function objects 980b57cec5SDimitry Andric template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; 990b57cec5SDimitry Andric template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; 1000b57cec5SDimitry Andric template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; 1010b57cec5SDimitry Andric template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; 1020b57cec5SDimitry Andric template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; 1030b57cec5SDimitry Andric template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric} // namespace std 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric*/ 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric#include <experimental/__config> 110*04eeddc0SDimitry Andric#include <functional> 111*04eeddc0SDimitry Andric#include <type_traits> 112*04eeddc0SDimitry Andric#include <utility> 113*04eeddc0SDimitry Andric 1140b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1150b57cec5SDimitry Andric#pragma GCC system_header 1160b57cec5SDimitry Andric#endif 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andrictemplate <class _Tp> 1230b57cec5SDimitry Andricclass propagate_const; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andrictemplate <class _Up> 1260b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1270b57cec5SDimitry Andricconst _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andrictemplate <class _Up> 1300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1310b57cec5SDimitry Andric_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andrictemplate <class _Tp> 1340b57cec5SDimitry Andricclass propagate_const 1350b57cec5SDimitry Andric{ 1360b57cec5SDimitry Andricpublic: 137fe6060f1SDimitry Andric typedef remove_reference_t<decltype(*declval<_Tp&>())> element_type; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric static_assert(!is_array<_Tp>::value, 1400b57cec5SDimitry Andric "Instantiation of propagate_const with an array type is ill-formed."); 1410b57cec5SDimitry Andric static_assert(!is_reference<_Tp>::value, 1420b57cec5SDimitry Andric "Instantiation of propagate_const with a reference type is ill-formed."); 1430b57cec5SDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value), 1440b57cec5SDimitry Andric "Instantiation of propagate_const with a function-pointer type is ill-formed."); 1450b57cec5SDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value), 1460b57cec5SDimitry Andric "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andricprivate: 1490b57cec5SDimitry Andric template <class _Up> 1500b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) 1510b57cec5SDimitry Andric { 1520b57cec5SDimitry Andric return __u; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric template <class _Up> 1560b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) 1570b57cec5SDimitry Andric { 1580b57cec5SDimitry Andric return __get_pointer(__u.get()); 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric template <class _Up> 1620b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) 1630b57cec5SDimitry Andric { 1640b57cec5SDimitry Andric return __u; 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric template <class _Up> 1680b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) 1690b57cec5SDimitry Andric { 1700b57cec5SDimitry Andric return __get_pointer(__u.get()); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric template <class _Up> 1740b57cec5SDimitry Andric struct __is_propagate_const : false_type 1750b57cec5SDimitry Andric { 1760b57cec5SDimitry Andric }; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric template <class _Up> 1790b57cec5SDimitry Andric struct __is_propagate_const<propagate_const<_Up>> : true_type 1800b57cec5SDimitry Andric { 1810b57cec5SDimitry Andric }; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric _Tp __t_; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andricpublic: 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 1880b57cec5SDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const() = default; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric propagate_const(const propagate_const&) = delete; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && 1970b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = true> 1980b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 1990b57cec5SDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2000b57cec5SDimitry Andric { 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2040b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = false> 2050b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 2060b57cec5SDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2070b57cec5SDimitry Andric { 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && 2110b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value && 2120b57cec5SDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = true> 2130b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2140b57cec5SDimitry Andric : __t_(std::forward<_Up>(__u)) 2150b57cec5SDimitry Andric { 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2190b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value && 2200b57cec5SDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = false> 2210b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2220b57cec5SDimitry Andric : __t_(std::forward<_Up>(__u)) 2230b57cec5SDimitry Andric { 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric propagate_const& operator=(const propagate_const&) = delete; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric template <class _Up> 2310b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) 2320b57cec5SDimitry Andric { 2330b57cec5SDimitry Andric __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); 2340b57cec5SDimitry Andric return *this; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> 2380b57cec5SDimitry Andric _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) 2390b57cec5SDimitry Andric { 2400b57cec5SDimitry Andric __t_ = std::forward<_Up>(__u); 2410b57cec5SDimitry Andric return *this; 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric _LIBCPP_CONSTEXPR const element_type* get() const 2450b57cec5SDimitry Andric { 2460b57cec5SDimitry Andric return __get_pointer(__t_); 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric _LIBCPP_CONSTEXPR element_type* get() 2500b57cec5SDimitry Andric { 2510b57cec5SDimitry Andric return __get_pointer(__t_); 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric explicit _LIBCPP_CONSTEXPR operator bool() const 2550b57cec5SDimitry Andric { 2560b57cec5SDimitry Andric return get() != nullptr; 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric _LIBCPP_CONSTEXPR const element_type* operator->() const 2600b57cec5SDimitry Andric { 2610b57cec5SDimitry Andric return get(); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< 2650b57cec5SDimitry Andric const _Tp_, const element_type *>::value>> 2660b57cec5SDimitry Andric _LIBCPP_CONSTEXPR operator const element_type *() const { 2670b57cec5SDimitry Andric return get(); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric _LIBCPP_CONSTEXPR const element_type& operator*() const 2710b57cec5SDimitry Andric { 2720b57cec5SDimitry Andric return *get(); 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric _LIBCPP_CONSTEXPR element_type* operator->() 2760b57cec5SDimitry Andric { 2770b57cec5SDimitry Andric return get(); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric template <class _Tp_ = _Tp, class _Up = enable_if_t< 2810b57cec5SDimitry Andric is_convertible<_Tp_, element_type *>::value>> 2820b57cec5SDimitry Andric _LIBCPP_CONSTEXPR operator element_type *() { 2830b57cec5SDimitry Andric return get(); 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric _LIBCPP_CONSTEXPR element_type& operator*() 2870b57cec5SDimitry Andric { 2880b57cec5SDimitry Andric return *get(); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 2920b57cec5SDimitry Andric { 2930b57cec5SDimitry Andric using _VSTD::swap; 2940b57cec5SDimitry Andric swap(__t_, __pt.__t_); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric}; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andrictemplate <class _Tp> 3000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3010b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) 3020b57cec5SDimitry Andric{ 3030b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; 3040b57cec5SDimitry Andric} 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andrictemplate <class _Tp> 3070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3080b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) 3090b57cec5SDimitry Andric{ 3100b57cec5SDimitry Andric return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); 3110b57cec5SDimitry Andric} 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andrictemplate <class _Tp> 3140b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3150b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) 3160b57cec5SDimitry Andric{ 3170b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; 3180b57cec5SDimitry Andric} 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andrictemplate <class _Tp> 3210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3220b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) 3230b57cec5SDimitry Andric{ 3240b57cec5SDimitry Andric return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); 3250b57cec5SDimitry Andric} 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3290b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, 3300b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3310b57cec5SDimitry Andric{ 3320b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); 3330b57cec5SDimitry Andric} 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3360b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3370b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, 3380b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3390b57cec5SDimitry Andric{ 3400b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); 3410b57cec5SDimitry Andric} 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3450b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, 3460b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3470b57cec5SDimitry Andric{ 3480b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); 3490b57cec5SDimitry Andric} 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3530b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, 3540b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3550b57cec5SDimitry Andric{ 3560b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); 3570b57cec5SDimitry Andric} 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3610b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, 3620b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3630b57cec5SDimitry Andric{ 3640b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); 3650b57cec5SDimitry Andric} 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3680b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3690b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, 3700b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3710b57cec5SDimitry Andric{ 3720b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); 3730b57cec5SDimitry Andric} 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3760b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3770b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) 3780b57cec5SDimitry Andric{ 3790b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == __u; 3800b57cec5SDimitry Andric} 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3830b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3840b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) 3850b57cec5SDimitry Andric{ 3860b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != __u; 3870b57cec5SDimitry Andric} 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3910b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) 3920b57cec5SDimitry Andric{ 3930b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < __u; 3940b57cec5SDimitry Andric} 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3980b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) 3990b57cec5SDimitry Andric{ 4000b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > __u; 4010b57cec5SDimitry Andric} 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4040b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4050b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) 4060b57cec5SDimitry Andric{ 4070b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; 4080b57cec5SDimitry Andric} 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4120b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) 4130b57cec5SDimitry Andric{ 4140b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; 4150b57cec5SDimitry Andric} 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4190b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4200b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) 4210b57cec5SDimitry Andric{ 4220b57cec5SDimitry Andric return __t == _VSTD_LFTS_V2::get_underlying(__pu); 4230b57cec5SDimitry Andric} 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4260b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4270b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) 4280b57cec5SDimitry Andric{ 4290b57cec5SDimitry Andric return __t != _VSTD_LFTS_V2::get_underlying(__pu); 4300b57cec5SDimitry Andric} 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4330b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4340b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) 4350b57cec5SDimitry Andric{ 4360b57cec5SDimitry Andric return __t < _VSTD_LFTS_V2::get_underlying(__pu); 4370b57cec5SDimitry Andric} 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4410b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) 4420b57cec5SDimitry Andric{ 4430b57cec5SDimitry Andric return __t > _VSTD_LFTS_V2::get_underlying(__pu); 4440b57cec5SDimitry Andric} 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4470b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4480b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) 4490b57cec5SDimitry Andric{ 4500b57cec5SDimitry Andric return __t <= _VSTD_LFTS_V2::get_underlying(__pu); 4510b57cec5SDimitry Andric} 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4540b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4550b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) 4560b57cec5SDimitry Andric{ 4570b57cec5SDimitry Andric return __t >= _VSTD_LFTS_V2::get_underlying(__pu); 4580b57cec5SDimitry Andric} 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andrictemplate <class _Tp> 4610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4620b57cec5SDimitry Andric_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 4630b57cec5SDimitry Andric{ 4640b57cec5SDimitry Andric __pc1.swap(__pc2); 4650b57cec5SDimitry Andric} 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andrictemplate <class _Tp> 4680b57cec5SDimitry Andric_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT 4690b57cec5SDimitry Andric{ 4700b57cec5SDimitry Andric return __pt.__t_; 4710b57cec5SDimitry Andric} 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andrictemplate <class _Tp> 4740b57cec5SDimitry Andric_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT 4750b57cec5SDimitry Andric{ 4760b57cec5SDimitry Andric return __pt.__t_; 4770b57cec5SDimitry Andric} 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andrictemplate <class _Tp> 4840b57cec5SDimitry Andricstruct hash<experimental::fundamentals_v2::propagate_const<_Tp>> 4850b57cec5SDimitry Andric{ 4860b57cec5SDimitry Andric typedef size_t result_type; 4870b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const 4900b57cec5SDimitry Andric { 4910b57cec5SDimitry Andric return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric}; 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andrictemplate <class _Tp> 4960b57cec5SDimitry Andricstruct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 4970b57cec5SDimitry Andric{ 4980b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 4990b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5020b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5030b57cec5SDimitry Andric { 5040b57cec5SDimitry Andric return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric}; 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andrictemplate <class _Tp> 5090b57cec5SDimitry Andricstruct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 5100b57cec5SDimitry Andric{ 5110b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5120b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5150b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5160b57cec5SDimitry Andric { 5170b57cec5SDimitry Andric return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric}; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andrictemplate <class _Tp> 5220b57cec5SDimitry Andricstruct less<experimental::fundamentals_v2::propagate_const<_Tp>> 5230b57cec5SDimitry Andric{ 5240b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5250b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5280b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5290b57cec5SDimitry Andric { 5300b57cec5SDimitry Andric return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric}; 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andrictemplate <class _Tp> 5350b57cec5SDimitry Andricstruct greater<experimental::fundamentals_v2::propagate_const<_Tp>> 5360b57cec5SDimitry Andric{ 5370b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5380b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5410b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5420b57cec5SDimitry Andric { 5430b57cec5SDimitry Andric return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric}; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andrictemplate <class _Tp> 5480b57cec5SDimitry Andricstruct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5490b57cec5SDimitry Andric{ 5500b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5510b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5540b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5550b57cec5SDimitry Andric { 5560b57cec5SDimitry Andric return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric}; 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andrictemplate <class _Tp> 5610b57cec5SDimitry Andricstruct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5620b57cec5SDimitry Andric{ 5630b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5640b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5670b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5680b57cec5SDimitry Andric { 5690b57cec5SDimitry Andric return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric}; 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 11 5760b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 577