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