|
15 | 15 |
|
16 | 16 | #include <algorithm> |
17 | 17 | #include <array> |
18 | | - #include <functional> |
19 | 18 | #include <iterator> |
20 | 19 | #include <type_traits> |
21 | 20 |
|
|
45 | 44 | class pi_spigot |
46 | 45 | { |
47 | 46 | public: |
48 | | - static constexpr auto result_digit() -> std::uint32_t { return ResultDigit; } |
49 | | - |
50 | 47 | using unsigned_small_type = UnsignedSmallType; |
51 | 48 | using unsigned_large_type = UnsignedLargeType; |
52 | 49 |
|
53 | 50 | private: |
54 | | - static constexpr auto loop_digit() -> std::uint32_t { return LoopDigit; } |
55 | | - |
56 | | - static_assert(loop_digit() <= static_cast<std::uint32_t>(std::numeric_limits<unsigned_small_type>::digits10), |
57 | | - "Error: loop_digit exceeds the number of base-10 digits in its constituent unsigned_small_type"); |
58 | | - |
59 | | - static_assert(result_digit() <= static_cast<std::uint32_t>(UINT32_C(100001)), |
60 | | - "Error: result_digit exceeds its limit of 100,001"); |
61 | | - |
62 | | - static_assert(std::numeric_limits<unsigned_small_type>::digits * 2 == std::numeric_limits<unsigned_large_type>::digits, |
63 | | - "Error: unsigned_large_type must be exactly twice as wide as unsigned_small_type"); |
| 51 | + using callback_type = void(*)(const std::uint32_t); |
64 | 52 |
|
65 | | - static_assert((!std::numeric_limits<unsigned_small_type>::is_signed), |
66 | | - "Error: unsigned_small_type must be unsigned"); |
| 53 | + static constexpr auto result_digit() -> std::uint32_t { return ResultDigit; } |
67 | 54 |
|
68 | | - static_assert((!std::numeric_limits<unsigned_large_type>::is_signed), |
69 | | - "Error: unsigned_large_type must be unsigned"); |
| 55 | + static constexpr auto loop_digit() -> std::uint32_t { return LoopDigit; } |
70 | 56 |
|
71 | 57 | static constexpr auto input_scale(std::uint32_t x) -> std::uint32_t |
72 | 58 | { |
|
83 | 69 | } |
84 | 70 |
|
85 | 71 | public: |
86 | | - static constexpr std::uint32_t input_static_size { input_scale(result_digit()) }; |
87 | | - |
88 | | - static constexpr auto get_input_static_size() -> std::uint32_t { return input_static_size; } |
| 72 | + static constexpr auto get_input_static_size() -> std::uint32_t { return input_scale(result_digit()); } |
89 | 73 |
|
90 | 74 | constexpr pi_spigot() = default; // LCOV_EXCL_LINE |
91 | 75 |
|
|
104 | 88 | return my_operation_count; |
105 | 89 | } |
106 | 90 |
|
107 | | - using callback_type = void(*)(const std::uint32_t); |
108 | | - |
109 | | - |
110 | 91 | template<typename InputIteratorType> |
111 | 92 | auto calculate(InputIteratorType my_pi_in, |
112 | 93 | callback_type pfn_callback_to_report_digits10 = nullptr, |
|
126 | 107 | } |
127 | 108 |
|
128 | 109 | using local_input_iterator_type = InputIteratorType; |
129 | | - using local_input_value_type = typename std::iterator_traits<local_input_iterator_type>::value_type; |
| 110 | + using local_input_value_type = typename std::iterator_traits<local_input_iterator_type>::value_type; |
130 | 111 |
|
131 | 112 | // Invalidate the input container values at the first 32 indices. |
132 | 113 | const std::uint32_t |
133 | 114 | invalidate_size |
134 | 115 | { |
135 | | - (std::min)(static_cast<std::uint32_t>(UINT8_C(32)), input_static_size) |
| 116 | + (std::min)(std::uint32_t { UINT8_C(32) }, get_input_static_size()) |
136 | 117 | }; |
137 | 118 |
|
138 | 119 | std::fill(my_pi_in, |
|
339 | 320 | pow10(loop_digit()) / static_cast<unsigned>(UINT8_C(5)) |
340 | 321 | ); |
341 | 322 | } |
342 | | - }; |
343 | 323 |
|
| 324 | + static_assert(loop_digit() <= static_cast<std::uint32_t>(std::numeric_limits<unsigned_small_type>::digits10), |
| 325 | + "Error: loop_digit exceeds the number of base-10 digits in its constituent unsigned_small_type"); |
| 326 | + |
| 327 | + static_assert(result_digit() <= static_cast<std::uint32_t>(UINT32_C(100001)), |
| 328 | + "Error: result_digit exceeds its limit of 100,001"); |
| 329 | + |
| 330 | + static_assert(std::numeric_limits<unsigned_small_type>::digits * 2 == std::numeric_limits<unsigned_large_type>::digits, |
| 331 | + "Error: unsigned_large_type must be exactly twice as wide as unsigned_small_type"); |
| 332 | + |
| 333 | + static_assert((!std::numeric_limits<unsigned_small_type>::is_signed), |
| 334 | + "Error: unsigned_small_type must be unsigned"); |
| 335 | + |
| 336 | + static_assert((!std::numeric_limits<unsigned_large_type>::is_signed), |
| 337 | + "Error: unsigned_large_type must be unsigned"); |
| 338 | + }; |
344 | 339 |
|
345 | 340 | template<const std::uint32_t ResultDigit, |
346 | 341 | const std::uint32_t LoopDigit, |
|
0 commit comments