xref: /dflybsd-src/contrib/gcc-8.0/libstdc++-v3/include/experimental/propagate_const (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj// <experimental/propagate_const> -*- C++ -*-
2*38fd1498Szrj
3*38fd1498Szrj// Copyright (C) 2015-2018 Free Software Foundation, Inc.
4*38fd1498Szrj//
5*38fd1498Szrj// This file is part of the GNU ISO C++ Library.  This library is free
6*38fd1498Szrj// software; you can redistribute it and/or modify it under the
7*38fd1498Szrj// terms of the GNU General Public License as published by the
8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option)
9*38fd1498Szrj// any later version.
10*38fd1498Szrj
11*38fd1498Szrj// This library is distributed in the hope that it will be useful,
12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*38fd1498Szrj// GNU General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional
17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version
18*38fd1498Szrj// 3.1, as published by the Free Software Foundation.
19*38fd1498Szrj
20*38fd1498Szrj// You should have received a copy of the GNU General Public License and
21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program;
22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*38fd1498Szrj// <http://www.gnu.org/licenses/>.
24*38fd1498Szrj
25*38fd1498Szrj/** @file experimental/propagate_const
26*38fd1498Szrj *  This is a TS C++ Library header.
27*38fd1498Szrj */
28*38fd1498Szrj
29*38fd1498Szrj#ifndef _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST
30*38fd1498Szrj#define _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST 1
31*38fd1498Szrj
32*38fd1498Szrj#pragma GCC system_header
33*38fd1498Szrj
34*38fd1498Szrj#if __cplusplus >= 201402L
35*38fd1498Szrj
36*38fd1498Szrj#include <type_traits>
37*38fd1498Szrj#include <bits/functional_hash.h>
38*38fd1498Szrj#include <bits/move.h>
39*38fd1498Szrj#include <bits/stl_function.h>
40*38fd1498Szrj#include <experimental/bits/lfts_config.h>
41*38fd1498Szrj
42*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default)
43*38fd1498Szrj{
44*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION
45*38fd1498Szrj
46*38fd1498Szrjnamespace experimental
47*38fd1498Szrj{
48*38fd1498Szrjinline namespace fundamentals_v2
49*38fd1498Szrj{
50*38fd1498Szrj  /**
51*38fd1498Szrj   * @defgroup propagate_const Const-propagating wrapper
52*38fd1498Szrj   * @ingroup experimental
53*38fd1498Szrj   *
54*38fd1498Szrj   * A const-propagating wrapper that propagates const to pointer-like members,
55*38fd1498Szrj   * as described in n4388 "A Proposal to Add a Const-Propagating Wrapper
56*38fd1498Szrj   * to the Standard Library".
57*38fd1498Szrj   *
58*38fd1498Szrj   * @{
59*38fd1498Szrj   */
60*38fd1498Szrj
61*38fd1498Szrj/// Const-propagating wrapper.
62*38fd1498Szrj  template <typename _Tp>
63*38fd1498Szrj    class propagate_const
64*38fd1498Szrj    {
65*38fd1498Szrj    public:
66*38fd1498Szrj      typedef remove_reference_t<decltype(*std::declval<_Tp&>())> element_type;
67*38fd1498Szrj
68*38fd1498Szrj    private:
69*38fd1498Szrj      template <typename _Up>
70*38fd1498Szrj	struct __is_propagate_const : false_type
71*38fd1498Szrj	{ };
72*38fd1498Szrj
73*38fd1498Szrj      template <typename _Up>
74*38fd1498Szrj	struct __is_propagate_const<propagate_const<_Up>> : true_type
75*38fd1498Szrj	{ };
76*38fd1498Szrj
77*38fd1498Szrj      template <typename _Up>
78*38fd1498Szrj	friend constexpr const _Up&
79*38fd1498Szrj	get_underlying(const propagate_const<_Up>& __pt) noexcept;
80*38fd1498Szrj      template <typename _Up>
81*38fd1498Szrj	friend constexpr _Up&
82*38fd1498Szrj	get_underlying(propagate_const<_Up>& __pt) noexcept;
83*38fd1498Szrj
84*38fd1498Szrj      template <typename _Up>
85*38fd1498Szrj	static constexpr element_type*
86*38fd1498Szrj	__to_raw_pointer(_Up* __u)
87*38fd1498Szrj	{ return __u; }
88*38fd1498Szrj
89*38fd1498Szrj      template <typename _Up>
90*38fd1498Szrj	static constexpr element_type*
91*38fd1498Szrj	__to_raw_pointer(_Up& __u)
92*38fd1498Szrj	{ return __u.get(); }
93*38fd1498Szrj
94*38fd1498Szrj      template <typename _Up>
95*38fd1498Szrj	static constexpr const element_type*
96*38fd1498Szrj	__to_raw_pointer(const _Up* __u)
97*38fd1498Szrj	{ return __u; }
98*38fd1498Szrj
99*38fd1498Szrj      template <typename _Up>
100*38fd1498Szrj	static constexpr const element_type*
101*38fd1498Szrj	__to_raw_pointer(const _Up& __u)
102*38fd1498Szrj	{ return __u.get(); }
103*38fd1498Szrj
104*38fd1498Szrj    public:
105*38fd1498Szrj      static_assert(__and_<is_object<typename remove_pointer<_Tp>::type>,
106*38fd1498Szrj			   __not_<is_array<_Tp>>,
107*38fd1498Szrj			   __or_<is_class<_Tp>, is_pointer<_Tp>>>::value,
108*38fd1498Szrj		    "propagate_const requires a class or a pointer to an"
109*38fd1498Szrj		    " object type");
110*38fd1498Szrj
111*38fd1498Szrj      // [propagate_const.ctor], constructors
112*38fd1498Szrj      constexpr propagate_const() = default;
113*38fd1498Szrj      propagate_const(const propagate_const& __p) = delete;
114*38fd1498Szrj      constexpr propagate_const(propagate_const&& __p) = default;
115*38fd1498Szrj      template <typename _Up, typename
116*38fd1498Szrj		enable_if<__and_<is_constructible<_Tp, _Up&&>,
117*38fd1498Szrj				 is_convertible<_Up&&, _Tp>>::value, bool
118*38fd1498Szrj			  >::type=true>
119*38fd1498Szrj      constexpr propagate_const(propagate_const<_Up>&& __pu)
120*38fd1498Szrj	: _M_t(std::move(get_underlying(__pu)))
121*38fd1498Szrj      {}
122*38fd1498Szrj      template <typename _Up, typename
123*38fd1498Szrj		enable_if<__and_<is_constructible<_Tp, _Up&&>,
124*38fd1498Szrj				 __not_<is_convertible<_Up&&, _Tp>>>::value,
125*38fd1498Szrj			  bool>::type=false>
126*38fd1498Szrj      constexpr explicit propagate_const(propagate_const<_Up>&& __pu)
127*38fd1498Szrj	: _M_t(std::move(get_underlying(__pu)))
128*38fd1498Szrj      {}
129*38fd1498Szrj      template <typename _Up, typename
130*38fd1498Szrj		enable_if<__and_<is_constructible<_Tp, _Up&&>,
131*38fd1498Szrj				 is_convertible<_Up&&, _Tp>,
132*38fd1498Szrj				 __not_<__is_propagate_const<
133*38fd1498Szrj					  typename decay<_Up>::type>>
134*38fd1498Szrj				 >::value, bool>::type=true>
135*38fd1498Szrj      constexpr propagate_const(_Up&& __u)
136*38fd1498Szrj	: _M_t(std::forward<_Up>(__u))
137*38fd1498Szrj      {}
138*38fd1498Szrj      template <typename _Up, typename
139*38fd1498Szrj		enable_if<__and_<is_constructible<_Tp, _Up&&>,
140*38fd1498Szrj				 __not_<is_convertible<_Up&&, _Tp>>,
141*38fd1498Szrj				 __not_<__is_propagate_const<
142*38fd1498Szrj					  typename decay<_Up>::type>>
143*38fd1498Szrj				 >::value, bool>::type=false>
144*38fd1498Szrj      constexpr explicit propagate_const(_Up&& __u)
145*38fd1498Szrj	: _M_t(std::forward<_Up>(__u))
146*38fd1498Szrj      {}
147*38fd1498Szrj
148*38fd1498Szrj      // [propagate_const.assignment], assignment
149*38fd1498Szrj      propagate_const& operator=(const propagate_const& __p) = delete;
150*38fd1498Szrj      constexpr propagate_const& operator=(propagate_const&& __p) = default;
151*38fd1498Szrj
152*38fd1498Szrj      template <typename _Up, typename =
153*38fd1498Szrj		typename enable_if<is_convertible<_Up&&, _Tp>::value>::type>
154*38fd1498Szrj      constexpr propagate_const& operator=(propagate_const<_Up>&& __pu)
155*38fd1498Szrj      {
156*38fd1498Szrj	_M_t = std::move(get_underlying(__pu));
157*38fd1498Szrj	return *this;
158*38fd1498Szrj      }
159*38fd1498Szrj
160*38fd1498Szrj      template <typename _Up, typename =
161*38fd1498Szrj		typename enable_if<__and_<is_convertible<_Up&&, _Tp>,
162*38fd1498Szrj					  __not_<__is_propagate_const<
163*38fd1498Szrj						   typename decay<_Up>::type>>
164*38fd1498Szrj					  >::value>::type>
165*38fd1498Szrj      constexpr propagate_const& operator=(_Up&& __u)
166*38fd1498Szrj      {
167*38fd1498Szrj	_M_t = std::forward<_Up>(__u);
168*38fd1498Szrj	return *this;
169*38fd1498Szrj      }
170*38fd1498Szrj
171*38fd1498Szrj      // [propagate_const.const_observers], const observers
172*38fd1498Szrj      explicit constexpr operator bool() const
173*38fd1498Szrj      {
174*38fd1498Szrj	return bool(_M_t);
175*38fd1498Szrj      }
176*38fd1498Szrj
177*38fd1498Szrj      constexpr const element_type* operator->() const
178*38fd1498Szrj      {
179*38fd1498Szrj	return get();
180*38fd1498Szrj      }
181*38fd1498Szrj
182*38fd1498Szrj      template <typename _Up = _Tp,
183*38fd1498Szrj		typename enable_if<__or_<is_pointer<_Up>,
184*38fd1498Szrj					 is_convertible<_Up,
185*38fd1498Szrj							const element_type*>
186*38fd1498Szrj					 >::value, bool>::type = true>
187*38fd1498Szrj      constexpr operator const element_type*() const
188*38fd1498Szrj      {
189*38fd1498Szrj	return get();
190*38fd1498Szrj      }
191*38fd1498Szrj
192*38fd1498Szrj      constexpr const element_type& operator*() const
193*38fd1498Szrj      {
194*38fd1498Szrj	return *get();
195*38fd1498Szrj      }
196*38fd1498Szrj
197*38fd1498Szrj      constexpr const element_type* get() const
198*38fd1498Szrj      {
199*38fd1498Szrj	return __to_raw_pointer(_M_t);
200*38fd1498Szrj      }
201*38fd1498Szrj
202*38fd1498Szrj      // [propagate_const.non_const_observers], non-const observers
203*38fd1498Szrj      constexpr element_type* operator->()
204*38fd1498Szrj      {
205*38fd1498Szrj	return get();
206*38fd1498Szrj      }
207*38fd1498Szrj
208*38fd1498Szrj      template <typename _Up = _Tp,
209*38fd1498Szrj		typename enable_if<__or_<is_pointer<_Up>,
210*38fd1498Szrj					 is_convertible<_Up,
211*38fd1498Szrj						        const element_type*>
212*38fd1498Szrj					 >::value, bool>::type = true>
213*38fd1498Szrj      constexpr operator element_type*()
214*38fd1498Szrj      {
215*38fd1498Szrj	return get();
216*38fd1498Szrj      }
217*38fd1498Szrj
218*38fd1498Szrj      constexpr element_type& operator*()
219*38fd1498Szrj      {
220*38fd1498Szrj	return *get();
221*38fd1498Szrj      }
222*38fd1498Szrj
223*38fd1498Szrj      constexpr element_type* get()
224*38fd1498Szrj      {
225*38fd1498Szrj	return __to_raw_pointer(_M_t);
226*38fd1498Szrj      }
227*38fd1498Szrj
228*38fd1498Szrj      // [propagate_const.modifiers], modifiers
229*38fd1498Szrj      constexpr void
230*38fd1498Szrj      swap(propagate_const& __pt) noexcept(__is_nothrow_swappable<_Tp>::value)
231*38fd1498Szrj      {
232*38fd1498Szrj	using std::swap;
233*38fd1498Szrj	swap(_M_t, get_underlying(__pt));
234*38fd1498Szrj      }
235*38fd1498Szrj
236*38fd1498Szrj    private:
237*38fd1498Szrj      _Tp _M_t;
238*38fd1498Szrj    };
239*38fd1498Szrj
240*38fd1498Szrj  // [propagate_const.relational], relational operators
241*38fd1498Szrj  template <typename _Tp>
242*38fd1498Szrj    constexpr bool
243*38fd1498Szrj    operator==(const propagate_const<_Tp>& __pt, nullptr_t)
244*38fd1498Szrj    {
245*38fd1498Szrj      return get_underlying(__pt) == nullptr;
246*38fd1498Szrj    }
247*38fd1498Szrj
248*38fd1498Szrj  template <typename _Tp>
249*38fd1498Szrj    constexpr bool
250*38fd1498Szrj    operator==(nullptr_t, const propagate_const<_Tp>& __pu)
251*38fd1498Szrj    {
252*38fd1498Szrj      return nullptr == get_underlying(__pu);
253*38fd1498Szrj    }
254*38fd1498Szrj
255*38fd1498Szrj  template <typename _Tp>
256*38fd1498Szrj    constexpr bool
257*38fd1498Szrj    operator!=(const propagate_const<_Tp>& __pt, nullptr_t)
258*38fd1498Szrj    {
259*38fd1498Szrj      return get_underlying(__pt) != nullptr;
260*38fd1498Szrj    }
261*38fd1498Szrj
262*38fd1498Szrj  template <typename _Tp>
263*38fd1498Szrj    constexpr bool operator!=(nullptr_t, const propagate_const<_Tp>& __pu)
264*38fd1498Szrj    {
265*38fd1498Szrj      return nullptr != get_underlying(__pu);
266*38fd1498Szrj    }
267*38fd1498Szrj
268*38fd1498Szrj  template <typename _Tp, typename _Up>
269*38fd1498Szrj    constexpr bool
270*38fd1498Szrj    operator==(const propagate_const<_Tp>& __pt,
271*38fd1498Szrj	       const propagate_const<_Up>& __pu)
272*38fd1498Szrj    {
273*38fd1498Szrj      return get_underlying(__pt) == get_underlying(__pu);
274*38fd1498Szrj    }
275*38fd1498Szrj
276*38fd1498Szrj  template <typename _Tp, typename _Up>
277*38fd1498Szrj    constexpr bool
278*38fd1498Szrj    operator!=(const propagate_const<_Tp>& __pt,
279*38fd1498Szrj	       const propagate_const<_Up>& __pu)
280*38fd1498Szrj    {
281*38fd1498Szrj      return get_underlying(__pt) != get_underlying(__pu);
282*38fd1498Szrj    }
283*38fd1498Szrj
284*38fd1498Szrj  template <typename _Tp, typename _Up>
285*38fd1498Szrj    constexpr bool
286*38fd1498Szrj    operator<(const propagate_const<_Tp>& __pt,
287*38fd1498Szrj	      const propagate_const<_Up>& __pu)
288*38fd1498Szrj    {
289*38fd1498Szrj      return get_underlying(__pt) < get_underlying(__pu);
290*38fd1498Szrj    }
291*38fd1498Szrj
292*38fd1498Szrj  template <typename _Tp, typename _Up>
293*38fd1498Szrj    constexpr bool
294*38fd1498Szrj    operator>(const propagate_const<_Tp>& __pt,
295*38fd1498Szrj	      const propagate_const<_Up>& __pu)
296*38fd1498Szrj    {
297*38fd1498Szrj      return get_underlying(__pt) > get_underlying(__pu);
298*38fd1498Szrj    }
299*38fd1498Szrj
300*38fd1498Szrj  template <typename _Tp, typename _Up>
301*38fd1498Szrj    constexpr bool
302*38fd1498Szrj    operator<=(const propagate_const<_Tp>& __pt,
303*38fd1498Szrj	       const propagate_const<_Up>& __pu)
304*38fd1498Szrj    {
305*38fd1498Szrj      return get_underlying(__pt) <= get_underlying(__pu);
306*38fd1498Szrj    }
307*38fd1498Szrj
308*38fd1498Szrj  template <typename _Tp, typename _Up>
309*38fd1498Szrj    constexpr bool
310*38fd1498Szrj    operator>=(const propagate_const<_Tp>& __pt,
311*38fd1498Szrj	       const propagate_const<_Up>& __pu)
312*38fd1498Szrj    {
313*38fd1498Szrj      return get_underlying(__pt) >= get_underlying(__pu);
314*38fd1498Szrj    }
315*38fd1498Szrj
316*38fd1498Szrj  template <typename _Tp, typename _Up>
317*38fd1498Szrj    constexpr bool
318*38fd1498Szrj    operator==(const propagate_const<_Tp>& __pt, const _Up& __u)
319*38fd1498Szrj    {
320*38fd1498Szrj      return get_underlying(__pt) == __u;
321*38fd1498Szrj    }
322*38fd1498Szrj
323*38fd1498Szrj  template <typename _Tp, typename _Up>
324*38fd1498Szrj    constexpr bool
325*38fd1498Szrj    operator!=(const propagate_const<_Tp>& __pt, const _Up& __u)
326*38fd1498Szrj    {
327*38fd1498Szrj      return get_underlying(__pt) != __u;
328*38fd1498Szrj    }
329*38fd1498Szrj
330*38fd1498Szrj  template <typename _Tp, typename _Up>
331*38fd1498Szrj    constexpr bool
332*38fd1498Szrj    operator<(const propagate_const<_Tp>& __pt, const _Up& __u)
333*38fd1498Szrj    {
334*38fd1498Szrj      return get_underlying(__pt) < __u;
335*38fd1498Szrj    }
336*38fd1498Szrj
337*38fd1498Szrj  template <typename _Tp, typename _Up>
338*38fd1498Szrj    constexpr bool
339*38fd1498Szrj    operator>(const propagate_const<_Tp>& __pt, const _Up& __u)
340*38fd1498Szrj    {
341*38fd1498Szrj      return get_underlying(__pt) > __u;
342*38fd1498Szrj    }
343*38fd1498Szrj
344*38fd1498Szrj  template <typename _Tp, typename _Up>
345*38fd1498Szrj    constexpr bool
346*38fd1498Szrj    operator<=(const propagate_const<_Tp>& __pt, const _Up& __u)
347*38fd1498Szrj    {
348*38fd1498Szrj      return get_underlying(__pt) <= __u;
349*38fd1498Szrj    }
350*38fd1498Szrj
351*38fd1498Szrj  template <typename _Tp, typename _Up>
352*38fd1498Szrj    constexpr bool
353*38fd1498Szrj    operator>=(const propagate_const<_Tp>& __pt, const _Up& __u)
354*38fd1498Szrj    {
355*38fd1498Szrj      return get_underlying(__pt) >= __u;
356*38fd1498Szrj    }
357*38fd1498Szrj
358*38fd1498Szrj  template <typename _Tp, typename _Up>
359*38fd1498Szrj    constexpr bool
360*38fd1498Szrj    operator==(const _Tp& __t, const propagate_const<_Up>& __pu)
361*38fd1498Szrj    {
362*38fd1498Szrj      return __t == get_underlying(__pu);
363*38fd1498Szrj    }
364*38fd1498Szrj
365*38fd1498Szrj  template <typename _Tp, typename _Up>
366*38fd1498Szrj    constexpr bool
367*38fd1498Szrj    operator!=(const _Tp& __t, const propagate_const<_Up>& __pu)
368*38fd1498Szrj    {
369*38fd1498Szrj      return __t != get_underlying(__pu);
370*38fd1498Szrj    }
371*38fd1498Szrj
372*38fd1498Szrj  template <typename _Tp, typename _Up>
373*38fd1498Szrj    constexpr bool
374*38fd1498Szrj    operator<(const _Tp& __t, const propagate_const<_Up>& __pu)
375*38fd1498Szrj    {
376*38fd1498Szrj      return __t < get_underlying(__pu);
377*38fd1498Szrj    }
378*38fd1498Szrj
379*38fd1498Szrj  template <typename _Tp, typename _Up>
380*38fd1498Szrj    constexpr bool
381*38fd1498Szrj    operator>(const _Tp& __t, const propagate_const<_Up>& __pu)
382*38fd1498Szrj    {
383*38fd1498Szrj      return __t > get_underlying(__pu);
384*38fd1498Szrj    }
385*38fd1498Szrj
386*38fd1498Szrj  template <typename _Tp, typename _Up>
387*38fd1498Szrj    constexpr bool
388*38fd1498Szrj    operator<=(const _Tp& __t, const propagate_const<_Up>& __pu)
389*38fd1498Szrj    {
390*38fd1498Szrj      return __t <= get_underlying(__pu);
391*38fd1498Szrj    }
392*38fd1498Szrj
393*38fd1498Szrj  template <typename _Tp, typename _Up>
394*38fd1498Szrj    constexpr bool
395*38fd1498Szrj    operator>=(const _Tp& __t, const propagate_const<_Up>& __pu)
396*38fd1498Szrj    {
397*38fd1498Szrj      return __t >= get_underlying(__pu);
398*38fd1498Szrj    }
399*38fd1498Szrj
400*38fd1498Szrj  // [propagate_const.algorithms], specialized algorithms
401*38fd1498Szrj  template <typename _Tp>
402*38fd1498Szrj    constexpr void
403*38fd1498Szrj    swap(propagate_const<_Tp>& __pt, propagate_const<_Tp>& __pt2)
404*38fd1498Szrj      noexcept(__is_nothrow_swappable<_Tp>::value)
405*38fd1498Szrj    {
406*38fd1498Szrj      __pt.swap(__pt2);
407*38fd1498Szrj    }
408*38fd1498Szrj
409*38fd1498Szrj  // [propagate_const.underlying], underlying pointer access
410*38fd1498Szrj  template <typename _Tp>
411*38fd1498Szrj    constexpr const _Tp&
412*38fd1498Szrj    get_underlying(const propagate_const<_Tp>& __pt) noexcept
413*38fd1498Szrj    {
414*38fd1498Szrj      return __pt._M_t;
415*38fd1498Szrj    }
416*38fd1498Szrj
417*38fd1498Szrj  template <typename _Tp>
418*38fd1498Szrj    constexpr _Tp&
419*38fd1498Szrj    get_underlying(propagate_const<_Tp>& __pt) noexcept
420*38fd1498Szrj    {
421*38fd1498Szrj      return __pt._M_t;
422*38fd1498Szrj    }
423*38fd1498Szrj
424*38fd1498Szrj  // @} group propagate_const
425*38fd1498Szrj} // namespace fundamentals_v2
426*38fd1498Szrj} // namespace experimental
427*38fd1498Szrj
428*38fd1498Szrj// [propagate_const.hash], hash support
429*38fd1498Szrj template <typename _Tp>
430*38fd1498Szrj   struct hash<experimental::propagate_const<_Tp>>
431*38fd1498Szrj   {
432*38fd1498Szrj     using result_type = size_t;
433*38fd1498Szrj     using argument_type = experimental::propagate_const<_Tp>;
434*38fd1498Szrj
435*38fd1498Szrj     size_t
436*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __t) const
437*38fd1498Szrj     noexcept(noexcept(hash<_Tp>{}(get_underlying(__t))))
438*38fd1498Szrj     {
439*38fd1498Szrj       return hash<_Tp>{}(get_underlying(__t));
440*38fd1498Szrj     }
441*38fd1498Szrj   };
442*38fd1498Szrj
443*38fd1498Szrj // [propagate_const.comparison_function_objects], comparison function objects
444*38fd1498Szrj template <typename _Tp>
445*38fd1498Szrj   struct equal_to<experimental::propagate_const<_Tp>>
446*38fd1498Szrj   {
447*38fd1498Szrj     constexpr bool
448*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
449*38fd1498Szrj	        const experimental::propagate_const<_Tp>& __y) const
450*38fd1498Szrj     {
451*38fd1498Szrj       return equal_to<_Tp>{}(get_underlying(__x), get_underlying(__y));
452*38fd1498Szrj     }
453*38fd1498Szrj
454*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
455*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
456*38fd1498Szrj     typedef bool result_type;
457*38fd1498Szrj   };
458*38fd1498Szrj
459*38fd1498Szrj template <typename _Tp>
460*38fd1498Szrj   struct not_equal_to<experimental::propagate_const<_Tp>>
461*38fd1498Szrj   {
462*38fd1498Szrj     constexpr bool
463*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
464*38fd1498Szrj		const experimental::propagate_const<_Tp>& __y) const
465*38fd1498Szrj     {
466*38fd1498Szrj       return not_equal_to<_Tp>{}(get_underlying(__x), get_underlying(__y));
467*38fd1498Szrj     }
468*38fd1498Szrj
469*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
470*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
471*38fd1498Szrj     typedef bool result_type;
472*38fd1498Szrj   };
473*38fd1498Szrj
474*38fd1498Szrj template <typename _Tp>
475*38fd1498Szrj   struct less<experimental::propagate_const<_Tp>>
476*38fd1498Szrj   {
477*38fd1498Szrj     constexpr bool
478*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
479*38fd1498Szrj		const experimental::propagate_const<_Tp>& __y) const
480*38fd1498Szrj     {
481*38fd1498Szrj       return less<_Tp>{}(get_underlying(__x), get_underlying(__y));
482*38fd1498Szrj     }
483*38fd1498Szrj
484*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
485*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
486*38fd1498Szrj     typedef bool result_type;
487*38fd1498Szrj   };
488*38fd1498Szrj
489*38fd1498Szrj template <typename _Tp>
490*38fd1498Szrj   struct greater<experimental::propagate_const<_Tp>>
491*38fd1498Szrj   {
492*38fd1498Szrj     constexpr bool
493*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
494*38fd1498Szrj		const experimental::propagate_const<_Tp>& __y) const
495*38fd1498Szrj     {
496*38fd1498Szrj       return greater<_Tp>{}(get_underlying(__x), get_underlying(__y));
497*38fd1498Szrj     }
498*38fd1498Szrj
499*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
500*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
501*38fd1498Szrj     typedef bool result_type;
502*38fd1498Szrj   };
503*38fd1498Szrj
504*38fd1498Szrj template <typename _Tp>
505*38fd1498Szrj   struct less_equal<experimental::propagate_const<_Tp>>
506*38fd1498Szrj   {
507*38fd1498Szrj     constexpr bool
508*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
509*38fd1498Szrj	        const experimental::propagate_const<_Tp>& __y) const
510*38fd1498Szrj     {
511*38fd1498Szrj       return less_equal<_Tp>{}(get_underlying(__x), get_underlying(__y));
512*38fd1498Szrj     }
513*38fd1498Szrj
514*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
515*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
516*38fd1498Szrj     typedef bool result_type;
517*38fd1498Szrj   };
518*38fd1498Szrj
519*38fd1498Szrj template <typename _Tp>
520*38fd1498Szrj   struct greater_equal<experimental::propagate_const<_Tp>>
521*38fd1498Szrj   {
522*38fd1498Szrj     constexpr bool
523*38fd1498Szrj     operator()(const experimental::propagate_const<_Tp>& __x,
524*38fd1498Szrj		const experimental::propagate_const<_Tp>& __y) const
525*38fd1498Szrj     {
526*38fd1498Szrj       return greater_equal<_Tp>{}(get_underlying(__x), get_underlying(__y));
527*38fd1498Szrj     }
528*38fd1498Szrj
529*38fd1498Szrj     typedef experimental::propagate_const<_Tp> first_argument_type;
530*38fd1498Szrj     typedef experimental::propagate_const<_Tp> second_argument_type;
531*38fd1498Szrj     typedef bool result_type;
532*38fd1498Szrj   };
533*38fd1498Szrj
534*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION
535*38fd1498Szrj} // namespace std
536*38fd1498Szrj
537*38fd1498Szrj#endif // C++14
538*38fd1498Szrj
539*38fd1498Szrj#endif // _GLIBCXX_EXPERIMENTAL_PROPAGATE_CONST
540