@@ -56,11 +56,9 @@ add_with_carry_const(T a, T b, T carry_in) {
56
56
return {sum, carry_out};
57
57
}
58
58
59
- // This version is not always valid for constepxr because it's overriden below
60
- // if builtins are available.
61
59
template <typename T>
62
- LIBC_INLINE cpp::enable_if_t <cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
63
- SumCarry<T>>
60
+ LIBC_INLINE constexpr cpp::enable_if_t <
61
+ cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, SumCarry<T>>
64
62
add_with_carry (T a, T b, T carry_in) {
65
63
return add_with_carry_const<T>(a, b, carry_in);
66
64
}
@@ -69,48 +67,68 @@ add_with_carry(T a, T b, T carry_in) {
69
67
// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
70
68
71
69
template <>
72
- LIBC_INLINE SumCarry<unsigned char >
70
+ LIBC_INLINE constexpr SumCarry<unsigned char >
73
71
add_with_carry<unsigned char >(unsigned char a, unsigned char b,
74
72
unsigned char carry_in) {
75
- SumCarry<unsigned char > result{0 , 0 };
76
- result.sum = __builtin_addcb (a, b, carry_in, &result.carry );
77
- return result;
73
+ if (__builtin_is_constant_evaluated ()) {
74
+ return add_with_carry_const<unsigned char >(a, b, carry_in);
75
+ } else {
76
+ SumCarry<unsigned char > result{0 , 0 };
77
+ result.sum = __builtin_addcb (a, b, carry_in, &result.carry );
78
+ return result;
79
+ }
78
80
}
79
81
80
82
template <>
81
- LIBC_INLINE SumCarry<unsigned short >
83
+ LIBC_INLINE constexpr SumCarry<unsigned short >
82
84
add_with_carry<unsigned short >(unsigned short a, unsigned short b,
83
85
unsigned short carry_in) {
84
- SumCarry<unsigned short > result{0 , 0 };
85
- result.sum = __builtin_addcs (a, b, carry_in, &result.carry );
86
- return result;
86
+ if (__builtin_is_constant_evaluated ()) {
87
+ return add_with_carry_const<unsigned short >(a, b, carry_in);
88
+ } else {
89
+ SumCarry<unsigned short > result{0 , 0 };
90
+ result.sum = __builtin_addcs (a, b, carry_in, &result.carry );
91
+ return result;
92
+ }
87
93
}
88
94
89
95
template <>
90
- LIBC_INLINE SumCarry<unsigned int >
96
+ LIBC_INLINE constexpr SumCarry<unsigned int >
91
97
add_with_carry<unsigned int >(unsigned int a, unsigned int b,
92
98
unsigned int carry_in) {
93
- SumCarry<unsigned int > result{0 , 0 };
94
- result.sum = __builtin_addc (a, b, carry_in, &result.carry );
95
- return result;
99
+ if (__builtin_is_constant_evaluated ()) {
100
+ return add_with_carry_const<unsigned int >(a, b, carry_in);
101
+ } else {
102
+ SumCarry<unsigned int > result{0 , 0 };
103
+ result.sum = __builtin_addc (a, b, carry_in, &result.carry );
104
+ return result;
105
+ }
96
106
}
97
107
98
108
template <>
99
- LIBC_INLINE SumCarry<unsigned long >
109
+ LIBC_INLINE constexpr SumCarry<unsigned long >
100
110
add_with_carry<unsigned long >(unsigned long a, unsigned long b,
101
111
unsigned long carry_in) {
102
- SumCarry<unsigned long > result{0 , 0 };
103
- result.sum = __builtin_addcl (a, b, carry_in, &result.carry );
104
- return result;
112
+ if (__builtin_is_constant_evaluated ()) {
113
+ return add_with_carry_const<unsigned long >(a, b, carry_in);
114
+ } else {
115
+ SumCarry<unsigned long > result{0 , 0 };
116
+ result.sum = __builtin_addcl (a, b, carry_in, &result.carry );
117
+ return result;
118
+ }
105
119
}
106
120
107
121
template <>
108
- LIBC_INLINE SumCarry<unsigned long long >
122
+ LIBC_INLINE constexpr SumCarry<unsigned long long >
109
123
add_with_carry<unsigned long long >(unsigned long long a, unsigned long long b,
110
124
unsigned long long carry_in) {
111
- SumCarry<unsigned long long > result{0 , 0 };
112
- result.sum = __builtin_addcll (a, b, carry_in, &result.carry );
113
- return result;
125
+ if (__builtin_is_constant_evaluated ()) {
126
+ return add_with_carry_const<unsigned long long >(a, b, carry_in);
127
+ } else {
128
+ SumCarry<unsigned long long > result{0 , 0 };
129
+ result.sum = __builtin_addcll (a, b, carry_in, &result.carry );
130
+ return result;
131
+ }
114
132
}
115
133
116
134
#endif // LIBC_HAS_BUILTIN(__builtin_addc)
@@ -135,8 +153,8 @@ sub_with_borrow_const(T a, T b, T borrow_in) {
135
153
// This version is not always valid for constepxr because it's overriden below
136
154
// if builtins are available.
137
155
template <typename T>
138
- LIBC_INLINE cpp::enable_if_t <cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
139
- DiffBorrow<T>>
156
+ LIBC_INLINE constexpr cpp::enable_if_t <
157
+ cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, DiffBorrow<T>>
140
158
sub_with_borrow (T a, T b, T borrow_in) {
141
159
return sub_with_borrow_const<T>(a, b, borrow_in);
142
160
}
@@ -145,48 +163,68 @@ sub_with_borrow(T a, T b, T borrow_in) {
145
163
// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
146
164
147
165
template <>
148
- LIBC_INLINE DiffBorrow<unsigned char >
166
+ LIBC_INLINE constexpr DiffBorrow<unsigned char >
149
167
sub_with_borrow<unsigned char >(unsigned char a, unsigned char b,
150
168
unsigned char borrow_in) {
151
- DiffBorrow<unsigned char > result{0 , 0 };
152
- result.diff = __builtin_subcb (a, b, borrow_in, &result.borrow );
153
- return result;
169
+ if (__builtin_is_constant_evaluated ()) {
170
+ return sub_with_borrow_const<unsigned char >(a, b, borrow_in);
171
+ } else {
172
+ DiffBorrow<unsigned char > result{0 , 0 };
173
+ result.diff = __builtin_subcb (a, b, borrow_in, &result.borrow );
174
+ return result;
175
+ }
154
176
}
155
177
156
178
template <>
157
- LIBC_INLINE DiffBorrow<unsigned short >
179
+ LIBC_INLINE constexpr DiffBorrow<unsigned short >
158
180
sub_with_borrow<unsigned short >(unsigned short a, unsigned short b,
159
181
unsigned short borrow_in) {
160
- DiffBorrow<unsigned short > result{0 , 0 };
161
- result.diff = __builtin_subcs (a, b, borrow_in, &result.borrow );
162
- return result;
182
+ if (__builtin_is_constant_evaluated ()) {
183
+ return sub_with_borrow_const<unsigned short >(a, b, borrow_in);
184
+ } else {
185
+ DiffBorrow<unsigned short > result{0 , 0 };
186
+ result.diff = __builtin_subcs (a, b, borrow_in, &result.borrow );
187
+ return result;
188
+ }
163
189
}
164
190
165
191
template <>
166
- LIBC_INLINE DiffBorrow<unsigned int >
192
+ LIBC_INLINE constexpr DiffBorrow<unsigned int >
167
193
sub_with_borrow<unsigned int >(unsigned int a, unsigned int b,
168
194
unsigned int borrow_in) {
169
- DiffBorrow<unsigned int > result{0 , 0 };
170
- result.diff = __builtin_subc (a, b, borrow_in, &result.borrow );
171
- return result;
195
+ if (__builtin_is_constant_evaluated ()) {
196
+ return sub_with_borrow_const<unsigned int >(a, b, borrow_in);
197
+ } else {
198
+ DiffBorrow<unsigned int > result{0 , 0 };
199
+ result.diff = __builtin_subc (a, b, borrow_in, &result.borrow );
200
+ return result;
201
+ }
172
202
}
173
203
174
204
template <>
175
- LIBC_INLINE DiffBorrow<unsigned long >
205
+ LIBC_INLINE constexpr DiffBorrow<unsigned long >
176
206
sub_with_borrow<unsigned long >(unsigned long a, unsigned long b,
177
207
unsigned long borrow_in) {
178
- DiffBorrow<unsigned long > result{0 , 0 };
179
- result.diff = __builtin_subcl (a, b, borrow_in, &result.borrow );
180
- return result;
208
+ if (__builtin_is_constant_evaluated ()) {
209
+ return sub_with_borrow_const<unsigned long >(a, b, borrow_in);
210
+ } else {
211
+ DiffBorrow<unsigned long > result{0 , 0 };
212
+ result.diff = __builtin_subcl (a, b, borrow_in, &result.borrow );
213
+ return result;
214
+ }
181
215
}
182
216
183
217
template <>
184
- LIBC_INLINE DiffBorrow<unsigned long long >
218
+ LIBC_INLINE constexpr DiffBorrow<unsigned long long >
185
219
sub_with_borrow<unsigned long long >(unsigned long long a, unsigned long long b,
186
220
unsigned long long borrow_in) {
187
- DiffBorrow<unsigned long long > result{0 , 0 };
188
- result.diff = __builtin_subcll (a, b, borrow_in, &result.borrow );
189
- return result;
221
+ if (__builtin_is_constant_evaluated ()) {
222
+ return sub_with_borrow_const<unsigned long long >(a, b, borrow_in);
223
+ } else {
224
+ DiffBorrow<unsigned long long > result{0 , 0 };
225
+ result.diff = __builtin_subcll (a, b, borrow_in, &result.borrow );
226
+ return result;
227
+ }
190
228
}
191
229
192
230
#endif // LIBC_HAS_BUILTIN(__builtin_subc)
0 commit comments