AK: Move bijective-base-conversion into AK/String

This allows everybody to create a String version of their number
in a arbitrary bijective base. Bijective base meaning that the mapping
doesn't have a 0. In the usual mapping to the alphabet the follower
after 'Z' is 'AA'.
The mapping using the (uppercase) alphabet is used as a standard but
can be overridden specifying 'base' and 'map'.

The code was directly yanked from the Spreadsheet.
This commit is contained in:
Tobias Christiansen 2021-04-30 23:31:53 +02:00 committed by Linus Groh
parent 4dbf40399b
commit 4016e04061
Notes: sideshowbarker 2024-07-18 18:50:58 +09:00
2 changed files with 29 additions and 0 deletions

View file

@ -244,6 +244,33 @@ String String::repeated(char ch, size_t count)
return *impl;
}
String String::bijective_base_from(size_t value, unsigned base, StringView map)
{
if (map.is_null())
map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"sv;
VERIFY(base >= 2 && base <= map.length());
// The '8 bits per byte' assumption may need to go?
Array<char, round_up_to_power_of_two(sizeof(size_t) * 8 + 1, 2)> buffer;
size_t i = 0;
do {
buffer[i++] = map[value % base];
value /= base;
} while (value > 0);
// NOTE: Weird as this may seem, the thing that comes after 'Z' is 'AA', which as a number would be '00'
// to make this work, only the most significant digit has to be in a range of (1..25) as opposed to (0..25),
// but only if it's not the only digit in the string.
if (i > 1)
--buffer[i - 1];
for (size_t j = 0; j < i / 2; ++j)
swap(buffer[j], buffer[i - j - 1]);
return String { ReadonlyBytes(buffer.data(), i) };
}
bool String::matches(const StringView& mask, Vector<MaskSpan>& mask_spans, CaseSensitivity case_sensitivity) const
{
return StringUtils::matches(*this, mask, case_sensitivity, &mask_spans);

View file

@ -93,6 +93,8 @@ public:
[[nodiscard]] static String repeated(char, size_t count);
[[nodiscard]] static String bijective_base_from(size_t value, unsigned base = 26, StringView map = {});
template<class SeparatorType, class CollectionType>
[[nodiscard]] static String join(const SeparatorType& separator, const CollectionType& collection)
{