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 1281ad6265SDimitry 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 225f757f3fSDimitry Andric constexpr const _Tp& get_underlying(const propagate_const<T>& pt) noexcept; 235f757f3fSDimitry Andric constexpr T& 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 965f757f3fSDimitry Andric template <class T> struct hash<experimental::propagate_const<T>>; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // [propagate_const.comparison_function_objects], comparison function objects 995f757f3fSDimitry Andric template <class T> struct equal_to<experimental::propagate_const<T>>; 1005f757f3fSDimitry Andric template <class T> struct not_equal_to<experimental::propagate_const<T>>; 1015f757f3fSDimitry Andric template <class T> struct less<experimental::propagate_const<T>>; 1025f757f3fSDimitry Andric template <class T> struct greater<experimental::propagate_const<T>>; 1035f757f3fSDimitry Andric template <class T> struct less_equal<experimental::propagate_const<T>>; 1045f757f3fSDimitry Andric template <class T> struct greater_equal<experimental::propagate_const<T>>; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric} // namespace std 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric*/ 1090b57cec5SDimitry Andric 11081ad6265SDimitry Andric#include <__functional/operations.h> 111*0fca6ea1SDimitry Andric#include <__fwd/functional.h> 11206c3fb27SDimitry Andric#include <__type_traits/conditional.h> 11306c3fb27SDimitry Andric#include <__type_traits/decay.h> 11406c3fb27SDimitry Andric#include <__type_traits/enable_if.h> 11506c3fb27SDimitry Andric#include <__type_traits/is_array.h> 11606c3fb27SDimitry Andric#include <__type_traits/is_constructible.h> 11706c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 11806c3fb27SDimitry Andric#include <__type_traits/is_function.h> 11906c3fb27SDimitry Andric#include <__type_traits/is_pointer.h> 12006c3fb27SDimitry Andric#include <__type_traits/is_reference.h> 12106c3fb27SDimitry Andric#include <__type_traits/is_same.h> 12206c3fb27SDimitry Andric#include <__type_traits/is_swappable.h> 12306c3fb27SDimitry Andric#include <__type_traits/remove_cv.h> 12406c3fb27SDimitry Andric#include <__type_traits/remove_pointer.h> 12506c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 12606c3fb27SDimitry Andric#include <__utility/declval.h> 12781ad6265SDimitry Andric#include <__utility/forward.h> 12881ad6265SDimitry Andric#include <__utility/move.h> 12981ad6265SDimitry Andric#include <__utility/swap.h> 13006c3fb27SDimitry Andric#include <cstddef> 1310b57cec5SDimitry Andric#include <experimental/__config> 13204eeddc0SDimitry Andric 1330b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1340b57cec5SDimitry Andric# pragma GCC system_header 1350b57cec5SDimitry Andric#endif 1360b57cec5SDimitry Andric 13706c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS 13806c3fb27SDimitry Andric#include <__undef_macros> 13906c3fb27SDimitry Andric 14006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andrictemplate <class _Tp> 1450b57cec5SDimitry Andricclass propagate_const; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andrictemplate <class _Up> 148*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andrictemplate <class _Up> 151*0fca6ea1SDimitry Andricinline _LIBCPP_HIDE_FROM_ABI constexpr _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andrictemplate <class _Tp> 154cb14a3feSDimitry Andricclass propagate_const { 1550b57cec5SDimitry Andricpublic: 156bdd1243dSDimitry Andric typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type; 1570b57cec5SDimitry Andric 158cb14a3feSDimitry Andric static_assert(!is_array<_Tp>::value, "Instantiation of propagate_const with an array type is ill-formed."); 159cb14a3feSDimitry Andric static_assert(!is_reference<_Tp>::value, "Instantiation of propagate_const with a reference type is ill-formed."); 160bdd1243dSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value), 1610b57cec5SDimitry Andric "Instantiation of propagate_const with a function-pointer type is ill-formed."); 162bdd1243dSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value), 1630b57cec5SDimitry Andric "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andricprivate: 1660b57cec5SDimitry Andric template <class _Up> 167*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr element_type* __get_pointer(_Up* __u) { 1680b57cec5SDimitry Andric return __u; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric template <class _Up> 172*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr element_type* __get_pointer(_Up& __u) { 1730b57cec5SDimitry Andric return __get_pointer(__u.get()); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric template <class _Up> 177*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr const element_type* __get_pointer(const _Up* __u) { 1780b57cec5SDimitry Andric return __u; 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric template <class _Up> 182*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI constexpr const element_type* __get_pointer(const _Up& __u) { 1830b57cec5SDimitry Andric return __get_pointer(__u.get()); 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric template <class _Up> 187cb14a3feSDimitry Andric struct __is_propagate_const : false_type {}; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric template <class _Up> 190cb14a3feSDimitry Andric struct __is_propagate_const<propagate_const<_Up>> : true_type {}; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric _Tp __t_; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andricpublic: 195cb14a3feSDimitry Andric template <class _Up> 196*0fca6ea1SDimitry Andric friend constexpr const _Up& experimental::fundamentals_v2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 197cb14a3feSDimitry Andric template <class _Up> 198*0fca6ea1SDimitry Andric friend constexpr _Up& experimental::fundamentals_v2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1990b57cec5SDimitry Andric 200*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const() = default; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric propagate_const(const propagate_const&) = delete; 2030b57cec5SDimitry Andric 204*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const&&) = default; 2050b57cec5SDimitry Andric 206cb14a3feSDimitry Andric template <class _Up, 207cb14a3feSDimitry Andric enable_if_t<!is_convertible<_Up, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = true> 208*0fca6ea1SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const<_Up>&& __pu) 209cb14a3feSDimitry Andric : __t_(std::move(experimental::get_underlying(__pu))) {} 2100b57cec5SDimitry Andric 211cb14a3feSDimitry Andric template <class _Up, 212cb14a3feSDimitry Andric enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = false> 213*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const<_Up>&& __pu) 214cb14a3feSDimitry Andric : __t_(std::move(experimental::get_underlying(__pu))) {} 2150b57cec5SDimitry Andric 216cb14a3feSDimitry Andric template <class _Up, 217cb14a3feSDimitry Andric enable_if_t<!is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value && 218cb14a3feSDimitry Andric !__is_propagate_const<decay_t<_Up>>::value, 219cb14a3feSDimitry Andric bool> = true> 220*0fca6ea1SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {} 2210b57cec5SDimitry Andric 222cb14a3feSDimitry Andric template <class _Up, 223cb14a3feSDimitry Andric enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value && 224cb14a3feSDimitry Andric !__is_propagate_const<decay_t<_Up>>::value, 225cb14a3feSDimitry Andric bool> = false> 226*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {} 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric propagate_const& operator=(const propagate_const&) = delete; 2290b57cec5SDimitry Andric 230*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(propagate_const&&) = default; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric template <class _Up> 233*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(propagate_const<_Up>&& __pu) { 2345f757f3fSDimitry Andric __t_ = std::move(experimental::get_underlying(__pu)); 2350b57cec5SDimitry Andric return *this; 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> 239*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(_Up&& __u) { 2400b57cec5SDimitry Andric __t_ = std::forward<_Up>(__u); 2410b57cec5SDimitry Andric return *this; 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 244*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const element_type* get() const { return __get_pointer(__t_); } 2450b57cec5SDimitry Andric 246*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() { return __get_pointer(__t_); } 2470b57cec5SDimitry Andric 248*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit constexpr operator bool() const { return get() != nullptr; } 2490b57cec5SDimitry Andric 250*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const element_type* operator->() const { return get(); } 2510b57cec5SDimitry Andric 252cb14a3feSDimitry Andric template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible< const _Dummy, const element_type*>::value>> 253*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr operator const element_type*() const { 2540b57cec5SDimitry Andric return get(); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 257*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const element_type& operator*() const { return *get(); } 2580b57cec5SDimitry Andric 259*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() { return get(); } 2600b57cec5SDimitry Andric 261cb14a3feSDimitry Andric template <class _Dummy = _Tp, class _Up = enable_if_t< is_convertible<_Dummy, element_type*>::value>> 262*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr operator element_type*() { 2630b57cec5SDimitry Andric return get(); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 266*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type& operator*() { return *get(); } 2670b57cec5SDimitry Andric 268*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(propagate_const& __pt) noexcept(__is_nothrow_swappable_v<_Tp>) { 2695f757f3fSDimitry Andric using std::swap; 2700b57cec5SDimitry Andric swap(__t_, __pt.__t_); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric}; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andrictemplate <class _Tp> 275*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) { 2765f757f3fSDimitry Andric return experimental::get_underlying(__pt) == nullptr; 2770b57cec5SDimitry Andric} 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andrictemplate <class _Tp> 280*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) { 2815f757f3fSDimitry Andric return nullptr == experimental::get_underlying(__pt); 2820b57cec5SDimitry Andric} 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andrictemplate <class _Tp> 285*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) { 2865f757f3fSDimitry Andric return experimental::get_underlying(__pt) != nullptr; 2870b57cec5SDimitry Andric} 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andrictemplate <class _Tp> 290*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) { 2915f757f3fSDimitry Andric return nullptr != experimental::get_underlying(__pt); 2920b57cec5SDimitry Andric} 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 295*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 2965f757f3fSDimitry Andric return experimental::get_underlying(__pt) == experimental::get_underlying(__pu); 2970b57cec5SDimitry Andric} 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 300*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 3015f757f3fSDimitry Andric return experimental::get_underlying(__pt) != experimental::get_underlying(__pu); 3020b57cec5SDimitry Andric} 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 305*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 3065f757f3fSDimitry Andric return experimental::get_underlying(__pt) < experimental::get_underlying(__pu); 3070b57cec5SDimitry Andric} 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 310*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 3115f757f3fSDimitry Andric return experimental::get_underlying(__pt) > experimental::get_underlying(__pu); 3120b57cec5SDimitry Andric} 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 315*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 3165f757f3fSDimitry Andric return experimental::get_underlying(__pt) <= experimental::get_underlying(__pu); 3170b57cec5SDimitry Andric} 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 320*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) { 3215f757f3fSDimitry Andric return experimental::get_underlying(__pt) >= experimental::get_underlying(__pu); 3220b57cec5SDimitry Andric} 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 325*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) { 3265f757f3fSDimitry Andric return experimental::get_underlying(__pt) == __u; 3270b57cec5SDimitry Andric} 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 330*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) { 3315f757f3fSDimitry Andric return experimental::get_underlying(__pt) != __u; 3320b57cec5SDimitry Andric} 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 335*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) { 3365f757f3fSDimitry Andric return experimental::get_underlying(__pt) < __u; 3370b57cec5SDimitry Andric} 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 340*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) { 3415f757f3fSDimitry Andric return experimental::get_underlying(__pt) > __u; 3420b57cec5SDimitry Andric} 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 345*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) { 3465f757f3fSDimitry Andric return experimental::get_underlying(__pt) <= __u; 3470b57cec5SDimitry Andric} 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 350*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) { 3515f757f3fSDimitry Andric return experimental::get_underlying(__pt) >= __u; 3520b57cec5SDimitry Andric} 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 355*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) { 3565f757f3fSDimitry Andric return __t == experimental::get_underlying(__pu); 3570b57cec5SDimitry Andric} 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 360*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) { 3615f757f3fSDimitry Andric return __t != experimental::get_underlying(__pu); 3620b57cec5SDimitry Andric} 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 365*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) { 3665f757f3fSDimitry Andric return __t < experimental::get_underlying(__pu); 3670b57cec5SDimitry Andric} 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 370*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) { 3715f757f3fSDimitry Andric return __t > experimental::get_underlying(__pu); 3720b57cec5SDimitry Andric} 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 375*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) { 3765f757f3fSDimitry Andric return __t <= experimental::get_underlying(__pu); 3770b57cec5SDimitry Andric} 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 380*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) { 3815f757f3fSDimitry Andric return __t >= experimental::get_underlying(__pu); 3820b57cec5SDimitry Andric} 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andrictemplate <class _Tp> 385*0fca6ea1SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void 386*0fca6ea1SDimitry Andricswap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) noexcept(__is_nothrow_swappable_v<_Tp>) { 3870b57cec5SDimitry Andric __pc1.swap(__pc2); 3880b57cec5SDimitry Andric} 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andrictemplate <class _Tp> 391*0fca6ea1SDimitry Andricconstexpr const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT { 3920b57cec5SDimitry Andric return __pt.__t_; 3930b57cec5SDimitry Andric} 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andrictemplate <class _Tp> 396*0fca6ea1SDimitry Andricconstexpr _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT { 3970b57cec5SDimitry Andric return __pt.__t_; 3980b57cec5SDimitry Andric} 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andrictemplate <class _Tp> 405cb14a3feSDimitry Andricstruct hash<experimental::propagate_const<_Tp>> { 4060b57cec5SDimitry Andric typedef size_t result_type; 4075f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> argument_type; 4080b57cec5SDimitry Andric 409cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::propagate_const<_Tp>& __pc1) const { 4105f757f3fSDimitry Andric return std::hash<_Tp>()(experimental::get_underlying(__pc1)); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric}; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andrictemplate <class _Tp> 415cb14a3feSDimitry Andricstruct equal_to<experimental::propagate_const<_Tp>> { 4165f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4175f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4180b57cec5SDimitry Andric 419cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 420cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4215f757f3fSDimitry Andric return std::equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric}; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andrictemplate <class _Tp> 426cb14a3feSDimitry Andricstruct not_equal_to<experimental::propagate_const<_Tp>> { 4275f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4285f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4290b57cec5SDimitry Andric 430cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 431cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4325f757f3fSDimitry Andric return std::not_equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric}; 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andrictemplate <class _Tp> 437cb14a3feSDimitry Andricstruct less<experimental::propagate_const<_Tp>> { 4385f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4395f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4400b57cec5SDimitry Andric 441cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 442cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4435f757f3fSDimitry Andric return std::less<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric}; 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andrictemplate <class _Tp> 448cb14a3feSDimitry Andricstruct greater<experimental::propagate_const<_Tp>> { 4495f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4505f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4510b57cec5SDimitry Andric 452cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 453cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4545f757f3fSDimitry Andric return std::greater<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric}; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andrictemplate <class _Tp> 459cb14a3feSDimitry Andricstruct less_equal<experimental::propagate_const<_Tp>> { 4605f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4615f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4620b57cec5SDimitry Andric 463cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 464cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4655f757f3fSDimitry Andric return std::less_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric}; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andrictemplate <class _Tp> 470cb14a3feSDimitry Andricstruct greater_equal<experimental::propagate_const<_Tp>> { 4715f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> first_argument_type; 4725f757f3fSDimitry Andric typedef experimental::propagate_const<_Tp> second_argument_type; 4730b57cec5SDimitry Andric 474cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool 475cb14a3feSDimitry Andric operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const { 4765f757f3fSDimitry Andric return std::greater_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2)); 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric}; 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 4810b57cec5SDimitry Andric 48206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14 48306c3fb27SDimitry Andric 48406c3fb27SDimitry Andric_LIBCPP_POP_MACROS 48506c3fb27SDimitry Andric 48606c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 48706c3fb27SDimitry Andric# include <type_traits> 48806c3fb27SDimitry Andric#endif 48906c3fb27SDimitry Andric 4900b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 491