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