Skip to content

Commit 69a98f5

Browse files
committed
Fixed behavior of some constructors in constant expressions
1 parent 83eedd8 commit 69a98f5

File tree

3 files changed

+27
-36
lines changed

3 files changed

+27
-36
lines changed

include/slimcpplib/long_int.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,11 @@ constexpr long_int_t<native_t, size>::long_int_t(const long_uint_t<native_t, siz
153153
template<typename native_t, uint_t size>
154154
template<uint_t other_size, std::enable_if_t<(other_size < size), int>>
155155
constexpr long_int_t<native_t, size>::long_int_t(const long_int_t<native_t, other_size>& that) noexcept
156+
: long_uint_t<native_t, size>(that)
156157
{
157158
constexpr uint_t value_size = std::min(size, other_size);
158159
const native_t extension = static_cast<native_t>(!that.sign() ? 0 : native_t(~0));
159160

160-
for (uint_t n = 0; n < value_size; ++n)
161-
digits[n] = that.digits[n];
162161
for (uint_t n = value_size; n < std::size(digits); ++n)
163162
digits[n] = extension;
164163
}

include/slimcpplib/long_math.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ using half_t = typename half_type<type_t>::type;
121121

122122
// make array from specified array
123123

124-
template<typename type_t, uint_t size, typename func_t>
125-
constexpr std::array<type_t, size> make_array(const std::array<type_t, size>& arr, const func_t& func);
126-
template<typename type_t, uint_t size, typename func_t, uint_t... idx>
127-
constexpr std::array<type_t, size> make_array(const std::array<type_t, size>& arr, const func_t& func, std::integer_sequence<uint_t, idx...>);
124+
template<uint_t size_out, typename type_t, uint_t size_in, typename func_t>
125+
constexpr std::array<type_t, size_out> make_array(const std::array<type_t, size_in>& arr, const func_t& func);
126+
template<uint_t size_out, typename type_t, uint_t size_in, typename func_t, uint_t... idx>
127+
constexpr std::array<type_t, size_out> make_array(const std::array<type_t, size_in>& arr, const func_t& func, std::integer_sequence<uint_t, idx...>);
128128

129129
// extract low half of unsigned integer
130130

@@ -190,19 +190,20 @@ constexpr type_t divr2(type_t value1_hi, type_t value1_lo, type_t value2, std::o
190190
// standalone routines
191191
////////////////////////////////////////////////////////////////////////////////////////////////////
192192

193-
template<typename type_t, uint_t size, typename func_t>
194-
constexpr std::array<type_t, size> make_array(const std::array<type_t, size>& arr, const func_t& func)
193+
template<uint_t size_out, typename type_t, uint_t size_in, typename func_t>
194+
constexpr std::array<type_t, size_out> make_array(const std::array<type_t, size_in>& arr, const func_t& func)
195195
{
196-
return make_array(arr, func, std::make_integer_sequence<uint_t, size>{});
196+
constexpr uint_t size = std::min(size_in, size_out);
197+
return make_array<size_out>(arr, func, std::make_integer_sequence<uint_t, size>{});
197198
}
198199

199200

200201

201202
////////////////////////////////////////////////////////////////////////////////////////////////////
202-
template<typename type_t, uint_t size, typename func_t, uint_t... idx>
203-
constexpr std::array<type_t, size> make_array(const std::array<type_t, size>& arr, const func_t& func, std::integer_sequence<uint_t, idx...>)
203+
template<uint_t size_out, typename type_t, uint_t size_in, typename func_t, uint_t... idx>
204+
constexpr std::array<type_t, size_out> make_array(const std::array<type_t, size_in>& arr, const func_t& func, std::integer_sequence<uint_t, idx...>)
204205
{
205-
return std::array<type_t, size>{ (func(idx, arr[idx]))... };
206+
return std::array<type_t, size_out>{ (func(arr, idx))... };
206207
}
207208

208209

include/slimcpplib/long_uint.h

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,8 @@ constexpr type_t muldiv(const type_t& value, const type_t& multiplier, const typ
161161
template<typename native_t, uint_t size>
162162
template<uint_t other_size, std::enable_if_t<(other_size < size), int>>
163163
constexpr long_uint_t<native_t, size>::long_uint_t(const long_uint_t<native_t, other_size>& that) noexcept
164+
: digits(make_array<size>(that.digits, [](const auto& digits, uint_t idx) { return digits[idx]; }))
164165
{
165-
constexpr uint_t value_size = std::min(size, other_size);
166-
167-
for (uint_t n = 0; n < value_size; ++n)
168-
digits[n] = that.digits[n];
169-
for (uint_t n = value_size; n < std::size(digits); ++n)
170-
digits[n] = native_t(0);
171166
}
172167

173168
template<typename native_t, uint_t size>
@@ -179,17 +174,18 @@ constexpr long_uint_t<native_t, size>::long_uint_t(native_array_t digits) noexce
179174
template<typename native_t, uint_t size>
180175
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int>>
181176
constexpr long_uint_t<native_t, size>::long_uint_t(type_t value) noexcept
182-
{
177+
: digits(make_array<size>(digits, [&value](const auto& /*digits*/, uint_t idx) {
178+
183179
constexpr uint_t value_size = std::min(size, (byte_count_v<type_t> + byte_count_v<native_t> - 1) / byte_count_v<native_t>);
184-
const native_t extension = 0;
185180

186-
for (uint_t n = 0; n < value_size; ++n) {
181+
if (idx >= value_size)
182+
return native_t(0);
187183

188-
digits[n] = value & ~native_t(0);
189-
value >>= std::min(bit_count_v<type_t> - 1, bit_count_v<native_t>);
190-
}
191-
for (uint_t n = value_size; n < std::size(digits); ++n)
192-
digits[n] = extension;
184+
const native_t digit = value & ~native_t(0);
185+
value >>= std::min(bit_count_v<type_t> - 1, bit_count_v<native_t>);
186+
return digit;
187+
}))
188+
{
193189
}
194190

195191
template<typename native_t, uint_t size>
@@ -237,12 +233,7 @@ template<typename native_t, uint_t size>
237233
template<uint_t other_size, std::enable_if_t<(other_size < size), int>>
238234
constexpr long_uint_t<native_t, size>::operator long_uint_t<native_t, other_size>() const noexcept
239235
{
240-
long_uint_t<native_t, other_size> tmp;
241-
242-
for (uint_t n = 0; n < other_size; ++n)
243-
tmp.digits[n] = digits[n];
244-
245-
return tmp;
236+
return make_array<other_size>(digits, [](const auto& digits, uint_t idx) { return digits[idx]; });
246237
}
247238

248239

@@ -336,8 +327,8 @@ constexpr bool long_uint_t<native_t, size>::operator>=(const long_uint_t& that)
336327
template<typename native_t, uint_t size>
337328
constexpr long_uint_t<native_t, size> long_uint_t<native_t, size>::operator~() const noexcept
338329
{
339-
return make_array(digits, [](uint_t /*idx*/, native_t value) {
340-
return ~value;
330+
return make_array<size>(digits, [](const auto& digits, uint_t idx) {
331+
return ~digits[idx];
341332
});
342333
}
343334

@@ -576,8 +567,8 @@ constexpr long_uint_t<native_t, size> long_uint_t<native_t, size>::operator-() c
576567
{
577568
bool borrow = true;
578569

579-
return make_array(digits, [&borrow](uint_t /*idx*/, native_t value) {
580-
return ~subb<native_t>(value, 0, borrow);
570+
return make_array<size>(digits, [&borrow](const auto& digits, uint_t idx) {
571+
return ~subb<native_t>(digits[idx], 0, borrow);
581572
});
582573
}
583574

0 commit comments

Comments
 (0)