Bläddra i källkod

Add a few missing integral types

Sam Jaffe 2 år sedan
förälder
incheckning
69be20dd35
1 ändrade filer med 25 tillägg och 15 borttagningar
  1. 25 15
      include/string_utils/cast.h

+ 25 - 15
include/string_utils/cast.h

@@ -45,12 +45,23 @@ bool cast_number(std::string_view str, T & to, F func) noexcept {
   return counter == str.end();
 }
 
-std::vector<std::string_view> keyval(std::string_view input) {
+inline std::vector<std::string_view> keyval(std::string_view input) noexcept {
   if (size_t const pos = input.find('='); pos < input.size()) {
     return {input.substr(0, pos), input.substr(pos + 1)};
   }
   return {input};
 }
+
+inline bool cast_bool(bool & out, std::string_view str) noexcept {
+  if (any_of(str, "true", "TRUE", "YES", "1")) {
+    out = true;
+    return true;
+  } else if (any_of(str, "false", "FALSE", "NO", "0")) {
+    out = false;
+    return true;
+  }
+  return false;
+}
 }
 
 // This should be placed last in the file
@@ -59,32 +70,31 @@ namespace string_utils {
 template <typename Out> bool cast(Out & out, std::string_view str) noexcept {
   if constexpr (std::is_same_v<Out, long>) {
     return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtol, 10));
-  } else if constexpr (std::is_same_v<Out, long>) {
-    return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtol, 10));
+  } else if constexpr (std::is_same_v<Out, unsigned long>) {
+    return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtoul, 10));
   } else if constexpr (std::is_same_v<Out, long long>) {
     return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtoll, 10));
+  } else if constexpr (std::is_same_v<Out, unsigned long long>) {
+    return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtoull, 10));
   } else if constexpr (std::is_same_v<Out, float>) {
     return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtof));
   } else if constexpr (std::is_same_v<Out, double>) {
     return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtod));
   } else if constexpr (std::is_same_v<Out, long double>) {
     return detail::cast_number(str, out, SAFE_NUMBER_PARSE(std::strtold));
-  } else if constexpr (std::is_same_v<Out, int>) {
-    auto [tmp, success] = cast<long>(str);
-    out = static_cast<int>(tmp);
-    return success && tmp == static_cast<long>(out);
   } else if constexpr (std::is_same_v<Out, bool>) {
-    if (any_of(str, "true", "TRUE", "YES", "1")) {
-      out = true;
-      return true;
-    } else if (any_of(str, "false", "FALSE", "NO", "0")) {
-      out = false;
-      return true;
-    }
-    return false;
+    return detail::cast_bool(out, str);
+  } else if constexpr (std::is_same_v<Out, char>) {
+    out = str[0];
+    return str.size() == 1;
   } else if constexpr (std::is_constructible_v<Out, std::string_view>) {
     out = Out(str);
     return true;
+  } else if constexpr (std::is_integral_v<Out>) {
+    using V = std::conditional_t<std::is_unsigned_v<Out>, unsigned long, long>;
+    auto [tmp, success] = cast<V>(str);
+    out = static_cast<Out>(tmp);
+    return success && tmp == static_cast<V>(out);
   } else {
     static_assert(detail::always_false<Out>{}, "No match for cast(string)");
   }