Skip to content

Instantly share code, notes, and snippets.

@dakka
Last active August 24, 2024 20:53
Show Gist options
  • Save dakka/b93ff6ee9e7a8d42f35a9f79d612868d to your computer and use it in GitHub Desktop.
Save dakka/b93ff6ee9e7a8d42f35a9f79d612868d to your computer and use it in GitHub Desktop.
Create C++ source for an enum class with named numbers. 0 based.
#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <sstream>
#include <array>
#include <cstdlib>
constexpr std::array ones {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};
constexpr std::array teens {"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
constexpr std::array tens {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
std::string num2words(int number)
{
if (number == 0)
return ones[0];
std::ostringstream words;
if (number >= 1000000)
{
words << num2words(number / 1000000) << "_million";
if (number %= 1000000)
words << '_';
}
if (number >= 1000)
{
words << num2words(number / 1000) << "_thousand";
if (number %= 1000)
words << '_';
}
if (number >= 100)
{
words << ones[number / 100] << "_hundred";
if (number %= 100)
words << '_';
}
if (number >= 20)
{
words << tens[number / 10];
if (number %= 10)
words << '_';
}
if (number > 10 && number < 20)
words << teens[number - 11];
else if (number > 0)
words << ones[number];
return words.str();
}
int main(int argc, char *argv[])
{
const std::vector<std::string_view> args{argv, argv + argc};
if (args.size() < 3)
{
std::cerr << "Usage: " << args[0] << " <classname> <count> [<prefix>]\n";
return 1;
}
bool has_prefix { args.size() >= 4 };
int number{};
try
{
if ((number = std::stoi(args[2].data())) <= 0)
{
std::cerr << "<count=" << number << "> must be > 0\n";
return 1;
}
}
catch(const std::exception& e)
{
std::cerr << "exception: invalid count: " << e.what() << '(' << args[1] << ")\n";
return 1;
}
std::cout << "enum class " << args[1] << "\n{\n ";
for (int ii{}; ii < number; ++ii)
{
if (ii)
{
std::cout << ", ";
if (ii % 5 == 0)
std::cout << "\n ";
}
if (has_prefix)
std::cout << args[3] << '_' << ii;
else
std::cout << num2words(ii);
}
std::cout << "\n};\n";
return 0;
}
@dakka
Copy link
Author

dakka commented Aug 20, 2024

% ./numberwords-enum
Usage: ./numberwords-enum <classname> <count> [<prefix>]
% ./numberwords-enum "test : uint32_t" 100
enum class test : uint32_t
{
   zero, one, two, three, four,
   five, six, seven, eight, nine,
   ten, eleven, twelve, thirteen, fourteen,
   fifteen, sixteen, seventeen, eighteen, nineteen,
   twenty, twenty_one, twenty_two, twenty_three, twenty_four,
   twenty_five, twenty_six, twenty_seven, twenty_eight, twenty_nine,
   thirty, thirty_one, thirty_two, thirty_three, thirty_four,
   thirty_five, thirty_six, thirty_seven, thirty_eight, thirty_nine,
   forty, forty_one, forty_two, forty_three, forty_four,
   forty_five, forty_six, forty_seven, forty_eight, forty_nine,
   fifty, fifty_one, fifty_two, fifty_three, fifty_four,
   fifty_five, fifty_six, fifty_seven, fifty_eight, fifty_nine,
   sixty, sixty_one, sixty_two, sixty_three, sixty_four,
   sixty_five, sixty_six, sixty_seven, sixty_eight, sixty_nine,
   seventy, seventy_one, seventy_two, seventy_three, seventy_four,
   seventy_five, seventy_six, seventy_seven, seventy_eight, seventy_nine,
   eighty, eighty_one, eighty_two, eighty_three, eighty_four,
   eighty_five, eighty_six, eighty_seven, eighty_eight, eighty_nine,
   ninety, ninety_one, ninety_two, ninety_three, ninety_four,
   ninety_five, ninety_six, ninety_seven, ninety_eight, ninety_nine
};
% ./numberwords-enum test 20 blah
enum class test
{
   blah_0, blah_1, blah_2, blah_3, blah_4,
   blah_5, blah_6, blah_7, blah_8, blah_9,
   blah_10, blah_11, blah_12, blah_13, blah_14,
   blah_15, blah_16, blah_17, blah_18, blah_19
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment