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