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.
44 namespace __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  */
65 template<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 
75 template<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 
85 template<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 
98 using __gnu_cxx::ckd_add;
99 using __gnu_cxx::ckd_sub;
100 using __gnu_cxx::ckd_mul;
101 #endif
102 
103 #endif // __cpp_lib_stdckdint_h
104 
105 #endif // _GLIBCXX_STDCKDINT_H
GNU extensions for public use.