C++11のつもり。パブリックドメイン。無保証。

Format
C++
Post date
2019-11-08 11:41
Publication Period
Unlimited
  1. #include <cmath>
  2. #include <cstdlib>
  3. #include <iostream>
  4. #include <ratio>
  5. #include <chrono>
  6. template<class T>
  7. constexpr int constlog10(T v){
  8. return
  9. v <= 0 ?(
  10. std::abort(), 0
  11. ):(
  12. (v <= 1 && v*10 > 1) || (v >= 1 && v/10 < 1) ?(
  13. 0
  14. ):(
  15. v < 1 ?(
  16. constlog10(v * 10) - 1
  17. ):(
  18. constlog10(v / 10) + 1
  19. )
  20. )
  21. );
  22. }
  23. constexpr unsigned constpow10(unsigned v){
  24. return
  25. v == 0 ?
  26. 1
  27. :
  28. constpow10(v - 1) * 10;
  29. ;
  30. }
  31. template<class T, class S>
  32. void dump_duration(S&& target, const T& dur){
  33. constexpr int punit3
  34. = constlog10(T::period::num) - constlog10(T::period::den);
  35. using pr = std::ratio<
  36. T::period::num * constpow10(punit3<0 ? -punit3 : 0),
  37. T::period::den * constpow10(punit3>0 ? punit3 : 0)
  38. >;
  39. if(dur.count() == 0){
  40. target << "0s";
  41. return;
  42. }
  43. int unit3 = std::log10(dur.count());
  44. char prefix_small[] = "munp";
  45. char prefix_big[] = "kMGT";
  46. char prefix = 0;
  47. int uunit3 = unit3 + punit3;
  48. if(uunit3 < 0){
  49. int ud = -uunit3 % 3 - 3;
  50. unit3 += ud;
  51. uunit3 += ud;
  52. if(uunit3 < -12){
  53. unit3 += -uunit3 - 12;
  54. uunit3 = -12;
  55. }
  56. }else{
  57. int ud = uunit3 % 3;
  58. unit3 -= ud;
  59. uunit3 -= ud;
  60. if(uunit3 > 12){
  61. unit3 -= uunit3 - 12;
  62. uunit3 = 12;
  63. }
  64. }
  65. if(uunit3 < 0){
  66. prefix = prefix_small[-uunit3 / 3 - 1];
  67. }else if(uunit3 > 0){
  68. prefix = prefix_big[uunit3 / 3 - 1];
  69. }
  70. auto cnt = dur.count();
  71. if(unit3 < 0){
  72. cnt *= constpow10(-unit3);
  73. }else{
  74. cnt /= constpow10(unit3);
  75. }
  76. cnt *= pr::num;
  77. cnt /= pr::den;
  78. target << cnt;
  79. if(prefix){
  80. target << prefix;
  81. }
  82. target << "s";
  83. }
  84. template<class O, class T, class S>
  85. void dump_duration(S&& target, const T& dur){
  86. dump_duration(
  87. std::forward<S>(target),
  88. std::chrono::duration_cast<
  89. std::chrono::duration<O, typename T::period>
  90. >(dur)
  91. );
  92. }
  93. int main(){
  94. auto start = std::chrono::steady_clock::now();
  95. dump_duration(std::cout,
  96. std::chrono::duration<int, std::ratio<1, 1000>>(1));
  97. std::cout << '\n';
  98. dump_duration(std::cout,
  99. std::chrono::duration<int, std::ratio<1, 1>>(1));
  100. std::cout << '\n';
  101. dump_duration(std::cout,
  102. std::chrono::duration<int, std::ratio<1000, 1>>(1));
  103. std::cout << '\n';
  104. auto end = std::chrono::steady_clock::now();
  105. std::cout << "proc time: ";
  106. dump_duration<double>(std::cout, end - start);
  107. std::cout << '\n';
  108. return 0;
  109. }
다운로드 Printable view

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text