toolbox.cpp : thousand_sep now supports negative integers && added doxygen
This commit is contained in:
		
							
								
								
									
										200
									
								
								toolbox.cpp
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								toolbox.cpp
									
									
									
									
									
								
							@@ -131,94 +131,144 @@ namespace asp {
 | 
			
		||||
		return ss;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct separate_thousands : std::numpunct<char> {
 | 
			
		||||
		char sep_;
 | 
			
		||||
		separate_thousands(const char sep) noexcept : sep_(sep) {}
 | 
			
		||||
		char_type do_thousands_sep() const override { return sep_; }  // separate with commas
 | 
			
		||||
		string_type do_grouping() const override { return "\3"; } // groups of 3 digit
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Format a given integer with a given seperator for each thousands.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param k Integer
 | 
			
		||||
	 * @param sep Thousand seperator
 | 
			
		||||
	 * @return Formatted integer
 | 
			
		||||
	 */
 | 
			
		||||
	std::string thousand_sep(const int64_t k, const char sep) noexcept {
 | 
			
		||||
		std::ostringstream out;
 | 
			
		||||
		out.imbue(std::locale(out.getloc(), new separate_thousands(sep)));
 | 
			
		||||
		out << k;
 | 
			
		||||
		return out.str();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Format a given integer with ',' for each thousands.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param k Integer
 | 
			
		||||
	 * @return Formatted integer
 | 
			
		||||
	 */
 | 
			
		||||
	std::string thousand_sep(const int64_t k) noexcept {
 | 
			
		||||
		return thousand_sep(k, ',');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Run some unitary tests on format functions
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
	void toolbox_unit_test(void) noexcept {
 | 
			
		||||
		assert(std::string("0B")                                            == format_byte_size(u64(0)));
 | 
			
		||||
		assert(std::string("1B")                                            == format_byte_size(u64(1)));
 | 
			
		||||
		assert(std::string("1KB")                                           == format_byte_size(u64(1) << 10));
 | 
			
		||||
		assert(std::string("1MB")                                           == format_byte_size(u64(1) << 20));
 | 
			
		||||
		assert(std::string("1GB")                                           == format_byte_size(u64(1) << 30));
 | 
			
		||||
		assert(std::string("0B")                                            == format_byte_size(0));
 | 
			
		||||
		assert(std::string("1B")                                            == format_byte_size(1));
 | 
			
		||||
		assert(std::string("1KB")                                           == format_byte_size(1 << 10));
 | 
			
		||||
		assert(std::string("1MB")                                           == format_byte_size(1 << 20));
 | 
			
		||||
		assert(std::string("1GB")                                           == format_byte_size(1 << 30));
 | 
			
		||||
		assert(std::string("1TB")                                           == format_byte_size(u64(1) << 40));
 | 
			
		||||
		assert(std::string("1PB")                                           == format_byte_size(u64(1) << 50));
 | 
			
		||||
		assert(std::string("1EB")                                           == format_byte_size(u64(1) << 60));
 | 
			
		||||
		// uint64_t_MAX == 2**64 == 18446744073709551615 == -1
 | 
			
		||||
		assert(std::string("15EB 1023PB 1023TB 1023GB 1023MB 1023KB 1023B") == format_byte_size(u64(-1)));
 | 
			
		||||
		assert(std::string("15EB 1023PB 1023TB 1023GB 1023MB 1023KB 1023B") == format_byte_size(std::numeric_limits<uint64_t>::max()));
 | 
			
		||||
		assert(std::string("15EB 1023PB 1023TB 1023GB 1023MB 1023KB 1023B") == format_byte_size(18446744073709551615ull));
 | 
			
		||||
		assert(std::string("10EB 1000PB 1000TB 1000GB 1000MB 1000KB 1000B") == format_byte_size(12656215539330294760ull));
 | 
			
		||||
 | 
			
		||||
		// https://en.wikipedia.org/wiki/Unit_of_time
 | 
			
		||||
		assert(std::string("0ns")                                            == format_time_ns(u64(0)));
 | 
			
		||||
		assert(std::string("1ns")                                            == format_time_ns(u64(1)));
 | 
			
		||||
		assert(std::string("10ns")                                           == format_time_ns(u64(10)));
 | 
			
		||||
		assert(std::string("1us")                                            == format_time_ns(u64(1e3)));
 | 
			
		||||
		assert(std::string("1ms")                                            == format_time_ns(u64(1e6)));
 | 
			
		||||
		assert(std::string("10ms")                                           == format_time_ns(u64(1e7)));
 | 
			
		||||
		assert(std::string("100ms")                                          == format_time_ns(u64(1e8)));
 | 
			
		||||
		assert(std::string("1s")                                             == format_time_ns(u64(1e9)));
 | 
			
		||||
		assert(std::string("10s")                                            == format_time_ns(u64(1e10)));
 | 
			
		||||
		assert(std::string("1m")                                             == format_time_ns(u64(6e10)));
 | 
			
		||||
		assert(std::string("1m 26s 400ms")                                   == format_time_ns(u64(864e8)));
 | 
			
		||||
		assert(std::string("1m 40s")                                         == format_time_ns(u64(1e11)));
 | 
			
		||||
		assert(std::string("16m 40s")                                        == format_time_ns(u64(1e12)));
 | 
			
		||||
		assert(std::string("1h")                                             == format_time_ns(u64(36e11)));
 | 
			
		||||
		assert(std::string("1j")                                             == format_time_ns(u64(864e11)));
 | 
			
		||||
		assert(std::string("1w")                                             == format_time_ns(u64(6048e11)));
 | 
			
		||||
		assert(std::string("1w 4j 13h 46m 40s")                              == format_time_ns(u64(1e15)));
 | 
			
		||||
		assert(std::string("2w")                                             == format_time_ns(u64(12096e11)));
 | 
			
		||||
		assert(std::string("3w 6j 5h 5m 35s 800ms")                          == format_time_ns(u64(23511358e8)));
 | 
			
		||||
		assert(std::string("3w 6j 7h 43m 4s 700ms")                          == format_time_ns(u64(23605847e8)));
 | 
			
		||||
		assert(std::string("3w 6j 7h 43m 11s 600ms")                         == format_time_ns(u64(23605916e8)));
 | 
			
		||||
		assert(std::string("3w 6j 13h 18m 33s 200ms")                        == format_time_ns(u64(23807132e8)));
 | 
			
		||||
		assert(std::string("4w 1j 12h 44m 2s 900ms")                         == format_time_ns(u64(25514429e8)));
 | 
			
		||||
		assert(std::string("1M")                                             == format_time_ns(u64(26298e11)));
 | 
			
		||||
		assert(std::string("1M 1w 2j 13h 30m")                               == format_time_ns(u64(3456e12)));
 | 
			
		||||
		assert(std::string("4M 4j 6h")                                       == format_time_ns(u64(108864e11)));
 | 
			
		||||
		assert(std::string("11M 2w 5j 13h 22m 48s")                          == format_time_ns(u64(30617568e9)));
 | 
			
		||||
		assert(std::string("11M 4w 2j 4h 30m")                               == format_time_ns(u64(31536e12)));
 | 
			
		||||
		assert(std::string("1y")                                             == format_time_ns(u64(315576e11)));
 | 
			
		||||
		assert(std::string("11M 4w 2j 10h 18m 45s")                          == format_time_ns(u64(31556925e9)));
 | 
			
		||||
		assert(std::string("11M 4w 2j 10h 19m 12s")                          == format_time_ns(u64(31556952e9)));
 | 
			
		||||
		assert(std::string("1y 9m 9s")                                       == format_time_ns(u64(31558149e9)));
 | 
			
		||||
		assert(std::string("1y 18h")                                         == format_time_ns(u64(316224e11)));
 | 
			
		||||
		assert(std::string("4y")                                             == format_time_ns(u64(1262304e11)));
 | 
			
		||||
		assert(std::string("5y")                                             == format_time_ns(u64(157788e12)));
 | 
			
		||||
		assert(std::string("10y")                                            == format_time_ns(u64(315576e12)));
 | 
			
		||||
		assert(std::string("15y")                                            == format_time_ns(u64(473364e12)));
 | 
			
		||||
		assert(std::string("20y")                                            == format_time_ns(u64(631152e12)));
 | 
			
		||||
		assert(std::string("31y 8M 1w 19h 46m 40s")                          == format_time_ns(u64(1e18)));
 | 
			
		||||
		assert(std::string("50y")                                            == format_time_ns(u64(157788e13)));
 | 
			
		||||
		assert(std::string("1c")                                             == format_time_ns(u64(315576e13)));
 | 
			
		||||
		// uint64_t_MAX == 2**64 == 18446744073709551615 == -1
 | 
			
		||||
		assert(std::string("5c 84y 6M 2w 1j 8h 34m 33s 709ms 551us 615ns")   == format_time_ns(u64(-1)));
 | 
			
		||||
		assert(std::string("0ns")                                            == format_time_ns(0));
 | 
			
		||||
		assert(std::string("1ns")                                            == format_time_ns(1));
 | 
			
		||||
		assert(std::string("10ns")                                           == format_time_ns(10));
 | 
			
		||||
		assert(std::string("1us")                                            == format_time_ns(1e3));
 | 
			
		||||
		assert(std::string("1ms")                                            == format_time_ns(1e6));
 | 
			
		||||
		assert(std::string("10ms")                                           == format_time_ns(1e7));
 | 
			
		||||
		assert(std::string("100ms")                                          == format_time_ns(1e8));
 | 
			
		||||
		assert(std::string("1s")                                             == format_time_ns(1e9));
 | 
			
		||||
		assert(std::string("10s")                                            == format_time_ns(1e10));
 | 
			
		||||
		assert(std::string("1m")                                             == format_time_ns(6e10));
 | 
			
		||||
		assert(std::string("1m 26s 400ms")                                   == format_time_ns(864e8));
 | 
			
		||||
		assert(std::string("1m 40s")                                         == format_time_ns(1e11));
 | 
			
		||||
		assert(std::string("16m 40s")                                        == format_time_ns(1e12));
 | 
			
		||||
		assert(std::string("1h")                                             == format_time_ns(36e11));
 | 
			
		||||
		assert(std::string("1j")                                             == format_time_ns(864e11));
 | 
			
		||||
		assert(std::string("1w")                                             == format_time_ns(6048e11));
 | 
			
		||||
		assert(std::string("1w 4j 13h 46m 40s")                              == format_time_ns(1e15));
 | 
			
		||||
		assert(std::string("2w")                                             == format_time_ns(12096e11));
 | 
			
		||||
		assert(std::string("3w 6j 5h 5m 35s 800ms")                          == format_time_ns(23511358e8));
 | 
			
		||||
		assert(std::string("3w 6j 7h 43m 4s 700ms")                          == format_time_ns(23605847e8));
 | 
			
		||||
		assert(std::string("3w 6j 7h 43m 11s 600ms")                         == format_time_ns(23605916e8));
 | 
			
		||||
		assert(std::string("3w 6j 13h 18m 33s 200ms")                        == format_time_ns(23807132e8));
 | 
			
		||||
		assert(std::string("4w 1j 12h 44m 2s 900ms")                         == format_time_ns(25514429e8));
 | 
			
		||||
		assert(std::string("1M")                                             == format_time_ns(26298e11));
 | 
			
		||||
		assert(std::string("1M 1w 2j 13h 30m")                               == format_time_ns(3456e12));
 | 
			
		||||
		assert(std::string("4M 4j 6h")                                       == format_time_ns(108864e11));
 | 
			
		||||
		assert(std::string("11M 2w 5j 13h 22m 48s")                          == format_time_ns(30617568e9));
 | 
			
		||||
		assert(std::string("11M 4w 2j 4h 30m")                               == format_time_ns(31536e12));
 | 
			
		||||
		assert(std::string("1y")                                             == format_time_ns(315576e11));
 | 
			
		||||
		assert(std::string("11M 4w 2j 10h 18m 45s")                          == format_time_ns(31556925e9));
 | 
			
		||||
		assert(std::string("11M 4w 2j 10h 19m 12s")                          == format_time_ns(31556952e9));
 | 
			
		||||
		assert(std::string("1y 9m 9s")                                       == format_time_ns(31558149e9));
 | 
			
		||||
		assert(std::string("1y 18h")                                         == format_time_ns(316224e11));
 | 
			
		||||
		assert(std::string("4y")                                             == format_time_ns(1262304e11));
 | 
			
		||||
		assert(std::string("5y")                                             == format_time_ns(157788e12));
 | 
			
		||||
		assert(std::string("10y")                                            == format_time_ns(315576e12));
 | 
			
		||||
		assert(std::string("15y")                                            == format_time_ns(473364e12));
 | 
			
		||||
		assert(std::string("20y")                                            == format_time_ns(631152e12));
 | 
			
		||||
		assert(std::string("31y 8M 1w 19h 46m 40s")                          == format_time_ns(1e18));
 | 
			
		||||
		assert(std::string("50y")                                            == format_time_ns(157788e13));
 | 
			
		||||
		assert(std::string("1c")                                             == format_time_ns(315576e13));
 | 
			
		||||
		assert(std::string("5c 84y 6M 2w 1j 8h 34m 33s 709ms 551us 615ns")   == format_time_ns(std::numeric_limits<uint64_t>::max()));
 | 
			
		||||
		assert(std::string("5c 84y 6M 2w 1j 8h 34m 33s 709ms 551us 615ns")   == format_time_ns(18446744073709551615ull));
 | 
			
		||||
		assert(std::string("1c 10y 10M 3w 6j 10h 10m 10s 100ms 100us 100ns") == format_time_ns(3500003410100100100ull));
 | 
			
		||||
	}
 | 
			
		||||
		assert(std::string("1c 10y 10M 3w 6j 10h 10m 10s 100ms 100us 100ns") == format_time_ns(3500003410100100100));
 | 
			
		||||
 | 
			
		||||
	std::string thousand_sep(const uint64_t& k, const char& sep) noexcept {
 | 
			
		||||
		std::string s = "", n = std::to_string(k);
 | 
			
		||||
		assert(std::string("0")                          == thousand_sep(0));
 | 
			
		||||
		assert(std::string("1")                          == thousand_sep(1));
 | 
			
		||||
		assert(std::string("10")                         == thousand_sep(10));
 | 
			
		||||
		assert(std::string("100")                        == thousand_sep(100));
 | 
			
		||||
		assert(std::string("1,000")                      == thousand_sep(1e3));
 | 
			
		||||
		assert(std::string("10,000")                     == thousand_sep(1e4));
 | 
			
		||||
		assert(std::string("100,000")                    == thousand_sep(1e5));
 | 
			
		||||
		assert(std::string("1,000,000")                  == thousand_sep(1e6));
 | 
			
		||||
		assert(std::string("10,000,000")                 == thousand_sep(1e7));
 | 
			
		||||
		assert(std::string("100,000,000")                == thousand_sep(1e8));
 | 
			
		||||
		assert(std::string("1,000,000,000")              == thousand_sep(1e9));
 | 
			
		||||
		assert(std::string("10,000,000,000")             == thousand_sep(1e10));
 | 
			
		||||
		assert(std::string("100,000,000,000")            == thousand_sep(1e11));
 | 
			
		||||
		assert(std::string("1,000,000,000,000")          == thousand_sep(1e12));
 | 
			
		||||
		assert(std::string("10,000,000,000,000")         == thousand_sep(1e13));
 | 
			
		||||
		assert(std::string("100,000,000,000,000")        == thousand_sep(1e14));
 | 
			
		||||
		assert(std::string("1,000,000,000,000,000")      == thousand_sep(1e15));
 | 
			
		||||
		assert(std::string("10,000,000,000,000,000")     == thousand_sep(1e16));
 | 
			
		||||
		assert(std::string("100,000,000,000,000,000")    == thousand_sep(1e17));
 | 
			
		||||
		assert(std::string("1,000,000,000,000,000,000")  == thousand_sep(1e18));
 | 
			
		||||
		assert(std::string("1,234,567,890")              == thousand_sep(1234567890));
 | 
			
		||||
		assert(std::string("9,876,543,210")              == thousand_sep(9876543210));
 | 
			
		||||
		assert(std::string("9,223,372,036,854,775,807")  == thousand_sep(std::numeric_limits<int64_t>::max()));
 | 
			
		||||
 | 
			
		||||
		uint8_t c = 0;
 | 
			
		||||
		for (int64_t i = int64_t(n.size()) - 1; i >= 0; --i) {
 | 
			
		||||
			++c;
 | 
			
		||||
			s.push_back(n[i]);
 | 
			
		||||
			if (c == 3) {
 | 
			
		||||
				s.push_back(sep);
 | 
			
		||||
				c = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		std::reverse(s.begin(), s.end());
 | 
			
		||||
 | 
			
		||||
		if (s.size() % 4 == 0)
 | 
			
		||||
			s.erase(s.begin());
 | 
			
		||||
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::string thousand_sep(const uint64_t& k) noexcept {
 | 
			
		||||
		return thousand_sep(k, ',');
 | 
			
		||||
		assert(std::string("-1")                         == thousand_sep(-1));
 | 
			
		||||
		assert(std::string("-10")                        == thousand_sep(-10));
 | 
			
		||||
		assert(std::string("-100")                       == thousand_sep(-100));
 | 
			
		||||
		assert(std::string("-1,000")                     == thousand_sep(-1e3));
 | 
			
		||||
		assert(std::string("-10,000")                    == thousand_sep(-1e4));
 | 
			
		||||
		assert(std::string("-100,000")                   == thousand_sep(-1e5));
 | 
			
		||||
		assert(std::string("-1,000,000")                 == thousand_sep(-1e6));
 | 
			
		||||
		assert(std::string("-10,000,000")                == thousand_sep(-1e7));
 | 
			
		||||
		assert(std::string("-100,000,000")               == thousand_sep(-1e8));
 | 
			
		||||
		assert(std::string("-1,000,000,000")             == thousand_sep(-1e9));
 | 
			
		||||
		assert(std::string("-10,000,000,000")            == thousand_sep(-1e10));
 | 
			
		||||
		assert(std::string("-100,000,000,000")           == thousand_sep(-1e11));
 | 
			
		||||
		assert(std::string("-1,000,000,000,000")         == thousand_sep(-1e12));
 | 
			
		||||
		assert(std::string("-10,000,000,000,000")        == thousand_sep(-1e13));
 | 
			
		||||
		assert(std::string("-100,000,000,000,000")       == thousand_sep(-1e14));
 | 
			
		||||
		assert(std::string("-1,000,000,000,000,000")     == thousand_sep(-1e15));
 | 
			
		||||
		assert(std::string("-10,000,000,000,000,000")    == thousand_sep(-1e16));
 | 
			
		||||
		assert(std::string("-100,000,000,000,000,000")   == thousand_sep(-1e17));
 | 
			
		||||
		assert(std::string("-1,000,000,000,000,000,000") == thousand_sep(-1e18));
 | 
			
		||||
		assert(std::string("-1,234,567,890")             == thousand_sep(-1234567890));
 | 
			
		||||
		assert(std::string("-9,876,543,210")             == thousand_sep(-9876543210));
 | 
			
		||||
		assert(std::string("-9,223,372,036,854,775,808") == thousand_sep(std::numeric_limits<int64_t>::min()));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user