]> sigrok.org Git - libsigrok.git/blobdiff - bindings/cxx/ConfigKey_methods.cpp
bindings/cxx: implement std::stoul() fallback when C++11 is missing
[libsigrok.git] / bindings / cxx / ConfigKey_methods.cpp
index 7f8c201ed5a8f1e649b4f4e9a452b5c8344e1dd3..7381c922f3203e58a97e83d6d5a48bab3e4beae1 100644 (file)
@@ -70,6 +70,36 @@ static inline double stod( const std::string& str )
 }
 #endif
 
+#ifndef HAVE_STOUL
+
+/* Fallback implementation of stoul. */
+
+#include <cerrno>
+#include <cstdlib>
+#include <limits>
+#include <stdexcept>
+
+static inline unsigned long stoul(const std::string &str)
+{
+       char *endptr;
+       unsigned long ret;
+       errno = 0;
+       ret = std::strtoul(str.c_str(), &endptr, 10);
+       if (endptr == str.c_str())
+               throw std::invalid_argument("stoul");
+       /*
+        * TODO Convert to a larger/wider intermediate data type?
+        * Because after conversion into the very target type, the
+        * range check is assumed to be ineffective.
+        */
+       if (errno == ERANGE ||
+               ret < std::numeric_limits<unsigned long>::min() ||
+               ret > std::numeric_limits<unsigned long>::max())
+               throw std::out_of_range("stoul");
+       return ret;
+}
+#endif
+
 Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt)
 {
        GVariant *variant;