about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-04-13T15·54+0200
committerEelco Dolstra <edolstra@gmail.com>2017-04-13T15·54+0200
commit6bd9576aeb55927cb551736a47b4e8e3fd1063bb (patch)
tree601949100e2e7db0032dc54397180614dd3cf965
parent0bf34de43b2fc4c9c3104b986eaea5c5cc856b83 (diff)
Support arbitrary numeric types for settings
-rw-r--r--src/libutil/config.cc21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 893cdccce344..c05a3253bce6 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -74,17 +74,25 @@ template<> std::string Setting<std::string>::to_string()
     return value;
 }
 
-template<> void Setting<int>::set(const std::string & str)
+template<typename T>
+void Setting<T>::set(const std::string & str)
 {
+    static_assert(std::is_integral<T>::value, "Integer required.");
     try {
-        value = std::stoi(str);
-    } catch (...) {
+        auto i = std::stoll(str);
+        if (i < std::numeric_limits<T>::min() ||
+            i > std::numeric_limits<T>::max())
+            throw UsageError("setting '%s' has out-of-range value %d", name, i);
+        value = i;
+    } catch (std::logic_error&) {
         throw UsageError("setting '%s' has invalid value '%s'", name, str);
     }
 }
 
-template<> std::string Setting<int>::to_string()
+template<typename T>
+std::string Setting<T>::to_string()
 {
+    static_assert(std::is_integral<T>::value, "Integer required.");
     return std::to_string(value);
 }
 
@@ -103,6 +111,11 @@ template<> std::string Setting<bool>::to_string()
     return value ? "true" : "false";
 }
 
+template class Setting<int>;
+template class Setting<unsigned int>;
+template class Setting<long>;
+template class Setting<size_t>;
+
 void PathSetting::set(const std::string & str)
 {
     if (str == "") {