forked from Alepha/Alepha
Integrate the number printing functionality.
This might make writing some kinds of tests which need lots of string data easier (convert large numbers to larger strings). Merges branch 'number-print' Conflicts: Utility/CMakeLists.txt
This commit is contained in:
@ -3,3 +3,4 @@ target_sources( alepha PRIVATE
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory( derived_pointer_cast.test )
|
add_subdirectory( derived_pointer_cast.test )
|
||||||
|
add_subdirectory( print_number.test )
|
||||||
|
|||||||
115
Utility/print_number.h
Normal file
115
Utility/print_number.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
static_assert( __cplusplus > 2020'99 );
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Alepha/Alepha.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::Utility ::detail:: print_number_m
|
||||||
|
{
|
||||||
|
inline namespace exports
|
||||||
|
{
|
||||||
|
std::string formatPrint( std::uint64_t );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string
|
||||||
|
exports::formatPrint( std::uint64_t value )
|
||||||
|
{
|
||||||
|
const std::map< int, std::string > names
|
||||||
|
{
|
||||||
|
{ 1, "one" },
|
||||||
|
{ 2, "two" },
|
||||||
|
{ 3, "three" },
|
||||||
|
{ 4, "four" },
|
||||||
|
{ 5, "five" },
|
||||||
|
{ 6, "six" },
|
||||||
|
{ 7, "seven" },
|
||||||
|
{ 8, "eight" },
|
||||||
|
{ 9, "nine" },
|
||||||
|
{ 10, "ten" },
|
||||||
|
{ 11, "eleven" },
|
||||||
|
{ 12, "twelve" },
|
||||||
|
{ 13, "thirteen" },
|
||||||
|
{ 14, "fourteen" },
|
||||||
|
{ 15, "fifteen" },
|
||||||
|
{ 16, "sixteen" },
|
||||||
|
{ 17, "seventeen" },
|
||||||
|
{ 18, "eighteen" },
|
||||||
|
{ 19, "nineteen" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map< int, std::string > tens
|
||||||
|
{
|
||||||
|
{ 20, "twenty" },
|
||||||
|
{ 30, "thirty" },
|
||||||
|
{ 40, "forty" },
|
||||||
|
{ 50, "fifty" },
|
||||||
|
{ 60, "sixty" },
|
||||||
|
{ 70, "seventy" },
|
||||||
|
{ 80, "eighty" },
|
||||||
|
{ 90, "ninety" },
|
||||||
|
};
|
||||||
|
|
||||||
|
// One Thousand to the N
|
||||||
|
const std::map< std::uint64_t, std::string > powers
|
||||||
|
{
|
||||||
|
{ 0, "" },
|
||||||
|
{ 1, "thousand" },
|
||||||
|
{ 2, "million" },
|
||||||
|
{ 3, "billion" },
|
||||||
|
{ 4, "trillion" },
|
||||||
|
{ 5, "quadrillion" },
|
||||||
|
{ 6, "quintillion" },
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector< std::string > parts;
|
||||||
|
|
||||||
|
if( value == 0 ) return "zero";
|
||||||
|
|
||||||
|
for( int millennium= 0; value; ++millennium )
|
||||||
|
{
|
||||||
|
auto remainder= value % 1000;
|
||||||
|
value/= 1000;
|
||||||
|
if( not remainder ) continue;
|
||||||
|
std::string next;
|
||||||
|
if( remainder >= 100 ) next+= names.at( remainder / 100 ) + " hundred ";
|
||||||
|
remainder%= 100;
|
||||||
|
if( remainder >= 20 )
|
||||||
|
{
|
||||||
|
next+= tens.at( remainder - remainder % 10 );
|
||||||
|
if( remainder % 10 ) next+= " " + names.at( remainder % 10 );
|
||||||
|
}
|
||||||
|
else if( remainder )
|
||||||
|
{
|
||||||
|
next+= names.at( remainder );
|
||||||
|
}
|
||||||
|
next+= " " + powers.at( millennium );
|
||||||
|
parts.push_back( std::move( next ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::reverse( begin( parts ), end( parts ) );
|
||||||
|
std::string rv;
|
||||||
|
bool first= true;
|
||||||
|
for( auto part: parts )
|
||||||
|
{
|
||||||
|
while( part.back() == ' ' ) part.pop_back();
|
||||||
|
while( part.front() == ' ' ) part= part.substr( 1 );
|
||||||
|
if( not first ) rv+= ' ';
|
||||||
|
rv+= part;
|
||||||
|
first= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::Utility::inline exports::inline print_number_m
|
||||||
|
{
|
||||||
|
using namespace detail::print_number_m::exports;
|
||||||
|
}
|
||||||
39
Utility/print_number.test/0.cc
Normal file
39
Utility/print_number.test/0.cc
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
static_assert( __cplusplus > 2020'99 );
|
||||||
|
|
||||||
|
#include "../print_number.h"
|
||||||
|
|
||||||
|
#include <Alepha/Testing/TableTest.h>
|
||||||
|
#include <Alepha/Testing/test.h>
|
||||||
|
|
||||||
|
#include <Alepha/Utility/evaluation_helpers.h>
|
||||||
|
|
||||||
|
static auto init= Alepha::Utility::enroll <=[]
|
||||||
|
{
|
||||||
|
using namespace Alepha::Testing::exports;
|
||||||
|
"Do simple numerical tests come out as we want?"_test
|
||||||
|
<=TableTest< Alepha::Utility::formatPrint >::Cases
|
||||||
|
{
|
||||||
|
{ "zero", { 0 }, "zero" },
|
||||||
|
{ "one", { 1 }, "one" },
|
||||||
|
{ "seven hundred", { 700 }, "seven hundred" },
|
||||||
|
{ "one thousand twenty four", { 1024 }, "one thousand twenty four" },
|
||||||
|
{ "ten thousand two hundred forty", { 10240 }, "ten thousand two hundred forty" },
|
||||||
|
{ "1283721", { 1'283'721 }, "one million two hundred eighty three thousand seven hundred twenty one" },
|
||||||
|
{ "1000283000721", { 1'000'283'000'721 },
|
||||||
|
"one trillion two hundred eighty three million seven hundred twenty one" },
|
||||||
|
|
||||||
|
{ "1000283000000", { 1'000'283'000'000 },
|
||||||
|
"one trillion two hundred eighty three million" },
|
||||||
|
};
|
||||||
|
|
||||||
|
-"repl"_test <=[]
|
||||||
|
{
|
||||||
|
while( std::cin )
|
||||||
|
{
|
||||||
|
std::uint64_t value;
|
||||||
|
std::cout << "input: " << std::flush;
|
||||||
|
std::cin >> value;
|
||||||
|
std::cout << Alepha::Utility::formatPrint( value ) << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
1
Utility/print_number.test/CMakeLists.txt
Normal file
1
Utility/print_number.test/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
unit_test( 0 )
|
||||||
Reference in New Issue
Block a user