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+
156172template <typename native_t , uint_t size>
157173constexpr 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// //////////////////////////////////////////////////////////////////////////////////////////////////
219250template <typename native_t , uint_t size>
220251template <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 };
789822constexpr uint8_t kSeparator = 0xff ;
790823
791824
0 commit comments