xref: /llvm-project/libcxx/include/__cxx03/experimental/propagate_const (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser// -*- C++ -*-
2e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
3e78f53d1SNikolas Klauser//
4e78f53d1SNikolas Klauser// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5e78f53d1SNikolas Klauser// See https://llvm.org/LICENSE.txt for license information.
6e78f53d1SNikolas Klauser// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7e78f53d1SNikolas Klauser//
8e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
9e78f53d1SNikolas Klauser
10*ce777190SNikolas Klauser#ifndef _LIBCPP___CXX03_EXPERIMENTAL_PROPAGATE_CONST
11*ce777190SNikolas Klauser#define _LIBCPP___CXX03_EXPERIMENTAL_PROPAGATE_CONST
12e78f53d1SNikolas Klauser
13e78f53d1SNikolas Klauser/*
14e78f53d1SNikolas Klauser    propagate_const synopsis
15e78f53d1SNikolas Klauser
16e78f53d1SNikolas Klauser    namespace std { namespace experimental { inline namespace fundamentals_v2 {
17e78f53d1SNikolas Klauser
18e78f53d1SNikolas Klauser    // [propagate_const]
19e78f53d1SNikolas Klauser    template <class T> class propagate_const;
20e78f53d1SNikolas Klauser
21e78f53d1SNikolas Klauser    // [propagate_const.underlying], underlying pointer access
22e78f53d1SNikolas Klauser    constexpr const _Tp& get_underlying(const propagate_const<T>& pt) noexcept;
23e78f53d1SNikolas Klauser    constexpr T& get_underlying(propagate_const<T>& pt) noexcept;
24e78f53d1SNikolas Klauser
25e78f53d1SNikolas Klauser    // [propagate_const.relational], relational operators
26e78f53d1SNikolas Klauser    template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t);
27e78f53d1SNikolas Klauser    template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu);
28e78f53d1SNikolas Klauser    template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t);
29e78f53d1SNikolas Klauser    template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu);
30e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
31e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
32e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
33e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
34e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
35e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu);
36e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u);
37e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u);
38e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u);
39e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u);
40e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u);
41e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u);
42e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu);
43e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu);
44e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu);
45e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu);
46e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu);
47e78f53d1SNikolas Klauser    template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu);
48e78f53d1SNikolas Klauser
49e78f53d1SNikolas Klauser    // [propagate_const.algorithms], specialized algorithms
50e78f53d1SNikolas Klauser    template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below);
51e78f53d1SNikolas Klauser
52e78f53d1SNikolas Klauser    template <class T>
53e78f53d1SNikolas Klauser    class propagate_const
54e78f53d1SNikolas Klauser    {
55e78f53d1SNikolas Klauser
56e78f53d1SNikolas Klauser    public:
57e78f53d1SNikolas Klauser      typedef remove_reference_t<decltype(*declval<T&>())> element_type;
58e78f53d1SNikolas Klauser
59e78f53d1SNikolas Klauser      // [propagate_const.ctor], constructors
60e78f53d1SNikolas Klauser      constexpr propagate_const() = default;
61e78f53d1SNikolas Klauser      propagate_const(const propagate_const& p) = delete;
62e78f53d1SNikolas Klauser      constexpr propagate_const(propagate_const&& p) = default;
63e78f53d1SNikolas Klauser      template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below
64e78f53d1SNikolas Klauser      template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below
65e78f53d1SNikolas Klauser
66e78f53d1SNikolas Klauser      // [propagate_const.assignment], assignment
67e78f53d1SNikolas Klauser      propagate_const& operator=(const propagate_const& p) = delete;
68e78f53d1SNikolas Klauser      constexpr propagate_const& operator=(propagate_const&& p) = default;
69e78f53d1SNikolas Klauser      template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu);
70e78f53d1SNikolas Klauser      template <class U> constexpr propagate_const& operator=(U&& u); // see below
71e78f53d1SNikolas Klauser
72e78f53d1SNikolas Klauser      // [propagate_const.const_observers], const observers
73e78f53d1SNikolas Klauser      explicit constexpr operator bool() const;
74e78f53d1SNikolas Klauser      constexpr const element_type* operator->() const;
75e78f53d1SNikolas Klauser      constexpr operator const element_type*() const; // Not always defined
76e78f53d1SNikolas Klauser      constexpr const element_type& operator*() const;
77e78f53d1SNikolas Klauser      constexpr const element_type* get() const;
78e78f53d1SNikolas Klauser
79e78f53d1SNikolas Klauser      // [propagate_const.non_const_observers], non-const observers
80e78f53d1SNikolas Klauser      constexpr element_type* operator->();
81e78f53d1SNikolas Klauser      constexpr operator element_type*(); // Not always defined
82e78f53d1SNikolas Klauser      constexpr element_type& operator*();
83e78f53d1SNikolas Klauser      constexpr element_type* get();
84e78f53d1SNikolas Klauser
85e78f53d1SNikolas Klauser      // [propagate_const.modifiers], modifiers
86e78f53d1SNikolas Klauser      constexpr void swap(propagate_const& pt) noexcept(see below)
87e78f53d1SNikolas Klauser
88e78f53d1SNikolas Klauser    private:
89e78f53d1SNikolas Klauser      T t_; // exposition only
90e78f53d1SNikolas Klauser    };
91e78f53d1SNikolas Klauser
92e78f53d1SNikolas Klauser  } // namespace fundamentals_v2
93e78f53d1SNikolas Klauser  } // namespace experimental
94e78f53d1SNikolas Klauser
95e78f53d1SNikolas Klauser  // [propagate_const.hash], hash support
96e78f53d1SNikolas Klauser  template <class T> struct hash<experimental::propagate_const<T>>;
97e78f53d1SNikolas Klauser
98e78f53d1SNikolas Klauser  // [propagate_const.comparison_function_objects], comparison function objects
99e78f53d1SNikolas Klauser  template <class T> struct equal_to<experimental::propagate_const<T>>;
100e78f53d1SNikolas Klauser  template <class T> struct not_equal_to<experimental::propagate_const<T>>;
101e78f53d1SNikolas Klauser  template <class T> struct less<experimental::propagate_const<T>>;
102e78f53d1SNikolas Klauser  template <class T> struct greater<experimental::propagate_const<T>>;
103e78f53d1SNikolas Klauser  template <class T> struct less_equal<experimental::propagate_const<T>>;
104e78f53d1SNikolas Klauser  template <class T> struct greater_equal<experimental::propagate_const<T>>;
105e78f53d1SNikolas Klauser
106e78f53d1SNikolas Klauser} // namespace std
107e78f53d1SNikolas Klauser
108e78f53d1SNikolas Klauser*/
109e78f53d1SNikolas Klauser
11073fbae83SNikolas Klauser#include <__cxx03/__functional/operations.h>
11173fbae83SNikolas Klauser#include <__cxx03/__fwd/functional.h>
11273fbae83SNikolas Klauser#include <__cxx03/__type_traits/conditional.h>
11373fbae83SNikolas Klauser#include <__cxx03/__type_traits/decay.h>
11473fbae83SNikolas Klauser#include <__cxx03/__type_traits/enable_if.h>
11573fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_array.h>
11673fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_constructible.h>
11773fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_convertible.h>
11873fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_function.h>
11973fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_pointer.h>
12073fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_reference.h>
12173fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_same.h>
12273fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_swappable.h>
12373fbae83SNikolas Klauser#include <__cxx03/__type_traits/remove_cv.h>
12473fbae83SNikolas Klauser#include <__cxx03/__type_traits/remove_pointer.h>
12573fbae83SNikolas Klauser#include <__cxx03/__type_traits/remove_reference.h>
12673fbae83SNikolas Klauser#include <__cxx03/__utility/declval.h>
12773fbae83SNikolas Klauser#include <__cxx03/__utility/forward.h>
12873fbae83SNikolas Klauser#include <__cxx03/__utility/move.h>
12973fbae83SNikolas Klauser#include <__cxx03/__utility/swap.h>
13073fbae83SNikolas Klauser#include <__cxx03/cstddef>
13173fbae83SNikolas Klauser#include <__cxx03/experimental/__config>
132e78f53d1SNikolas Klauser
133e78f53d1SNikolas Klauser#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
134e78f53d1SNikolas Klauser#  pragma GCC system_header
135e78f53d1SNikolas Klauser#endif
136e78f53d1SNikolas Klauser
137e78f53d1SNikolas Klauser_LIBCPP_PUSH_MACROS
13873fbae83SNikolas Klauser#include <__cxx03/__undef_macros>
139e78f53d1SNikolas Klauser
140e78f53d1SNikolas Klauser#if _LIBCPP_STD_VER >= 14
141e78f53d1SNikolas Klauser
142e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
143e78f53d1SNikolas Klauser
144e78f53d1SNikolas Klausertemplate <class _Tp>
145e78f53d1SNikolas Klauserclass propagate_const;
146e78f53d1SNikolas Klauser
147e78f53d1SNikolas Klausertemplate <class _Up>
148e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI constexpr const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
149e78f53d1SNikolas Klauser
150e78f53d1SNikolas Klausertemplate <class _Up>
151e78f53d1SNikolas Klauserinline _LIBCPP_HIDE_FROM_ABI constexpr _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
152e78f53d1SNikolas Klauser
153e78f53d1SNikolas Klausertemplate <class _Tp>
154e78f53d1SNikolas Klauserclass propagate_const {
155e78f53d1SNikolas Klauserpublic:
156e78f53d1SNikolas Klauser  typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
157e78f53d1SNikolas Klauser
158e78f53d1SNikolas Klauser  static_assert(!is_array<_Tp>::value, "Instantiation of propagate_const with an array type is ill-formed.");
159e78f53d1SNikolas Klauser  static_assert(!is_reference<_Tp>::value, "Instantiation of propagate_const with a reference type is ill-formed.");
160e78f53d1SNikolas Klauser  static_assert(!(is_pointer<_Tp>::value && is_function<__remove_pointer_t<_Tp> >::value),
161e78f53d1SNikolas Klauser                "Instantiation of propagate_const with a function-pointer type is ill-formed.");
162e78f53d1SNikolas Klauser  static_assert(!(is_pointer<_Tp>::value && is_same<__remove_cv_t<__remove_pointer_t<_Tp> >, void>::value),
163e78f53d1SNikolas Klauser                "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed.");
164e78f53d1SNikolas Klauser
165e78f53d1SNikolas Klauserprivate:
166e78f53d1SNikolas Klauser  template <class _Up>
167e78f53d1SNikolas Klauser  static _LIBCPP_HIDE_FROM_ABI constexpr element_type* __get_pointer(_Up* __u) {
168e78f53d1SNikolas Klauser    return __u;
169e78f53d1SNikolas Klauser  }
170e78f53d1SNikolas Klauser
171e78f53d1SNikolas Klauser  template <class _Up>
172e78f53d1SNikolas Klauser  static _LIBCPP_HIDE_FROM_ABI constexpr element_type* __get_pointer(_Up& __u) {
173e78f53d1SNikolas Klauser    return __get_pointer(__u.get());
174e78f53d1SNikolas Klauser  }
175e78f53d1SNikolas Klauser
176e78f53d1SNikolas Klauser  template <class _Up>
177e78f53d1SNikolas Klauser  static _LIBCPP_HIDE_FROM_ABI constexpr const element_type* __get_pointer(const _Up* __u) {
178e78f53d1SNikolas Klauser    return __u;
179e78f53d1SNikolas Klauser  }
180e78f53d1SNikolas Klauser
181e78f53d1SNikolas Klauser  template <class _Up>
182e78f53d1SNikolas Klauser  static _LIBCPP_HIDE_FROM_ABI constexpr const element_type* __get_pointer(const _Up& __u) {
183e78f53d1SNikolas Klauser    return __get_pointer(__u.get());
184e78f53d1SNikolas Klauser  }
185e78f53d1SNikolas Klauser
186e78f53d1SNikolas Klauser  template <class _Up>
187e78f53d1SNikolas Klauser  struct __is_propagate_const : false_type {};
188e78f53d1SNikolas Klauser
189e78f53d1SNikolas Klauser  template <class _Up>
190e78f53d1SNikolas Klauser  struct __is_propagate_const<propagate_const<_Up>> : true_type {};
191e78f53d1SNikolas Klauser
192e78f53d1SNikolas Klauser  _Tp __t_;
193e78f53d1SNikolas Klauser
194e78f53d1SNikolas Klauserpublic:
195e78f53d1SNikolas Klauser  template <class _Up>
196e78f53d1SNikolas Klauser  friend constexpr const _Up& experimental::fundamentals_v2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT;
197e78f53d1SNikolas Klauser  template <class _Up>
198e78f53d1SNikolas Klauser  friend constexpr _Up& experimental::fundamentals_v2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT;
199e78f53d1SNikolas Klauser
200e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const() = default;
201e78f53d1SNikolas Klauser
202e78f53d1SNikolas Klauser  propagate_const(const propagate_const&) = delete;
203e78f53d1SNikolas Klauser
204e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const&&) = default;
205e78f53d1SNikolas Klauser
206e78f53d1SNikolas Klauser  template <class _Up,
207e78f53d1SNikolas Klauser            enable_if_t<!is_convertible<_Up, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = true>
208e78f53d1SNikolas Klauser  explicit _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const<_Up>&& __pu)
209e78f53d1SNikolas Klauser      : __t_(std::move(experimental::get_underlying(__pu))) {}
210e78f53d1SNikolas Klauser
211e78f53d1SNikolas Klauser  template <class _Up,
212e78f53d1SNikolas Klauser            enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value, bool> = false>
213e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(propagate_const<_Up>&& __pu)
214e78f53d1SNikolas Klauser      : __t_(std::move(experimental::get_underlying(__pu))) {}
215e78f53d1SNikolas Klauser
216e78f53d1SNikolas Klauser  template <class _Up,
217e78f53d1SNikolas Klauser            enable_if_t<!is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value &&
218e78f53d1SNikolas Klauser                            !__is_propagate_const<decay_t<_Up>>::value,
219e78f53d1SNikolas Klauser                        bool> = true>
220e78f53d1SNikolas Klauser  explicit _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {}
221e78f53d1SNikolas Klauser
222e78f53d1SNikolas Klauser  template <class _Up,
223e78f53d1SNikolas Klauser            enable_if_t<is_convertible<_Up&&, _Tp>::value && is_constructible<_Tp, _Up&&>::value &&
224e78f53d1SNikolas Klauser                            !__is_propagate_const<decay_t<_Up>>::value,
225e78f53d1SNikolas Klauser                        bool> = false>
226e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const(_Up&& __u) : __t_(std::forward<_Up>(__u)) {}
227e78f53d1SNikolas Klauser
228e78f53d1SNikolas Klauser  propagate_const& operator=(const propagate_const&) = delete;
229e78f53d1SNikolas Klauser
230e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(propagate_const&&) = default;
231e78f53d1SNikolas Klauser
232e78f53d1SNikolas Klauser  template <class _Up>
233e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(propagate_const<_Up>&& __pu) {
234e78f53d1SNikolas Klauser    __t_ = std::move(experimental::get_underlying(__pu));
235e78f53d1SNikolas Klauser    return *this;
236e78f53d1SNikolas Klauser  }
237e78f53d1SNikolas Klauser
238e78f53d1SNikolas Klauser  template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>>
239e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr propagate_const& operator=(_Up&& __u) {
240e78f53d1SNikolas Klauser    __t_ = std::forward<_Up>(__u);
241e78f53d1SNikolas Klauser    return *this;
242e78f53d1SNikolas Klauser  }
243e78f53d1SNikolas Klauser
244e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr const element_type* get() const { return __get_pointer(__t_); }
245e78f53d1SNikolas Klauser
246e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() { return __get_pointer(__t_); }
247e78f53d1SNikolas Klauser
248e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI explicit constexpr operator bool() const { return get() != nullptr; }
249e78f53d1SNikolas Klauser
250e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr const element_type* operator->() const { return get(); }
251e78f53d1SNikolas Klauser
252e78f53d1SNikolas Klauser  template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible< const _Dummy, const element_type*>::value>>
253e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr operator const element_type*() const {
254e78f53d1SNikolas Klauser    return get();
255e78f53d1SNikolas Klauser  }
256e78f53d1SNikolas Klauser
257e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr const element_type& operator*() const { return *get(); }
258e78f53d1SNikolas Klauser
259e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() { return get(); }
260e78f53d1SNikolas Klauser
261e78f53d1SNikolas Klauser  template <class _Dummy = _Tp, class _Up = enable_if_t< is_convertible<_Dummy, element_type*>::value>>
262e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr operator element_type*() {
263e78f53d1SNikolas Klauser    return get();
264e78f53d1SNikolas Klauser  }
265e78f53d1SNikolas Klauser
266e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type& operator*() { return *get(); }
267e78f53d1SNikolas Klauser
268e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr void swap(propagate_const& __pt) noexcept(__is_nothrow_swappable_v<_Tp>) {
269e78f53d1SNikolas Klauser    using std::swap;
270e78f53d1SNikolas Klauser    swap(__t_, __pt.__t_);
271e78f53d1SNikolas Klauser  }
272e78f53d1SNikolas Klauser};
273e78f53d1SNikolas Klauser
274e78f53d1SNikolas Klausertemplate <class _Tp>
275e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) {
276e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) == nullptr;
277e78f53d1SNikolas Klauser}
278e78f53d1SNikolas Klauser
279e78f53d1SNikolas Klausertemplate <class _Tp>
280e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) {
281e78f53d1SNikolas Klauser  return nullptr == experimental::get_underlying(__pt);
282e78f53d1SNikolas Klauser}
283e78f53d1SNikolas Klauser
284e78f53d1SNikolas Klausertemplate <class _Tp>
285e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) {
286e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) != nullptr;
287e78f53d1SNikolas Klauser}
288e78f53d1SNikolas Klauser
289e78f53d1SNikolas Klausertemplate <class _Tp>
290e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) {
291e78f53d1SNikolas Klauser  return nullptr != experimental::get_underlying(__pt);
292e78f53d1SNikolas Klauser}
293e78f53d1SNikolas Klauser
294e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
295e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
296e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) == experimental::get_underlying(__pu);
297e78f53d1SNikolas Klauser}
298e78f53d1SNikolas Klauser
299e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
300e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
301e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) != experimental::get_underlying(__pu);
302e78f53d1SNikolas Klauser}
303e78f53d1SNikolas Klauser
304e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
305e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
306e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) < experimental::get_underlying(__pu);
307e78f53d1SNikolas Klauser}
308e78f53d1SNikolas Klauser
309e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
310e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
311e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) > experimental::get_underlying(__pu);
312e78f53d1SNikolas Klauser}
313e78f53d1SNikolas Klauser
314e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
315e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
316e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) <= experimental::get_underlying(__pu);
317e78f53d1SNikolas Klauser}
318e78f53d1SNikolas Klauser
319e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
320e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const propagate_const<_Tp>& __pt, const propagate_const<_Up>& __pu) {
321e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) >= experimental::get_underlying(__pu);
322e78f53d1SNikolas Klauser}
323e78f53d1SNikolas Klauser
324e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
325e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) {
326e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) == __u;
327e78f53d1SNikolas Klauser}
328e78f53d1SNikolas Klauser
329e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
330e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) {
331e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) != __u;
332e78f53d1SNikolas Klauser}
333e78f53d1SNikolas Klauser
334e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
335e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) {
336e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) < __u;
337e78f53d1SNikolas Klauser}
338e78f53d1SNikolas Klauser
339e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
340e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) {
341e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) > __u;
342e78f53d1SNikolas Klauser}
343e78f53d1SNikolas Klauser
344e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
345e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) {
346e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) <= __u;
347e78f53d1SNikolas Klauser}
348e78f53d1SNikolas Klauser
349e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
350e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) {
351e78f53d1SNikolas Klauser  return experimental::get_underlying(__pt) >= __u;
352e78f53d1SNikolas Klauser}
353e78f53d1SNikolas Klauser
354e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
355e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) {
356e78f53d1SNikolas Klauser  return __t == experimental::get_underlying(__pu);
357e78f53d1SNikolas Klauser}
358e78f53d1SNikolas Klauser
359e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
360e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) {
361e78f53d1SNikolas Klauser  return __t != experimental::get_underlying(__pu);
362e78f53d1SNikolas Klauser}
363e78f53d1SNikolas Klauser
364e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
365e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) {
366e78f53d1SNikolas Klauser  return __t < experimental::get_underlying(__pu);
367e78f53d1SNikolas Klauser}
368e78f53d1SNikolas Klauser
369e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
370e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) {
371e78f53d1SNikolas Klauser  return __t > experimental::get_underlying(__pu);
372e78f53d1SNikolas Klauser}
373e78f53d1SNikolas Klauser
374e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
375e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) {
376e78f53d1SNikolas Klauser  return __t <= experimental::get_underlying(__pu);
377e78f53d1SNikolas Klauser}
378e78f53d1SNikolas Klauser
379e78f53d1SNikolas Klausertemplate <class _Tp, class _Up>
380e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) {
381e78f53d1SNikolas Klauser  return __t >= experimental::get_underlying(__pu);
382e78f53d1SNikolas Klauser}
383e78f53d1SNikolas Klauser
384e78f53d1SNikolas Klausertemplate <class _Tp>
385e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr void
386e78f53d1SNikolas Klauserswap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) noexcept(__is_nothrow_swappable_v<_Tp>) {
387e78f53d1SNikolas Klauser  __pc1.swap(__pc2);
388e78f53d1SNikolas Klauser}
389e78f53d1SNikolas Klauser
390e78f53d1SNikolas Klausertemplate <class _Tp>
391e78f53d1SNikolas Klauserconstexpr const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT {
392e78f53d1SNikolas Klauser  return __pt.__t_;
393e78f53d1SNikolas Klauser}
394e78f53d1SNikolas Klauser
395e78f53d1SNikolas Klausertemplate <class _Tp>
396e78f53d1SNikolas Klauserconstexpr _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT {
397e78f53d1SNikolas Klauser  return __pt.__t_;
398e78f53d1SNikolas Klauser}
399e78f53d1SNikolas Klauser
400e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_LFTS_V2
401e78f53d1SNikolas Klauser
402e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_STD
403e78f53d1SNikolas Klauser
404e78f53d1SNikolas Klausertemplate <class _Tp>
405e78f53d1SNikolas Klauserstruct hash<experimental::propagate_const<_Tp>> {
406e78f53d1SNikolas Klauser  typedef size_t result_type;
407e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> argument_type;
408e78f53d1SNikolas Klauser
409e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::propagate_const<_Tp>& __pc1) const {
410e78f53d1SNikolas Klauser    return std::hash<_Tp>()(experimental::get_underlying(__pc1));
411e78f53d1SNikolas Klauser  }
412e78f53d1SNikolas Klauser};
413e78f53d1SNikolas Klauser
414e78f53d1SNikolas Klausertemplate <class _Tp>
415e78f53d1SNikolas Klauserstruct equal_to<experimental::propagate_const<_Tp>> {
416e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
417e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
418e78f53d1SNikolas Klauser
419e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
420e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
421e78f53d1SNikolas Klauser    return std::equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
422e78f53d1SNikolas Klauser  }
423e78f53d1SNikolas Klauser};
424e78f53d1SNikolas Klauser
425e78f53d1SNikolas Klausertemplate <class _Tp>
426e78f53d1SNikolas Klauserstruct not_equal_to<experimental::propagate_const<_Tp>> {
427e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
428e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
429e78f53d1SNikolas Klauser
430e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
431e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
432e78f53d1SNikolas Klauser    return std::not_equal_to<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
433e78f53d1SNikolas Klauser  }
434e78f53d1SNikolas Klauser};
435e78f53d1SNikolas Klauser
436e78f53d1SNikolas Klausertemplate <class _Tp>
437e78f53d1SNikolas Klauserstruct less<experimental::propagate_const<_Tp>> {
438e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
439e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
440e78f53d1SNikolas Klauser
441e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
442e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
443e78f53d1SNikolas Klauser    return std::less<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
444e78f53d1SNikolas Klauser  }
445e78f53d1SNikolas Klauser};
446e78f53d1SNikolas Klauser
447e78f53d1SNikolas Klausertemplate <class _Tp>
448e78f53d1SNikolas Klauserstruct greater<experimental::propagate_const<_Tp>> {
449e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
450e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
451e78f53d1SNikolas Klauser
452e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
453e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
454e78f53d1SNikolas Klauser    return std::greater<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
455e78f53d1SNikolas Klauser  }
456e78f53d1SNikolas Klauser};
457e78f53d1SNikolas Klauser
458e78f53d1SNikolas Klausertemplate <class _Tp>
459e78f53d1SNikolas Klauserstruct less_equal<experimental::propagate_const<_Tp>> {
460e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
461e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
462e78f53d1SNikolas Klauser
463e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
464e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
465e78f53d1SNikolas Klauser    return std::less_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
466e78f53d1SNikolas Klauser  }
467e78f53d1SNikolas Klauser};
468e78f53d1SNikolas Klauser
469e78f53d1SNikolas Klausertemplate <class _Tp>
470e78f53d1SNikolas Klauserstruct greater_equal<experimental::propagate_const<_Tp>> {
471e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> first_argument_type;
472e78f53d1SNikolas Klauser  typedef experimental::propagate_const<_Tp> second_argument_type;
473e78f53d1SNikolas Klauser
474e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI bool
475e78f53d1SNikolas Klauser  operator()(const experimental::propagate_const<_Tp>& __pc1, const experimental::propagate_const<_Tp>& __pc2) const {
476e78f53d1SNikolas Klauser    return std::greater_equal<_Tp>()(experimental::get_underlying(__pc1), experimental::get_underlying(__pc2));
477e78f53d1SNikolas Klauser  }
478e78f53d1SNikolas Klauser};
479e78f53d1SNikolas Klauser
480e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_STD
481e78f53d1SNikolas Klauser
482e78f53d1SNikolas Klauser#endif // _LIBCPP_STD_VER >= 14
483e78f53d1SNikolas Klauser
484e78f53d1SNikolas Klauser_LIBCPP_POP_MACROS
485e78f53d1SNikolas Klauser
486e78f53d1SNikolas Klauser#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
48773fbae83SNikolas Klauser#  include <__cxx03/type_traits>
488e78f53d1SNikolas Klauser#endif
489e78f53d1SNikolas Klauser
490*ce777190SNikolas Klauser#endif // _LIBCPP___CXX03_EXPERIMENTAL_PROPAGATE_CONST
491