libstdc++
stdckdint.h
Go to the documentation of this file.
1// C compatibility header <stdckdint.h> -*- C++ -*-
2
3// Copyright The GNU Toolchain Authors.
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 include/stdckdint.h
26 * This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_STDCKDINT_H
30#define _GLIBCXX_STDCKDINT_H
31
32#define __glibcxx_want_stdckdint_h
33#include <bits/version.h>
34
35#ifdef __cpp_lib_stdckdint_h // C++ >= 26
36
37#include <type_traits>
38#include <concepts>
39
40#define __STDC_VERSION_STDCKDINT_H__ 202311L
41
42#ifndef _GLIBCXX_DOXYGEN
43// We define these in our own namespace, but let Doxygen think otherwise.
44namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
45{
46#endif
47/// @cond undocumented
48namespace __detail
49{
50 template<typename _Tp>
51 concept __cv_unqual_signed_or_unsigned_integer_type
52 = std::same_as<_Tp, std::remove_cv_t<_Tp>>
53 && std::__is_standard_integer<_Tp>::value;
54}
55/// @endcond
56
57/** Checked integer arithmetic
58 *
59 * Performs arithmetic on `__a` and `__b` and stores the result in `*__result`,
60 * with overflow detection.
61 * The arithmetic is performed in infinite signed precision, without overflow,
62 * then converted to the result type, `_Tp1`. If the converted result is not
63 * equal to the infinite precision result, the stored result is wrapped to the
64 * width of `_Tp1` and `true` is returned. Otherwise, the stored result is
65 * correct and `false` is returned.
66 *
67 * @param __result A pointer to a signed or unsigned integer type.
68 * @param __a A signed or unsigned integer type.
69 * @param __b A signed or unsigned integer type.
70 * @return True if overflow occurred, false otherwise.
71 * @since C++26
72 * @{
73 */
74template<typename _Tp1, typename _Tp2, typename _Tp3>
75 inline bool
76 ckd_add(_Tp1* __result, _Tp2 __a, _Tp3 __b)
77 {
78 using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
79 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
80 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
81 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
82 return __builtin_add_overflow(__a, __b, __result);
83 }
84
85template<typename _Tp1, typename _Tp2, typename _Tp3>
86 inline bool
87 ckd_sub(_Tp1* __result, _Tp2 __a, _Tp3 __b)
88 {
89 using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
90 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
91 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
92 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
93 return __builtin_sub_overflow(__a, __b, __result);
94 }
95
96template<typename _Tp1, typename _Tp2, typename _Tp3>
97 inline bool
98 ckd_mul(_Tp1* __result, _Tp2 __a, _Tp3 __b)
99 {
100 using __gnu_cxx::__detail::__cv_unqual_signed_or_unsigned_integer_type;
101 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp1>);
102 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp2>);
103 static_assert(__cv_unqual_signed_or_unsigned_integer_type<_Tp3>);
104 return __builtin_mul_overflow(__a, __b, __result);
105 }
106/// @}
107#ifndef _GLIBCXX_DOXYGEN
108}
109
110using __gnu_cxx::ckd_add;
111using __gnu_cxx::ckd_sub;
112using __gnu_cxx::ckd_mul;
113#endif
114
115#endif // __cpp_lib_stdckdint_h
116
117#endif // _GLIBCXX_STDCKDINT_H
GNU extensions for public use.
Implementation details not part of the namespace __gnu_cxx interface.