]> sigrok.org Git - libsigrok.git/commitdiff
C++: Provide fallbacks for missing stoi/stod functions
authorMarcus Comstedt <redacted>
Sun, 31 Aug 2014 08:56:00 +0000 (10:56 +0200)
committerBert Vermeulen <redacted>
Sun, 31 Aug 2014 11:31:35 +0000 (13:31 +0200)
Notably, Android does not provide these functions.  The fallback
implementation is based on the one in the GNU ISO C++ Library.

bindings/cxx/ConfigKey_methods.cpp
configure.ac

index 98b4e45b5e99e6531484bb96edfb7f16563cd9c2..ceeea02588e9fdbf4ef8bb394748a630d25404a9 100644 (file)
@@ -30,6 +30,46 @@ const ConfigKey *ConfigKey::get(string identifier)
        return get(info->key);
 }
 
+#include "config.h"
+
+#ifndef HAVE_STOI_STOD
+
+/* Fallback implementation of stoi and stod */
+
+#include <cstdlib>
+#include <cerrno>
+#include <stdexcept>
+#include <limits>
+
+static inline int stoi( const std::string& str )
+{
+       char *endptr;
+       errno = 0;
+       const long ret = std::strtol(str.c_str(), &endptr, 10);
+       if (endptr == str.c_str())
+               throw std::invalid_argument("stoi");
+       else if (errno == ERANGE ||
+                ret < std::numeric_limits<int>::min() ||
+                ret > std::numeric_limits<int>::max())
+               throw std::out_of_range("stoi");
+       else
+               return ret;
+}
+
+static inline double stod( const std::string& str )
+{
+       char *endptr;
+       errno = 0;
+       const double ret = std::strtod(str.c_str(), &endptr);
+       if (endptr == str.c_str())
+               throw std::invalid_argument("stod");
+       else if (errno == ERANGE)
+               throw std::out_of_range("stod");
+       else
+               return ret;
+}
+#endif
+
 Glib::VariantBase ConfigKey::parse_string(string value) const
 {
        GVariant *variant;
index a60450cd1cc2c599d4e6389364bdd3ff3534f1da..798128efe6ae176551136a882ebe27d1de5635c7 100644 (file)
@@ -386,6 +386,19 @@ PKG_CHECK_MODULES([glibmm], [glibmm-2.4 >= 2.32.0],
        CXXLIBS="$CXXLIBS $glibmm_LIBS"],
        [BINDINGS_CXX="no"; cxx_msg="glibmm required"])
 
+# C++ bindings want stoi and stod
+if test "x$BINDINGS_CXX" == "xyes"; then
+       AC_LANG_PUSH([C++])
+       AC_MSG_CHECKING([for stoi and stod])
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <string>],
+                                          [{ return std::stoi("1")+std::stod("1.0"); }])],
+              [AC_MSG_RESULT([yes]);
+               AC_DEFINE_UNQUOTED(HAVE_STOI_STOD, [1],
+               [Specifies whether we have the stoi and stod functions.])],
+              [AC_MSG_RESULT([no])])
+       AC_LANG_POP([C++])
+fi
+
 # PyGObject is needed for the Python bindings.
 PKG_CHECK_MODULES([pygobject], [pygobject-3.0 >= 3.0.0],
         [CXXFLAGS="$CXXFLAGS $pygobject_CFLAGS";