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

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

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text