123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- // Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
- // For more information, see LICENCE in the main folder
- #include "utilities.hpp"
- #include <algorithm>
- #include <chrono>
- #include <iostream>
- #include <numeric> //iota
- #include <string>
- struct cScopeTimer::sPimpl {
- std::chrono::steady_clock::time_point start;
- std::chrono::steady_clock::time_point end;
-
- sPimpl()
- {
- start = std::chrono::steady_clock::now();
- }
-
- ~sPimpl(){
- end = std::chrono::steady_clock::now();
- std::chrono::microseconds diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
- std::cout << " took=" << diff.count() << "ms !\n";
- }
- };
- cScopeTimer::cScopeTimer()
- : aPimpl(new sPimpl())
- {}
- /**
- * Calculates the Levenshtein distance of two strings.
- * @author http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C.2B.2B
- * comparison test was done here http://cpp.sh/2o7w
- */
- int levenshtein(const std::string &s1, const std::string &s2)
- {
- // To change the type this function manipulates and returns, change
- // the return type and the types of the two variables below.
- int s1len = static_cast<int>(s1.size());
- int s2len = static_cast<int>(s2.size());
-
- auto column_start = (decltype(s1len))1;
-
- auto column = new decltype(s1len)[s1len + 1];
- std::iota(column + column_start, column + s1len + 1, column_start);
-
- for (auto x = column_start; x <= s2len; x++) {
- column[0] = x;
- auto last_diagonal = x - column_start;
- for (auto y = column_start; y <= s1len; y++) {
- auto old_diagonal = column[y];
- auto possibilities = {
- column[y] + 1,
- column[y - 1] + 1,
- last_diagonal + (s1[y - 1] == s2[x - 1]? 0 : 1)
- };
- column[y] = std::min(possibilities);
- last_diagonal = old_diagonal;
- }
- }
- auto result = column[s1len];
- delete[] column;
- return result;
- }
- bool rathena::util::safe_addition( int64 a, int64 b, int64& result ){
- #if defined(__GNUC__) || defined(__clang__)
- return __builtin_add_overflow( a, b, &result );
- #else
- bool overflow = false;
- if( b < 0 ){
- if( a < ( INT64_MIN - b ) ){
- overflow = true;
- }
- }else{
- if( a > ( INT64_MAX - b ) ){
- overflow = true;
- }
- }
- result = a + b;
- return overflow;
- #endif
- }
- bool rathena::util::safe_substraction( int64 a, int64 b, int64& result ){
- #if defined(__GNUC__) || defined(__clang__)
- return __builtin_sub_overflow( a, b, &result );
- #else
- bool overflow = false;
- if( b < 0 ){
- if( a > ( INT64_MAX + b ) ){
- overflow = true;
- }
- }else{
- if( a < ( INT64_MIN + b ) ){
- overflow = true;
- }
- }
- result = a - b;
- return overflow;
- #endif
- }
- bool rathena::util::safe_multiplication( int64 a, int64 b, int64& result ){
- #if defined(__GNUC__) || defined(__clang__)
- return __builtin_mul_overflow( a, b, &result );
- #else
- result = a * b;
- if( a > 0 ){
- if( b > 0 ){
- return result < 0;
- }else if( b < 0 ){
- return result > 0;
- }
- }else if( a < 0 ){
- if( b > 0 ){
- return result > 0;
- }else if( b < 0 ){
- return result < 0;
- }
- }
- return false;
- #endif
- }
|