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