7 #if !defined(CNL_IMPL_DUPLEX_INTEGER_NARROWEST_INTEGER_H)
8 #define CNL_IMPL_DUPLEX_INTEGER_NARROWEST_INTEGER_H
10 #include "../num_traits/digits.h"
11 #include "../num_traits/max_digits.h"
12 #include "../num_traits/set_digits.h"
13 #include "../numbers/set_signedness.h"
14 #include "../numbers/signedness.h"
15 #include "declaration.h"
18 #include <type_traits>
27 template<
typename Word,
int NumWords>
28 struct multiword_integer;
30 template<
typename Word>
31 struct multiword_integer<Word, 1> {
35 template<
typename Word>
36 struct multiword_integer<Word, 2> {
38 using lower = numbers::set_signedness_t<upper, false>;
39 using type = duplex_integer<upper, lower>;
42 template<
typename Word,
int NumWords>
43 struct multiword_integer {
45 static_assert(NumWords > 2);
46 static constexpr
auto num_words = NumWords;
47 static constexpr
auto num_words_rounded_up = (1 << used_digits(num_words - 1));
48 static constexpr
auto upper_num_words = num_words_rounded_up / 2;
49 static constexpr
auto lower_num_words = num_words - upper_num_words;
50 using upper =
typename multiword_integer<Word, upper_num_words>::type;
51 using lower =
typename multiword_integer<
52 numbers::set_signedness_t<Word, false>, lower_num_words>::type;
55 using type = duplex_integer<upper, lower>;
58 template<
typename Word,
int NumWords>
59 using multiword_integer_t =
typename multiword_integer<Word, NumWords>::type;
64 template<
typename Word>
65 [[nodiscard]] constexpr
auto duplex_num_words(
int min_digits)
67 auto const num_sign_bits = numbers::signedness_v<Word>;
68 auto const word_digits = digits_v<Word> + num_sign_bits;
69 auto const required_num_words =
70 (min_digits + num_sign_bits + word_digits - 1) / word_digits;
72 return required_num_words;
75 template<
int Digits,
typename Narrowest>
76 struct narrowest_integer {
77 using type = multiword_integer_t<Narrowest, duplex_num_words<Narrowest>(Digits)>;
80 template<
int Digits,
typename Narrowest>
81 using narrowest_integer_t =
82 typename narrowest_integer<Digits, Narrowest>::type;
86 #endif // CNL_IMPL_DUPLEX_INTEGER_NARROWEST_INTEGER_H