|
10 | 10 | #include "ada/url_components.h"
|
11 | 11 | #include <optional>
|
12 | 12 | #include <string>
|
| 13 | +#if ADA_REGULAR_VISUAL_STUDIO |
| 14 | +#include <intrin.h> |
| 15 | +#endif // ADA_REGULAR_VISUAL_STUDIO |
13 | 16 |
|
14 | 17 | namespace ada {
|
15 | 18 | [[nodiscard]] ada_really_inline bool url::includes_credentials() const noexcept {
|
@@ -77,6 +80,39 @@ namespace ada {
|
77 | 80 | return out << u.to_string();
|
78 | 81 | }
|
79 | 82 |
|
| 83 | + // number of 'leading zeroes'. |
| 84 | + inline int leading_zeroes(uint32_t input_num) { |
| 85 | +#if ADA_REGULAR_VISUAL_STUDIO |
| 86 | + unsigned long leading_zero(0); |
| 87 | + unsigned long in(input_num); |
| 88 | + return _BitScanReverse(&leading_zero, in) ? int(31 - leading_zero) : 32; |
| 89 | +#else |
| 90 | + return __builtin_clz(input_num); |
| 91 | +#endif// ADA_REGULAR_VISUAL_STUDIO |
| 92 | + } |
| 93 | + |
| 94 | + // integer logarithm of x (ceil(log2(x))) |
| 95 | + inline int int_log2(uint32_t x) { |
| 96 | + return 31 - leading_zeroes(x | 1); |
| 97 | + } |
| 98 | + |
| 99 | + // faster than std::to_string(x).size(). |
| 100 | + inline int fast_digit_count(uint32_t x) { |
| 101 | + // Compiles to very few instructions. Note that the |
| 102 | + // table is static and thus effectively a constant. |
| 103 | + // We leave it inside the function because it is meaningless |
| 104 | + // outside of it (this comes at no performance cost). |
| 105 | + const static uint64_t table[] = { |
| 106 | + 4294967296, 8589934582, 8589934582, 8589934582, 12884901788, |
| 107 | + 12884901788, 12884901788, 17179868184, 17179868184, 17179868184, |
| 108 | + 21474826480, 21474826480, 21474826480, 21474826480, 25769703776, |
| 109 | + 25769703776, 25769703776, 30063771072, 30063771072, 30063771072, |
| 110 | + 34349738368, 34349738368, 34349738368, 34349738368, 38554705664, |
| 111 | + 38554705664, 38554705664, 41949672960, 41949672960, 41949672960, |
| 112 | + 42949672960, 42949672960}; |
| 113 | + return (x + table[int_log2(x)]) >> 32; |
| 114 | + } |
| 115 | + |
80 | 116 | [[nodiscard]] ada_really_inline ada::url_components url::get_components() noexcept {
|
81 | 117 | url_components out{};
|
82 | 118 |
|
@@ -104,7 +140,7 @@ namespace ada {
|
104 | 140 |
|
105 | 141 | if (port.has_value()) {
|
106 | 142 | out.port = out.host_end;
|
107 |
| - out.pathname_start += std::to_string(port.value()).size(); |
| 143 | + out.pathname_start += fast_digit_count(port.value()); |
108 | 144 | }
|
109 | 145 |
|
110 | 146 | if (query.has_value()) {
|
|
0 commit comments