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 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 11081ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 11181ad6265SDimitry Andric#include <__functional/operations.h> 112bdd1243dSDimitry Andric#include <__fwd/hash.h> 113*06c3fb27SDimitry Andric#include <__type_traits/conditional.h> 114*06c3fb27SDimitry Andric#include <__type_traits/decay.h> 115*06c3fb27SDimitry Andric#include <__type_traits/enable_if.h> 116*06c3fb27SDimitry Andric#include <__type_traits/is_array.h> 117*06c3fb27SDimitry Andric#include <__type_traits/is_constructible.h> 118*06c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 119*06c3fb27SDimitry Andric#include <__type_traits/is_function.h> 120*06c3fb27SDimitry Andric#include <__type_traits/is_pointer.h> 121*06c3fb27SDimitry Andric#include <__type_traits/is_reference.h> 122*06c3fb27SDimitry Andric#include <__type_traits/is_same.h> 123*06c3fb27SDimitry Andric#include <__type_traits/is_swappable.h> 124*06c3fb27SDimitry Andric#include <__type_traits/remove_cv.h> 125*06c3fb27SDimitry Andric#include <__type_traits/remove_pointer.h> 126*06c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 127*06c3fb27SDimitry Andric#include <__utility/declval.h> 12881ad6265SDimitry Andric#include <__utility/forward.h> 12981ad6265SDimitry Andric#include <__utility/move.h> 13081ad6265SDimitry Andric#include <__utility/swap.h> 131*06c3fb27SDimitry Andric#include <cstddef> 1320b57cec5SDimitry Andric#include <experimental/__config> 13304eeddc0SDimitry Andric 1340b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1350b57cec5SDimitry Andric# pragma GCC system_header 1360b57cec5SDimitry Andric#endif 1370b57cec5SDimitry Andric 138*06c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS 139*06c3fb27SDimitry Andric#include <__undef_macros> 140*06c3fb27SDimitry Andric 141*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 14 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andrictemplate <class _Tp> 1460b57cec5SDimitry Andricclass propagate_const; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andrictemplate <class _Up> 1490b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1500b57cec5SDimitry Andricconst _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andrictemplate <class _Up> 1530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1540b57cec5SDimitry Andric_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andrictemplate <class _Tp> 1570b57cec5SDimitry Andricclass propagate_const 1580b57cec5SDimitry Andric{ 1590b57cec5SDimitry Andricpublic: 160bdd1243dSDimitry Andric typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric static_assert(!is_array<_Tp>::value, 1630b57cec5SDimitry Andric "Instantiation of propagate_const with an array type is ill-formed."); 1640b57cec5SDimitry Andric static_assert(!is_reference<_Tp>::value, 1650b57cec5SDimitry Andric "Instantiation of propagate_const with a reference type is ill-formed."); 166bdd1243dSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value), 1670b57cec5SDimitry Andric "Instantiation of propagate_const with a function-pointer type is ill-formed."); 168bdd1243dSDimitry Andric static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value), 1690b57cec5SDimitry Andric "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andricprivate: 1720b57cec5SDimitry Andric template <class _Up> 173*06c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) 1740b57cec5SDimitry Andric { 1750b57cec5SDimitry Andric return __u; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric template <class _Up> 179*06c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) 1800b57cec5SDimitry Andric { 1810b57cec5SDimitry Andric return __get_pointer(__u.get()); 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric template <class _Up> 185*06c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) 1860b57cec5SDimitry Andric { 1870b57cec5SDimitry Andric return __u; 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric template <class _Up> 191*06c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) 1920b57cec5SDimitry Andric { 1930b57cec5SDimitry Andric return __get_pointer(__u.get()); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric template <class _Up> 1970b57cec5SDimitry Andric struct __is_propagate_const : false_type 1980b57cec5SDimitry Andric { 1990b57cec5SDimitry Andric }; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric template <class _Up> 2020b57cec5SDimitry Andric struct __is_propagate_const<propagate_const<_Up>> : true_type 2030b57cec5SDimitry Andric { 2040b57cec5SDimitry Andric }; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric _Tp __t_; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andricpublic: 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; 2110b57cec5SDimitry Andric template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; 2120b57cec5SDimitry Andric 213*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric propagate_const(const propagate_const&) = delete; 2160b57cec5SDimitry Andric 217*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && 2200b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = true> 221*06c3fb27SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 2220b57cec5SDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2230b57cec5SDimitry Andric { 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2270b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value,bool> = false> 228*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) 2290b57cec5SDimitry Andric : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) 2300b57cec5SDimitry Andric { 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && 2340b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value && 2350b57cec5SDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = true> 236*06c3fb27SDimitry Andric explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2370b57cec5SDimitry Andric : __t_(std::forward<_Up>(__u)) 2380b57cec5SDimitry Andric { 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && 2420b57cec5SDimitry Andric is_constructible<_Tp, _Up&&>::value && 2430b57cec5SDimitry Andric !__is_propagate_const<decay_t<_Up>>::value,bool> = false> 244*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) 2450b57cec5SDimitry Andric : __t_(std::forward<_Up>(__u)) 2460b57cec5SDimitry Andric { 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric propagate_const& operator=(const propagate_const&) = delete; 2500b57cec5SDimitry Andric 251*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric template <class _Up> 254*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) 2550b57cec5SDimitry Andric { 2560b57cec5SDimitry Andric __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); 2570b57cec5SDimitry Andric return *this; 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> 261*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) 2620b57cec5SDimitry Andric { 2630b57cec5SDimitry Andric __t_ = std::forward<_Up>(__u); 2640b57cec5SDimitry Andric return *this; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 267*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const 2680b57cec5SDimitry Andric { 2690b57cec5SDimitry Andric return __get_pointer(__t_); 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 272*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get() 2730b57cec5SDimitry Andric { 2740b57cec5SDimitry Andric return __get_pointer(__t_); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 277*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const 2780b57cec5SDimitry Andric { 2790b57cec5SDimitry Andric return get() != nullptr; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 282*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const 2830b57cec5SDimitry Andric { 2840b57cec5SDimitry Andric return get(); 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 287*06c3fb27SDimitry Andric template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible< 288*06c3fb27SDimitry Andric const _Dummy, const element_type *>::value>> 289*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const { 2900b57cec5SDimitry Andric return get(); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 293*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const 2940b57cec5SDimitry Andric { 2950b57cec5SDimitry Andric return *get(); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 298*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->() 2990b57cec5SDimitry Andric { 3000b57cec5SDimitry Andric return get(); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric 303*06c3fb27SDimitry Andric template <class _Dummy = _Tp, class _Up = enable_if_t< 304*06c3fb27SDimitry Andric is_convertible<_Dummy, element_type *>::value>> 305*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() { 3060b57cec5SDimitry Andric return get(); 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric 309*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*() 3100b57cec5SDimitry Andric { 3110b57cec5SDimitry Andric return *get(); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 314*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) 315*06c3fb27SDimitry Andric _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { 3160b57cec5SDimitry Andric using _VSTD::swap; 3170b57cec5SDimitry Andric swap(__t_, __pt.__t_); 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric}; 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andrictemplate <class _Tp> 3230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3240b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) 3250b57cec5SDimitry Andric{ 3260b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; 3270b57cec5SDimitry Andric} 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andrictemplate <class _Tp> 3300b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3310b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) 3320b57cec5SDimitry Andric{ 3330b57cec5SDimitry Andric return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); 3340b57cec5SDimitry Andric} 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andrictemplate <class _Tp> 3370b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3380b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) 3390b57cec5SDimitry Andric{ 3400b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; 3410b57cec5SDimitry Andric} 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andrictemplate <class _Tp> 3440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3450b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) 3460b57cec5SDimitry Andric{ 3470b57cec5SDimitry Andric return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); 3480b57cec5SDimitry Andric} 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3510b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3520b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, 3530b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3540b57cec5SDimitry Andric{ 3550b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); 3560b57cec5SDimitry Andric} 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3600b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, 3610b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3620b57cec5SDimitry Andric{ 3630b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); 3640b57cec5SDimitry Andric} 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3680b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, 3690b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3700b57cec5SDimitry Andric{ 3710b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); 3720b57cec5SDimitry Andric} 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3760b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, 3770b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3780b57cec5SDimitry Andric{ 3790b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); 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, 3850b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3860b57cec5SDimitry Andric{ 3870b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); 3880b57cec5SDimitry Andric} 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 3920b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, 3930b57cec5SDimitry Andric const propagate_const<_Up>& __pu) 3940b57cec5SDimitry Andric{ 3950b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); 3960b57cec5SDimitry Andric} 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 3990b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4000b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) 4010b57cec5SDimitry Andric{ 4020b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) == __u; 4030b57cec5SDimitry Andric} 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4070b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) 4080b57cec5SDimitry Andric{ 4090b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) != __u; 4100b57cec5SDimitry Andric} 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4140b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) 4150b57cec5SDimitry Andric{ 4160b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) < __u; 4170b57cec5SDimitry Andric} 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4200b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4210b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) 4220b57cec5SDimitry Andric{ 4230b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) > __u; 4240b57cec5SDimitry Andric} 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4270b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4280b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) 4290b57cec5SDimitry Andric{ 4300b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; 4310b57cec5SDimitry Andric} 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4350b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) 4360b57cec5SDimitry Andric{ 4370b57cec5SDimitry Andric return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; 4380b57cec5SDimitry Andric} 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4430b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) 4440b57cec5SDimitry Andric{ 4450b57cec5SDimitry Andric return __t == _VSTD_LFTS_V2::get_underlying(__pu); 4460b57cec5SDimitry Andric} 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4500b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) 4510b57cec5SDimitry Andric{ 4520b57cec5SDimitry Andric return __t != _VSTD_LFTS_V2::get_underlying(__pu); 4530b57cec5SDimitry Andric} 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4560b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4570b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) 4580b57cec5SDimitry Andric{ 4590b57cec5SDimitry Andric return __t < _VSTD_LFTS_V2::get_underlying(__pu); 4600b57cec5SDimitry Andric} 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4630b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4640b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) 4650b57cec5SDimitry Andric{ 4660b57cec5SDimitry Andric return __t > _VSTD_LFTS_V2::get_underlying(__pu); 4670b57cec5SDimitry Andric} 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4710b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) 4720b57cec5SDimitry Andric{ 4730b57cec5SDimitry Andric return __t <= _VSTD_LFTS_V2::get_underlying(__pu); 4740b57cec5SDimitry Andric} 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andrictemplate <class _Tp, class _Up> 4770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4780b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) 4790b57cec5SDimitry Andric{ 4800b57cec5SDimitry Andric return __t >= _VSTD_LFTS_V2::get_underlying(__pu); 4810b57cec5SDimitry Andric} 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andrictemplate <class _Tp> 4840b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 4850b57cec5SDimitry Andric_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) 4860b57cec5SDimitry Andric{ 4870b57cec5SDimitry Andric __pc1.swap(__pc2); 4880b57cec5SDimitry Andric} 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andrictemplate <class _Tp> 4910b57cec5SDimitry Andric_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT 4920b57cec5SDimitry Andric{ 4930b57cec5SDimitry Andric return __pt.__t_; 4940b57cec5SDimitry Andric} 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andrictemplate <class _Tp> 4970b57cec5SDimitry Andric_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT 4980b57cec5SDimitry Andric{ 4990b57cec5SDimitry Andric return __pt.__t_; 5000b57cec5SDimitry Andric} 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andrictemplate <class _Tp> 5070b57cec5SDimitry Andricstruct hash<experimental::fundamentals_v2::propagate_const<_Tp>> 5080b57cec5SDimitry Andric{ 5090b57cec5SDimitry Andric typedef size_t result_type; 5100b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; 5110b57cec5SDimitry Andric 512*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const 5130b57cec5SDimitry Andric { 5140b57cec5SDimitry Andric return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric}; 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andrictemplate <class _Tp> 5190b57cec5SDimitry Andricstruct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 5200b57cec5SDimitry Andric{ 5210b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5220b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5230b57cec5SDimitry Andric 524*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5250b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5260b57cec5SDimitry Andric { 5270b57cec5SDimitry Andric return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric}; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andrictemplate <class _Tp> 5320b57cec5SDimitry Andricstruct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> 5330b57cec5SDimitry Andric{ 5340b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5350b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5360b57cec5SDimitry Andric 537*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5380b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5390b57cec5SDimitry Andric { 5400b57cec5SDimitry Andric return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric}; 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andrictemplate <class _Tp> 5450b57cec5SDimitry Andricstruct less<experimental::fundamentals_v2::propagate_const<_Tp>> 5460b57cec5SDimitry Andric{ 5470b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5480b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5490b57cec5SDimitry Andric 550*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5510b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5520b57cec5SDimitry Andric { 5530b57cec5SDimitry Andric return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5540b57cec5SDimitry Andric } 5550b57cec5SDimitry Andric}; 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andrictemplate <class _Tp> 5580b57cec5SDimitry Andricstruct greater<experimental::fundamentals_v2::propagate_const<_Tp>> 5590b57cec5SDimitry Andric{ 5600b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5610b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5620b57cec5SDimitry Andric 563*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5640b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5650b57cec5SDimitry Andric { 5660b57cec5SDimitry Andric return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric}; 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andrictemplate <class _Tp> 5710b57cec5SDimitry Andricstruct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5720b57cec5SDimitry Andric{ 5730b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5740b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5750b57cec5SDimitry Andric 576*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5770b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5780b57cec5SDimitry Andric { 5790b57cec5SDimitry Andric return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric}; 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andrictemplate <class _Tp> 5840b57cec5SDimitry Andricstruct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> 5850b57cec5SDimitry Andric{ 5860b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; 5870b57cec5SDimitry Andric typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; 5880b57cec5SDimitry Andric 589*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, 5900b57cec5SDimitry Andric const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const 5910b57cec5SDimitry Andric { 5920b57cec5SDimitry Andric return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); 5930b57cec5SDimitry Andric } 5940b57cec5SDimitry Andric}; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5970b57cec5SDimitry Andric 598*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 14 599*06c3fb27SDimitry Andric 600*06c3fb27SDimitry Andric_LIBCPP_POP_MACROS 601*06c3fb27SDimitry Andric 602*06c3fb27SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 603*06c3fb27SDimitry Andric# include <type_traits> 604*06c3fb27SDimitry Andric#endif 605*06c3fb27SDimitry Andric 6060b57cec5SDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST 607