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