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