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