17c82a1ecSDimitry Andric// -*- C++ -*-
27c82a1ecSDimitry Andric//===------------------------ propagate_const -----------------------------===//
37c82a1ecSDimitry Andric//
47c82a1ecSDimitry Andric//                     The LLVM Compiler Infrastructure
57c82a1ecSDimitry Andric//
67c82a1ecSDimitry Andric// This file is dual licensed under the MIT and the University of Illinois Open
77c82a1ecSDimitry Andric// Source Licenses. See LICENSE.TXT for details.
87c82a1ecSDimitry Andric//
97c82a1ecSDimitry Andric//===----------------------------------------------------------------------===//
107c82a1ecSDimitry Andric
117c82a1ecSDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
127c82a1ecSDimitry Andric#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
137c82a1ecSDimitry Andric/*
147c82a1ecSDimitry Andric    propagate_const synopsis
157c82a1ecSDimitry Andric
167c82a1ecSDimitry Andric    namespace std { namespace experimental { inline namespace fundamentals_v2 {
177c82a1ecSDimitry Andric
187c82a1ecSDimitry Andric    // [propagate_const]
197c82a1ecSDimitry Andric    template <class T> class propagate_const;
207c82a1ecSDimitry Andric
217c82a1ecSDimitry Andric    // [propagate_const.underlying], underlying pointer access
227c82a1ecSDimitry Andric    constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept;
237c82a1ecSDimitry Andric    constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept;
247c82a1ecSDimitry Andric
257c82a1ecSDimitry Andric    // [propagate_const.relational], relational operators
267c82a1ecSDimitry Andric    template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t);
277c82a1ecSDimitry Andric    template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu);
287c82a1ecSDimitry Andric    template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t);
297c82a1ecSDimitry Andric    template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu);
307c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
317c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
327c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
337c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
347c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
357c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
367c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u);
377c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u);
387c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u);
397c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u);
407c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u);
417c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u);
427c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu);
437c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu);
447c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu);
457c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu);
467c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu);
477c82a1ecSDimitry Andric    template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu);
487c82a1ecSDimitry Andric
497c82a1ecSDimitry Andric    // [propagate_const.algorithms], specialized algorithms
507c82a1ecSDimitry Andric    template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below);
517c82a1ecSDimitry Andric
527c82a1ecSDimitry Andric    template <class T>
537c82a1ecSDimitry Andric    class propagate_const
547c82a1ecSDimitry Andric    {
557c82a1ecSDimitry Andric
567c82a1ecSDimitry Andric    public:
577c82a1ecSDimitry Andric      typedef remove_reference_t<decltype(*declval<T&>())> element_type;
587c82a1ecSDimitry Andric
597c82a1ecSDimitry Andric      // [propagate_const.ctor], constructors
607c82a1ecSDimitry Andric      constexpr propagate_const() = default;
617c82a1ecSDimitry Andric      propagate_const(const propagate_const& p) = delete;
627c82a1ecSDimitry Andric      constexpr propagate_const(propagate_const&& p) = default;
637c82a1ecSDimitry Andric      template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below
647c82a1ecSDimitry Andric      template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below
657c82a1ecSDimitry Andric
667c82a1ecSDimitry Andric      // [propagate_const.assignment], assignment
677c82a1ecSDimitry Andric      propagate_const& operator=(const propagate_const& p) = delete;
687c82a1ecSDimitry Andric      constexpr propagate_const& operator=(propagate_const&& p) = default;
697c82a1ecSDimitry Andric      template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
707c82a1ecSDimitry Andric      template <class U> constexpr propagate_const& operator=(U&& u); // see below
717c82a1ecSDimitry Andric
727c82a1ecSDimitry Andric      // [propagate_const.const_observers], const observers
737c82a1ecSDimitry Andric      explicit constexpr operator bool() const;
747c82a1ecSDimitry Andric      constexpr const element_type* operator->() const;
757c82a1ecSDimitry Andric      constexpr operator const element_type*() const; // Not always defined
767c82a1ecSDimitry Andric      constexpr const element_type& operator*() const;
777c82a1ecSDimitry Andric      constexpr const element_type* get() const;
787c82a1ecSDimitry Andric
797c82a1ecSDimitry Andric      // [propagate_const.non_const_observers], non-const observers
807c82a1ecSDimitry Andric      constexpr element_type* operator->();
817c82a1ecSDimitry Andric      constexpr operator element_type*(); // Not always defined
827c82a1ecSDimitry Andric      constexpr element_type& operator*();
837c82a1ecSDimitry Andric      constexpr element_type* get();
847c82a1ecSDimitry Andric
857c82a1ecSDimitry Andric      // [propagate_const.modifiers], modifiers
867c82a1ecSDimitry Andric      constexpr void swap(propagate_const& pt) noexcept(see below)
877c82a1ecSDimitry Andric
887c82a1ecSDimitry Andric    private:
897c82a1ecSDimitry Andric      T t_; // exposition only
907c82a1ecSDimitry Andric    };
917c82a1ecSDimitry Andric
927c82a1ecSDimitry Andric  } // namespace fundamentals_v2
937c82a1ecSDimitry Andric  } // namespace experimental
947c82a1ecSDimitry Andric
957c82a1ecSDimitry Andric  // [propagate_const.hash], hash support
967c82a1ecSDimitry Andric  template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>;
977c82a1ecSDimitry Andric
987c82a1ecSDimitry Andric  // [propagate_const.comparison_function_objects], comparison function objects
997c82a1ecSDimitry Andric  template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>;
1007c82a1ecSDimitry Andric  template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>;
1017c82a1ecSDimitry Andric  template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>;
1027c82a1ecSDimitry Andric  template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>;
1037c82a1ecSDimitry Andric  template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>;
1047c82a1ecSDimitry Andric  template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>;
1057c82a1ecSDimitry Andric
1067c82a1ecSDimitry Andric} // namespace std
1077c82a1ecSDimitry Andric
1087c82a1ecSDimitry Andric*/
1097c82a1ecSDimitry Andric
1107c82a1ecSDimitry Andric#include <experimental/__config>
1117c82a1ecSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1127c82a1ecSDimitry Andric#pragma GCC system_header
1137c82a1ecSDimitry Andric#endif
1147c82a1ecSDimitry Andric
1157c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 11
1167c82a1ecSDimitry Andric
1177c82a1ecSDimitry Andric#include <type_traits>
1187c82a1ecSDimitry Andric#include <utility>
1197c82a1ecSDimitry Andric#include <functional>
1207c82a1ecSDimitry Andric
1217c82a1ecSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
1227c82a1ecSDimitry Andric
1237c82a1ecSDimitry Andric
1247c82a1ecSDimitry Andrictemplate <class _Tp>
1257c82a1ecSDimitry Andricclass propagate_const;
126aed8d94eSDimitry Andric
127aed8d94eSDimitry Andrictemplate <class _Up>
128aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
129aed8d94eSDimitry Andricconst _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
130aed8d94eSDimitry Andric
131aed8d94eSDimitry Andrictemplate <class _Up>
132aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
133aed8d94eSDimitry Andric_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
1347c82a1ecSDimitry Andric
1357c82a1ecSDimitry Andrictemplate <class _Tp>
1367c82a1ecSDimitry Andricclass propagate_const
1377c82a1ecSDimitry Andric{
1387c82a1ecSDimitry Andricpublic:
1397c82a1ecSDimitry Andric  typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type;
1407c82a1ecSDimitry Andric
1417c82a1ecSDimitry Andric  static_assert(!is_array<_Tp>::value,
1427c82a1ecSDimitry Andric      "Instantiation of propagate_const with an array type is ill-formed.");
1437c82a1ecSDimitry Andric  static_assert(!is_reference<_Tp>::value,
1447c82a1ecSDimitry Andric      "Instantiation of propagate_const with a reference type is ill-formed.");
1457c82a1ecSDimitry Andric  static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value),
1467c82a1ecSDimitry Andric      "Instantiation of propagate_const with a function-pointer type is ill-formed.");
1477c82a1ecSDimitry Andric  static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value),
1487c82a1ecSDimitry Andric      "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed.");
1497c82a1ecSDimitry Andric
1507c82a1ecSDimitry Andricprivate:
1517c82a1ecSDimitry Andric  template <class _Up>
1527c82a1ecSDimitry Andric  static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u)
1537c82a1ecSDimitry Andric  {
1547c82a1ecSDimitry Andric    return __u;
1557c82a1ecSDimitry Andric  }
1567c82a1ecSDimitry Andric
1577c82a1ecSDimitry Andric  template <class _Up>
1587c82a1ecSDimitry Andric  static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u)
1597c82a1ecSDimitry Andric  {
1607c82a1ecSDimitry Andric    return __get_pointer(__u.get());
1617c82a1ecSDimitry Andric  }
1627c82a1ecSDimitry Andric
1637c82a1ecSDimitry Andric  template <class _Up>
1647c82a1ecSDimitry Andric  static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u)
1657c82a1ecSDimitry Andric  {
1667c82a1ecSDimitry Andric    return __u;
1677c82a1ecSDimitry Andric  }
1687c82a1ecSDimitry Andric
1697c82a1ecSDimitry Andric  template <class _Up>
1707c82a1ecSDimitry Andric  static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u)
1717c82a1ecSDimitry Andric  {
1727c82a1ecSDimitry Andric    return __get_pointer(__u.get());
1737c82a1ecSDimitry Andric  }
1747c82a1ecSDimitry Andric
1757c82a1ecSDimitry Andric  template <class _Up>
1767c82a1ecSDimitry Andric  struct __is_propagate_const : false_type
1777c82a1ecSDimitry Andric  {
1787c82a1ecSDimitry Andric  };
1797c82a1ecSDimitry Andric
1807c82a1ecSDimitry Andric  template <class _Up>
1817c82a1ecSDimitry Andric  struct __is_propagate_const<propagate_const<_Up>> : true_type
1827c82a1ecSDimitry Andric  {
1837c82a1ecSDimitry Andric  };
1847c82a1ecSDimitry Andric
1857c82a1ecSDimitry Andric  _Tp __t_;
1867c82a1ecSDimitry Andric
1877c82a1ecSDimitry Andricpublic:
1887c82a1ecSDimitry Andric
1897c82a1ecSDimitry Andric  template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
1907c82a1ecSDimitry Andric  template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
1917c82a1ecSDimitry Andric
1927c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const() = default;
1937c82a1ecSDimitry Andric
1947c82a1ecSDimitry Andric  propagate_const(const propagate_const&) = delete;
1957c82a1ecSDimitry Andric
1967c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default;
1977c82a1ecSDimitry Andric
1987c82a1ecSDimitry Andric  template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value &&
1997c82a1ecSDimitry Andric                                 is_constructible<_Tp, _Up&&>::value,bool> = true>
2007c82a1ecSDimitry Andric  explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
2017c82a1ecSDimitry Andric      : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
2027c82a1ecSDimitry Andric  {
2037c82a1ecSDimitry Andric  }
2047c82a1ecSDimitry Andric
2057c82a1ecSDimitry Andric  template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
2067c82a1ecSDimitry Andric                                 is_constructible<_Tp, _Up&&>::value,bool> = false>
2077c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu)
2087c82a1ecSDimitry Andric      : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu)))
2097c82a1ecSDimitry Andric  {
2107c82a1ecSDimitry Andric  }
2117c82a1ecSDimitry Andric
2127c82a1ecSDimitry Andric  template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value &&
2137c82a1ecSDimitry Andric                                 is_constructible<_Tp, _Up&&>::value &&
2147c82a1ecSDimitry Andric                                 !__is_propagate_const<decay_t<_Up>>::value,bool> = true>
2157c82a1ecSDimitry Andric  explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
2167c82a1ecSDimitry Andric      : __t_(std::forward<_Up>(__u))
2177c82a1ecSDimitry Andric  {
2187c82a1ecSDimitry Andric  }
2197c82a1ecSDimitry Andric
2207c82a1ecSDimitry Andric  template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value &&
2217c82a1ecSDimitry Andric                                 is_constructible<_Tp, _Up&&>::value &&
2227c82a1ecSDimitry Andric                                 !__is_propagate_const<decay_t<_Up>>::value,bool> = false>
2237c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const(_Up&& __u)
2247c82a1ecSDimitry Andric      : __t_(std::forward<_Up>(__u))
2257c82a1ecSDimitry Andric  {
2267c82a1ecSDimitry Andric  }
2277c82a1ecSDimitry Andric
2287c82a1ecSDimitry Andric  propagate_const& operator=(const propagate_const&) = delete;
2297c82a1ecSDimitry Andric
2307c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default;
2317c82a1ecSDimitry Andric
2327c82a1ecSDimitry Andric  template <class _Up>
2337c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu)
2347c82a1ecSDimitry Andric  {
2357c82a1ecSDimitry Andric    __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu));
2367c82a1ecSDimitry Andric    return *this;
2377c82a1ecSDimitry Andric  }
2387c82a1ecSDimitry Andric
2397c82a1ecSDimitry Andric  template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
2407c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u)
2417c82a1ecSDimitry Andric  {
2427c82a1ecSDimitry Andric    __t_ = std::forward<_Up>(__u);
2437c82a1ecSDimitry Andric    return *this;
2447c82a1ecSDimitry Andric  }
2457c82a1ecSDimitry Andric
2467c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR const element_type* get() const
2477c82a1ecSDimitry Andric  {
2487c82a1ecSDimitry Andric    return __get_pointer(__t_);
2497c82a1ecSDimitry Andric  }
2507c82a1ecSDimitry Andric
2517c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR element_type* get()
2527c82a1ecSDimitry Andric  {
2537c82a1ecSDimitry Andric    return __get_pointer(__t_);
2547c82a1ecSDimitry Andric  }
2557c82a1ecSDimitry Andric
2567c82a1ecSDimitry Andric  explicit _LIBCPP_CONSTEXPR operator bool() const
2577c82a1ecSDimitry Andric  {
2587c82a1ecSDimitry Andric    return get() != nullptr;
2597c82a1ecSDimitry Andric  }
2607c82a1ecSDimitry Andric
2617c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR const element_type* operator->() const
2627c82a1ecSDimitry Andric  {
2637c82a1ecSDimitry Andric    return get();
2647c82a1ecSDimitry Andric  }
2657c82a1ecSDimitry Andric
2667c82a1ecSDimitry Andric  template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible<
2677c82a1ecSDimitry Andric                                  const _Tp_, const element_type *>::value>>
2687c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR operator const element_type *() const {
2697c82a1ecSDimitry Andric    return get();
2707c82a1ecSDimitry Andric  }
2717c82a1ecSDimitry Andric
2727c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR const element_type& operator*() const
2737c82a1ecSDimitry Andric  {
2747c82a1ecSDimitry Andric    return *get();
2757c82a1ecSDimitry Andric  }
2767c82a1ecSDimitry Andric
2777c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR element_type* operator->()
2787c82a1ecSDimitry Andric  {
2797c82a1ecSDimitry Andric    return get();
2807c82a1ecSDimitry Andric  }
2817c82a1ecSDimitry Andric
2827c82a1ecSDimitry Andric  template <class _Tp_ = _Tp, class _Up = enable_if_t<
2837c82a1ecSDimitry Andric                                  is_convertible<_Tp_, element_type *>::value>>
2847c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR operator element_type *() {
2857c82a1ecSDimitry Andric    return get();
2867c82a1ecSDimitry Andric  }
2877c82a1ecSDimitry Andric
2887c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR element_type& operator*()
2897c82a1ecSDimitry Andric  {
2907c82a1ecSDimitry Andric    return *get();
2917c82a1ecSDimitry Andric  }
2927c82a1ecSDimitry Andric
2937c82a1ecSDimitry Andric  _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
2947c82a1ecSDimitry Andric  {
2957c82a1ecSDimitry Andric    using _VSTD::swap;
2967c82a1ecSDimitry Andric    swap(__t_, __pt.__t_);
2977c82a1ecSDimitry Andric  }
2987c82a1ecSDimitry Andric};
2997c82a1ecSDimitry Andric
3007c82a1ecSDimitry Andric
3017c82a1ecSDimitry Andrictemplate <class _Tp>
3027c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3037c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t)
3047c82a1ecSDimitry Andric{
3057c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr;
3067c82a1ecSDimitry Andric}
3077c82a1ecSDimitry Andric
3087c82a1ecSDimitry Andrictemplate <class _Tp>
3097c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3107c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt)
3117c82a1ecSDimitry Andric{
3127c82a1ecSDimitry Andric  return nullptr == _VSTD_LFTS_V2::get_underlying(__pt);
3137c82a1ecSDimitry Andric}
3147c82a1ecSDimitry Andric
3157c82a1ecSDimitry Andrictemplate <class _Tp>
3167c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3177c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
3187c82a1ecSDimitry Andric{
3197c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr;
3207c82a1ecSDimitry Andric}
3217c82a1ecSDimitry Andric
3227c82a1ecSDimitry Andrictemplate <class _Tp>
3237c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3247c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt)
3257c82a1ecSDimitry Andric{
3267c82a1ecSDimitry Andric  return nullptr != _VSTD_LFTS_V2::get_underlying(__pt);
3277c82a1ecSDimitry Andric}
3287c82a1ecSDimitry Andric
3297c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3307c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3317c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt,
3327c82a1ecSDimitry Andric                          const propagate_const<_Up>& __pu)
3337c82a1ecSDimitry Andric{
3347c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu);
3357c82a1ecSDimitry Andric}
3367c82a1ecSDimitry Andric
3377c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3387c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3397c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt,
3407c82a1ecSDimitry Andric                          const propagate_const<_Up>& __pu)
3417c82a1ecSDimitry Andric{
3427c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu);
3437c82a1ecSDimitry Andric}
3447c82a1ecSDimitry Andric
3457c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3467c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3477c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt,
3487c82a1ecSDimitry Andric                         const propagate_const<_Up>& __pu)
3497c82a1ecSDimitry Andric{
3507c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu);
3517c82a1ecSDimitry Andric}
3527c82a1ecSDimitry Andric
3537c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3547c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3557c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt,
3567c82a1ecSDimitry Andric                         const propagate_const<_Up>& __pu)
3577c82a1ecSDimitry Andric{
3587c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu);
3597c82a1ecSDimitry Andric}
3607c82a1ecSDimitry Andric
3617c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3627c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3637c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt,
3647c82a1ecSDimitry Andric                          const propagate_const<_Up>& __pu)
3657c82a1ecSDimitry Andric{
3667c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu);
3677c82a1ecSDimitry Andric}
3687c82a1ecSDimitry Andric
3697c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3707c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3717c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt,
3727c82a1ecSDimitry Andric                          const propagate_const<_Up>& __pu)
3737c82a1ecSDimitry Andric{
3747c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu);
3757c82a1ecSDimitry Andric}
3767c82a1ecSDimitry Andric
3777c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3787c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3797c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
3807c82a1ecSDimitry Andric{
3817c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) == __u;
3827c82a1ecSDimitry Andric}
3837c82a1ecSDimitry Andric
3847c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3857c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3867c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
3877c82a1ecSDimitry Andric{
3887c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) != __u;
3897c82a1ecSDimitry Andric}
3907c82a1ecSDimitry Andric
3917c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3927c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
3937c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
3947c82a1ecSDimitry Andric{
3957c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) < __u;
3967c82a1ecSDimitry Andric}
3977c82a1ecSDimitry Andric
3987c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
3997c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4007c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
4017c82a1ecSDimitry Andric{
4027c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) > __u;
4037c82a1ecSDimitry Andric}
4047c82a1ecSDimitry Andric
4057c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4067c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4077c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
4087c82a1ecSDimitry Andric{
4097c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) <= __u;
4107c82a1ecSDimitry Andric}
4117c82a1ecSDimitry Andric
4127c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4137c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4147c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
4157c82a1ecSDimitry Andric{
4167c82a1ecSDimitry Andric  return _VSTD_LFTS_V2::get_underlying(__pt) >= __u;
4177c82a1ecSDimitry Andric}
4187c82a1ecSDimitry Andric
4197c82a1ecSDimitry Andric
4207c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4217c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4227c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
4237c82a1ecSDimitry Andric{
4247c82a1ecSDimitry Andric  return __t == _VSTD_LFTS_V2::get_underlying(__pu);
4257c82a1ecSDimitry Andric}
4267c82a1ecSDimitry Andric
4277c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4287c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4297c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
4307c82a1ecSDimitry Andric{
4317c82a1ecSDimitry Andric  return __t != _VSTD_LFTS_V2::get_underlying(__pu);
4327c82a1ecSDimitry Andric}
4337c82a1ecSDimitry Andric
4347c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4357c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4367c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
4377c82a1ecSDimitry Andric{
4387c82a1ecSDimitry Andric  return __t < _VSTD_LFTS_V2::get_underlying(__pu);
4397c82a1ecSDimitry Andric}
4407c82a1ecSDimitry Andric
4417c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4427c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4437c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
4447c82a1ecSDimitry Andric{
4457c82a1ecSDimitry Andric  return __t > _VSTD_LFTS_V2::get_underlying(__pu);
4467c82a1ecSDimitry Andric}
4477c82a1ecSDimitry Andric
4487c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4497c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4507c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
4517c82a1ecSDimitry Andric{
4527c82a1ecSDimitry Andric  return __t <= _VSTD_LFTS_V2::get_underlying(__pu);
4537c82a1ecSDimitry Andric}
4547c82a1ecSDimitry Andric
4557c82a1ecSDimitry Andrictemplate <class _Tp, class _Up>
4567c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4577c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
4587c82a1ecSDimitry Andric{
4597c82a1ecSDimitry Andric  return __t >= _VSTD_LFTS_V2::get_underlying(__pu);
4607c82a1ecSDimitry Andric}
4617c82a1ecSDimitry Andric
4627c82a1ecSDimitry Andrictemplate <class _Tp>
4637c82a1ecSDimitry Andric_LIBCPP_INLINE_VISIBILITY
4647c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
4657c82a1ecSDimitry Andric{
466*4ba319b5SDimitry Andric  __pc1.swap(__pc2);
4677c82a1ecSDimitry Andric}
4687c82a1ecSDimitry Andric
4697c82a1ecSDimitry Andrictemplate <class _Tp>
4707c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT
4717c82a1ecSDimitry Andric{
4727c82a1ecSDimitry Andric  return __pt.__t_;
4737c82a1ecSDimitry Andric}
4747c82a1ecSDimitry Andric
4757c82a1ecSDimitry Andrictemplate <class _Tp>
4767c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT
4777c82a1ecSDimitry Andric{
4787c82a1ecSDimitry Andric  return __pt.__t_;
4797c82a1ecSDimitry Andric}
4807c82a1ecSDimitry Andric
4817c82a1ecSDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2
4827c82a1ecSDimitry Andric
4837c82a1ecSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
4847c82a1ecSDimitry Andric
4857c82a1ecSDimitry Andrictemplate <class _Tp>
4867c82a1ecSDimitry Andricstruct hash<experimental::fundamentals_v2::propagate_const<_Tp>>
4877c82a1ecSDimitry Andric{
4887c82a1ecSDimitry Andric  typedef size_t result_type;
4897c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type;
4907c82a1ecSDimitry Andric
4917c82a1ecSDimitry Andric  size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const
4927c82a1ecSDimitry Andric  {
4937c82a1ecSDimitry Andric    return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1));
4947c82a1ecSDimitry Andric  }
4957c82a1ecSDimitry Andric};
4967c82a1ecSDimitry Andric
4977c82a1ecSDimitry Andrictemplate <class _Tp>
4987c82a1ecSDimitry Andricstruct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
4997c82a1ecSDimitry Andric{
5007c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5017c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5027c82a1ecSDimitry Andric
5037c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5047c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5057c82a1ecSDimitry Andric  {
5067c82a1ecSDimitry Andric    return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5077c82a1ecSDimitry Andric  }
5087c82a1ecSDimitry Andric};
5097c82a1ecSDimitry Andric
5107c82a1ecSDimitry Andrictemplate <class _Tp>
5117c82a1ecSDimitry Andricstruct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>>
5127c82a1ecSDimitry Andric{
5137c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5147c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5157c82a1ecSDimitry Andric
5167c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5177c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5187c82a1ecSDimitry Andric  {
5197c82a1ecSDimitry Andric    return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5207c82a1ecSDimitry Andric  }
5217c82a1ecSDimitry Andric};
5227c82a1ecSDimitry Andric
5237c82a1ecSDimitry Andrictemplate <class _Tp>
5247c82a1ecSDimitry Andricstruct less<experimental::fundamentals_v2::propagate_const<_Tp>>
5257c82a1ecSDimitry Andric{
5267c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5277c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5287c82a1ecSDimitry Andric
5297c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5307c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5317c82a1ecSDimitry Andric  {
5327c82a1ecSDimitry Andric    return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5337c82a1ecSDimitry Andric  }
5347c82a1ecSDimitry Andric};
5357c82a1ecSDimitry Andric
5367c82a1ecSDimitry Andrictemplate <class _Tp>
5377c82a1ecSDimitry Andricstruct greater<experimental::fundamentals_v2::propagate_const<_Tp>>
5387c82a1ecSDimitry Andric{
5397c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5407c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5417c82a1ecSDimitry Andric
5427c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5437c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5447c82a1ecSDimitry Andric  {
5457c82a1ecSDimitry Andric    return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5467c82a1ecSDimitry Andric  }
5477c82a1ecSDimitry Andric};
5487c82a1ecSDimitry Andric
5497c82a1ecSDimitry Andrictemplate <class _Tp>
5507c82a1ecSDimitry Andricstruct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
5517c82a1ecSDimitry Andric{
5527c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5537c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5547c82a1ecSDimitry Andric
5557c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5567c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5577c82a1ecSDimitry Andric  {
5587c82a1ecSDimitry Andric    return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5597c82a1ecSDimitry Andric  }
5607c82a1ecSDimitry Andric};
5617c82a1ecSDimitry Andric
5627c82a1ecSDimitry Andrictemplate <class _Tp>
5637c82a1ecSDimitry Andricstruct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>>
5647c82a1ecSDimitry Andric{
5657c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type;
5667c82a1ecSDimitry Andric  typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type;
5677c82a1ecSDimitry Andric
5687c82a1ecSDimitry Andric  bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1,
5697c82a1ecSDimitry Andric      const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const
5707c82a1ecSDimitry Andric  {
5717c82a1ecSDimitry Andric    return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2));
5727c82a1ecSDimitry Andric  }
5737c82a1ecSDimitry Andric};
5747c82a1ecSDimitry Andric
5757c82a1ecSDimitry Andric_LIBCPP_END_NAMESPACE_STD
5767c82a1ecSDimitry Andric
5777c82a1ecSDimitry Andric#endif // _LIBCPP_STD_VER > 11
5787c82a1ecSDimitry Andric#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST
5797c82a1ecSDimitry Andric
580