Skip to content

Commit e8c0494

Browse files
authored
Fix implicit long_int conversion
Disable implicit conversion from larger to smaller integer type
1 parent 3c87a2e commit e8c0494

1 file changed

Lines changed: 39 additions & 6 deletions

File tree

include/long_uint.h

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@
3030
//
3131
////////////////////////////////////////////////////////////////////////////////////////////////////
3232
//
33-
// $Id: long_uint.h 151 2021-09-07 11:33:21Z ykalmykov $
33+
// $Id: long_uint.h 152 2021-09-07 14:14:03Z ykalmykov $
3434
//
3535
////////////////////////////////////////////////////////////////////////////////////////////////////
3636

3737
#pragma once
3838

3939
#include "long_math.h"
40-
#include "long_math_msvc.h"
4140
#include "long_math_gcc.h"
41+
#include "long_math_msvc.h"
4242

4343
#include <optional>
4444

@@ -70,6 +70,8 @@ class long_uint_t
7070
constexpr long_uint_t() noexcept = default;
7171
constexpr long_uint_t(const long_uint_t& that) noexcept = default;
7272
constexpr long_uint_t(long_uint_t&& that) noexcept = default;
73+
template<uint_t other_size, std::enable_if_t<(other_size < size), int> = 0>
74+
constexpr long_uint_t(const long_uint_t<native_t, other_size>& that) noexcept;
7375
constexpr long_uint_t(native_array_t digits) noexcept;
7476
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int> = 0>
7577
constexpr long_uint_t(type_t value) noexcept;
@@ -84,6 +86,8 @@ class long_uint_t
8486
constexpr long_uint_t& operator=(const long_uint_t& that) noexcept = default;
8587
constexpr long_uint_t& operator=(long_uint_t&& that) noexcept = default;
8688

89+
template<uint_t other_size, std::enable_if_t<(other_size < size), int> = 0>
90+
explicit constexpr operator long_uint_t<native_t, other_size>() const noexcept;
8791
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int> = 0>
8892
explicit constexpr operator type_t() const noexcept;
8993
template<typename type_t, std::enable_if_t<std::is_signed_v<type_t>, int> = 0>
@@ -153,6 +157,18 @@ constexpr type_t muldiv(const type_t& value, const type_t& multiplier, const typ
153157
////////////////////////////////////////////////////////////////////////////////////////////////////
154158
// construction/destruction
155159

160+
template<typename native_t, uint_t size>
161+
template<uint_t other_size, std::enable_if_t<(other_size < size), int>>
162+
constexpr long_uint_t<native_t, size>::long_uint_t(const long_uint_t<native_t, other_size>& that) noexcept
163+
{
164+
constexpr uint_t value_size = std::min(size, other_size);
165+
166+
for (uint_t n = 0; n < value_size; ++n)
167+
digits[n] = that.digits[n];
168+
for (uint_t n = value_size; n < std::size(digits); ++n)
169+
digits[n] = native_t(0);
170+
}
171+
156172
template<typename native_t, uint_t size>
157173
constexpr long_uint_t<native_t, size>::long_uint_t(native_array_t digits) noexcept
158174
: digits(std::move(digits))
@@ -185,7 +201,7 @@ constexpr long_uint_t<native_t, size>::long_uint_t(type_t value) noexcept
185201
for (uint_t n = 0; n < value_size; ++n) {
186202

187203
digits[n] = value & native_t(~0);
188-
value >>= std::min(bit_count_v<type_t> - 1, bit_count_v<native_t>);
204+
value >>= std::min(bit_count_v<type_t> - 1, bit_count_v<native_t>);
189205
}
190206
for (uint_t n = value_size; n < std::size(digits); ++n)
191207
digits[n] = extension;
@@ -215,6 +231,21 @@ constexpr void long_uint_t<native_t, size>::swap(long_uint_t& that) noexcept
215231

216232

217233

234+
////////////////////////////////////////////////////////////////////////////////////////////////////
235+
template<typename native_t, uint_t size>
236+
template<uint_t other_size, std::enable_if_t<(other_size < size), int>>
237+
constexpr long_uint_t<native_t, size>::operator long_uint_t<native_t, other_size>() const noexcept
238+
{
239+
long_uint_t<native_t, other_size> tmp;
240+
241+
for (uint_t n = 0; n < other_size; ++n)
242+
tmp.digits[n] = digits[n];
243+
244+
return tmp;
245+
}
246+
247+
248+
218249
////////////////////////////////////////////////////////////////////////////////////////////////////
219250
template<typename native_t, uint_t size>
220251
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int>>
@@ -615,7 +646,7 @@ constexpr long_uint_t<native_t, size>& long_uint_t<native_t, size>::operator/=(c
615646
{
616647
std::optional<long_uint_t> remainder;
617648
*this = divr_helper<long_uint_t>::calc(*this, that, remainder);
618-
649+
619650
return *this;
620651
}
621652

@@ -636,7 +667,7 @@ constexpr long_uint_t<native_t, size>& long_uint_t<native_t, size>::operator%=(c
636667
{
637668
long_uint_t dividend = *this;
638669
divr_helper<long_uint_t>::calc(dividend, that, *this);
639-
670+
640671
return *this;
641672
}
642673

@@ -785,7 +816,9 @@ namespace impl
785816
// enum parse_result
786817
////////////////////////////////////////////////////////////////////////////////////////////////////
787818

788-
enum class parse_result { ok, unexpected, overflow };
819+
enum class parse_result { ok,
820+
unexpected,
821+
overflow };
789822
constexpr uint8_t kSeparator = 0xff;
790823

791824

0 commit comments

Comments
 (0)