utilities.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "utilities.hpp"
  4. #include <algorithm>
  5. #include <chrono>
  6. #include <iostream>
  7. #include <numeric> //iota
  8. #include <string>
  9. #ifndef __has_builtin
  10. #define __has_builtin(x) 0
  11. #endif
  12. struct cScopeTimer::sPimpl {
  13. std::chrono::steady_clock::time_point start;
  14. std::chrono::steady_clock::time_point end;
  15. sPimpl()
  16. {
  17. start = std::chrono::steady_clock::now();
  18. }
  19. ~sPimpl(){
  20. end = std::chrono::steady_clock::now();
  21. std::chrono::microseconds diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
  22. std::cout << " took=" << diff.count() << "ms !\n";
  23. }
  24. };
  25. cScopeTimer::cScopeTimer()
  26. : aPimpl(new sPimpl())
  27. {}
  28. /**
  29. * Calculates the Levenshtein distance of two strings.
  30. * @author http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.2B.2B
  31. * comparison test was done here http://cpp.sh/2o7w
  32. */
  33. int levenshtein(const std::string &s1, const std::string &s2)
  34. {
  35. // To change the type this function manipulates and returns, change
  36. // the return type and the types of the two variables below.
  37. int s1len = static_cast<int>(s1.size());
  38. int s2len = static_cast<int>(s2.size());
  39. auto column_start = (decltype(s1len))1;
  40. auto column = new decltype(s1len)[s1len + 1];
  41. std::iota(column + column_start, column + s1len + 1, column_start);
  42. for (auto x = column_start; x <= s2len; x++) {
  43. column[0] = x;
  44. auto last_diagonal = x - column_start;
  45. for (auto y = column_start; y <= s1len; y++) {
  46. auto old_diagonal = column[y];
  47. auto possibilities = {
  48. column[y] + 1,
  49. column[y - 1] + 1,
  50. last_diagonal + (s1[y - 1] == s2[x - 1]? 0 : 1)
  51. };
  52. column[y] = std::min(possibilities);
  53. last_diagonal = old_diagonal;
  54. }
  55. }
  56. auto result = column[s1len];
  57. delete[] column;
  58. return result;
  59. }
  60. bool rathena::util::safe_addition( int64 a, int64 b, int64& result ){
  61. #if __has_builtin( __builtin_add_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 )
  62. return __builtin_add_overflow( a, b, &result );
  63. #else
  64. bool overflow = false;
  65. if( b < 0 ){
  66. if( a < ( INT64_MIN - b ) ){
  67. overflow = true;
  68. }
  69. }else{
  70. if( a > ( INT64_MAX - b ) ){
  71. overflow = true;
  72. }
  73. }
  74. result = a + b;
  75. return overflow;
  76. #endif
  77. }
  78. bool rathena::util::safe_substraction( int64 a, int64 b, int64& result ){
  79. #if __has_builtin( __builtin_sub_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 )
  80. return __builtin_sub_overflow( a, b, &result );
  81. #else
  82. bool overflow = false;
  83. if( b < 0 ){
  84. if( a > ( INT64_MAX + b ) ){
  85. overflow = true;
  86. }
  87. }else{
  88. if( a < ( INT64_MIN + b ) ){
  89. overflow = true;
  90. }
  91. }
  92. result = a - b;
  93. return overflow;
  94. #endif
  95. }
  96. bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){
  97. #if __has_builtin( __builtin_mul_overflow ) || ( defined( __GNUC__ ) && !defined( __clang__ ) && defined( GCC_VERSION ) && GCC_VERSION >= 50100 )
  98. return __builtin_mul_overflow( a, b, &result );
  99. #else
  100. result = a * b;
  101. if( a > 0 ){
  102. if( b > 0 ){
  103. return result < 0;
  104. }else if( b < 0 ){
  105. return result > 0;
  106. }
  107. }else if( a < 0 ){
  108. if( b > 0 ){
  109. return result > 0;
  110. }else if( b < 0 ){
  111. return result < 0;
  112. }
  113. }
  114. return false;
  115. #endif
  116. }