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#if __cplusplus > 202302L
33#include <type_traits>
34#include <concepts>
35
36#define __STDC_VERSION_STDCKDINT_H__ 202311L
37
38#ifndef _GLIBCXX_DOXYGEN
39// We define these in our own namespace, but let Doxygen think otherwise.
40namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
41{
42#endif
43
44/** Checked integer arithmetic
45 *
46 * Performs arithmetic on `__a` and `__b` and stores the result in `*__result`,
47 * with overflow detection.
48 * The arithmetic is performed in infinite signed precision, without overflow,
49 * then converted to the result type, `_Tp1`. If the converted result is not
50 * equal to the infinite precision result, the stored result is wrapped to the
51 * width of `_Tp1` and `true` is returned. Otherwise, the stored result is
52 * correct and `false` is returned.
53 *
54 * @param __result A pointer to a signed or unsigned integer type.
55 * @param __a A signed or unsigned integer type.
56 * @param __b A signed or unsigned integer type.
57 * @return True if overflow occurred, false otherwise.
58 * @since C++26
59 * @{
60 */
61template<typename _Tp1, typename _Tp2, typename _Tp3>
62 inline bool
63 ckd_add(_Tp1* __result, _Tp2 __a, _Tp3 __b)
64 {
65 static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
66 static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
67 static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
68 return __builtin_add_overflow(__a, __b, __result);
69 }
70
71template<typename _Tp1, typename _Tp2, typename _Tp3>
72 inline bool
73 ckd_sub(_Tp1* __result, _Tp2 __a, _Tp3 __b)
74 {
75 static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
76 static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
77 static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
78 return __builtin_sub_overflow(__a, __b, __result);
79 }
80
81template<typename _Tp1, typename _Tp2, typename _Tp3>
82 inline bool
83 ckd_mul(_Tp1* __result, _Tp2 __a, _Tp3 __b)
84 {
85 static_assert(std::__is_signed_or_unsigned_integer<_Tp1>::value);
86 static_assert(std::__is_signed_or_unsigned_integer<_Tp2>::value);
87 static_assert(std::__is_signed_or_unsigned_integer<_Tp3>::value);
88 return __builtin_mul_overflow(__a, __b, __result);
89 }
90/// @}
91#ifndef _GLIBCXX_DOXYGEN
92} // namespace __gnu_cxx
93
94using __gnu_cxx::ckd_add;
95using __gnu_cxx::ckd_sub;
96using __gnu_cxx::ckd_mul;
97#endif
98
99#endif // C++26
100
101#endif // _GLIBCXX_STDCKDINT_H
GNU extensions for public use.