Advertisement
ItsTotallyRSX

Safe ParseInt C++

Dec 31st, 2020
975
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.13 KB | None | 0 0
  1.  
  2.     template <typename T> int SignBit(T val) {
  3.         return (T(0) < val) - (val < T(0));
  4.     }
  5.  
  6.     template <typename T>
  7.     bool ParseInt(const AuString& in, T& out)
  8.     {
  9.         T res = 0;
  10.         T sign = 1;
  11.         out = 0;
  12.        
  13.         auto itr = in.begin();
  14.  
  15.         if constexpr (std::is_same<T, AuSInt>::value)
  16.         {
  17.             if (itr != in.end())
  18.             {
  19.                 if (*itr == '-')
  20.                 {
  21.                     itr++;
  22.                     sign = -1;
  23.                 }
  24.             }
  25.         }
  26.  
  27.         for (;
  28.              (itr != in.end()) &&
  29.              (*itr != '\0');
  30.              itr++)
  31.         {
  32.             auto c = *itr;
  33.  
  34.             if ((c < '0') || (c > '9')) return false;
  35.  
  36.             auto old = res;
  37.  
  38.             res *= 10;
  39.             res += static_cast<AuUInt>(*itr) - static_cast<AuUInt>('0');
  40.  
  41.             if constexpr (std::is_same<T, AuUInt>::value)
  42.             {
  43.                 if (old > res)
  44.                 {
  45.                     LogDbg("Unsigned integer overflow");
  46.                     return false;
  47.                 }
  48.             }
  49.             else if constexpr (std::is_same<T, AuSInt>::value)
  50.             {
  51.                 if (SignBit(old) != SignBit(res))
  52.                 {
  53.                     LogDbg("Signed integer overflow");
  54.                     return false;
  55.                 }
  56.             }
  57.         }
  58.  
  59.         out = res * sign;
  60.         return true;
  61.     }
  62.  
  63.     template <typename T>
  64.     bool ParseUInt(const AuString& in, T& out)
  65.     {
  66.         auto temp = AuUInt{};
  67.         out = 0;
  68.  
  69.         if (!ParseInt<AuUInt>(in, temp)) return false;
  70.  
  71.         if (temp > std::numeric_limits<T>::max()) return false;
  72.  
  73.         out = temp;
  74.         return true;
  75.     }
  76.  
  77.     template <typename T>
  78.     bool ParseSInt(const AuString& in, T& out)
  79.     {
  80.         auto temp = AuSInt{};
  81.         out = 0;
  82.  
  83.         if (!ParseInt<AuSInt>(in, temp)) return false;
  84.  
  85.         if (temp > std::numeric_limits<T>::max()) return false;
  86.         if (temp < std::numeric_limits<T>::min()) return false;
  87.        
  88.         out = temp;
  89.         return true;
  90.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement