encode/number: add base36 encode

This commit is contained in:
Danny Robson 2018-12-16 16:47:08 +11:00
parent 49b8594a73
commit 1bb566fcda
2 changed files with 46 additions and 0 deletions

View File

@ -9,6 +9,11 @@
#pragma once
#include "../view.hpp"
#include "../maths.hpp"
#include <array>
#include <limits>
///////////////////////////////////////////////////////////////////////////////
namespace cruft::encode {
@ -31,4 +36,31 @@ namespace cruft::encode {
return accum;
}
template <typename ValueT, typename OutputT>
OutputT
encode36 (OutputT out, ValueT val)
{
constexpr auto count = digits(std::numeric_limits<ValueT>::max (), 36u);
std::array<char, count> res;
auto cursor = res.begin ();
// Ensure we do at least one iteration so we output a zero.
do {
switch (auto const d = val % 36; d) {
case 0 ... 9: *cursor = d + '0'; break;
case 10 ...35: *cursor = d - 10 + 'a'; break;
}
val /= 36;
++cursor;
} while (val);
return std::copy (
std::make_reverse_iterator (cursor),
res.rend (),
out
);
}
}

View File

@ -20,8 +20,22 @@ int main ()
cruft::TAP::logger tap;
for (auto const &t: TESTS) {
// decode the truth string and test against the truth number
cruft::view src (t.str);
tap.expect_eq (cruft::encode::decode36<unsigned> (src), t.value, "base36 decode '%!'", t.str);
// encode the truth number
std::ostringstream dst;
cruft::encode::encode36<unsigned> (std::ostream_iterator<char> (dst), t.value);
// covert computed and truth strings to lower case
std::string encoded_computed = dst.str ();
std::string encoded_truth = t.str;
std::transform (encoded_computed.begin (), encoded_computed.end (), encoded_computed.begin (), ::tolower);
std::transform (encoded_truth.begin (), encoded_truth.end (), encoded_truth.begin (), ::tolower);
// compare lower case encoded strings
tap.expect_eq (encoded_computed, encoded_truth, "base36 encode '%!'", t.value);
}
return tap.status ();