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