Commit f31c9945 authored by Dominik Charousset's avatar Dominik Charousset

Fix parsing of size_t config options

parent 3aad1fdf
...@@ -47,9 +47,9 @@ public: ...@@ -47,9 +47,9 @@ public:
using config_reader_sink = std::function<void (size_t, config_value&, using config_reader_sink = std::function<void (size_t, config_value&,
optional<std::ostream&>)>; optional<std::ostream&>)>;
using legal_types = detail::type_list<bool, float, double, std::string, using legal_types = detail::type_list<bool, float, double, std::string,
atom_value, int8_t, uint8_t, int16_t, atom_value, int8_t, uint8_t, int16_t,
uint16_t, int32_t, uint32_t, int64_t, uint16_t, int32_t, uint32_t, int64_t,
uint64_t>; uint64_t>;
config_option(const char* cat, const char* nm, const char* expl); config_option(const char* cat, const char* nm, const char* expl);
...@@ -89,7 +89,7 @@ public: ...@@ -89,7 +89,7 @@ public:
public: public:
template <class T> template <class T>
const char* operator()(const T&) const { const char* operator()(const T&) const {
static constexpr bool is_int = std::is_integral<T>::value static constexpr bool is_int = std::is_integral<T>::value
&& !std::is_same<bool, T>::value; && !std::is_same<bool, T>::value;
static constexpr std::integral_constant<bool, is_int> tk{}; static constexpr std::integral_constant<bool, is_int> tk{};
static constexpr int index = idx<T>(tk); static constexpr int index = idx<T>(tk);
...@@ -98,13 +98,15 @@ public: ...@@ -98,13 +98,15 @@ public:
} }
private: private:
// Catches non-integer types.
template <class T> template <class T>
static constexpr int idx(std::false_type /* is_integer */) { static constexpr int idx(std::false_type) {
return detail::tl_index_of<legal_types, T>::value; return detail::tl_index_of<legal_types, T>::value;
} }
// Catches integer types.
template <class T> template <class T>
static constexpr int idx(std::true_type /* is_integer */) { static constexpr int idx(std::true_type) {
using squashed = detail::squashed_int_t<T>; using squashed = detail::squashed_int_t<T>;
return detail::tl_index_of<legal_types, squashed>::value; return detail::tl_index_of<legal_types, squashed>::value;
} }
...@@ -117,16 +119,22 @@ protected: ...@@ -117,16 +119,22 @@ protected:
return true; return true;
} }
// Catches any integer type that is smaller than int64_t.
template <class T> template <class T>
static bool assign_config_value(T& x, int64_t& y) { static typename std::enable_if<sizeof(T) < sizeof(int64_t), bool>::type
if (y < static_cast<int64_t>(std::numeric_limits<T>::lowest()) assign_config_value(T& x, int64_t& y) {
|| y > static_cast<int64_t>(std::numeric_limits<T>::max())) if (y < static_cast<int64_t>(std::numeric_limits<T>::lowest())
|| y > static_cast<int64_t>(std::numeric_limits<T>::max()))
return false; return false;
x = static_cast<T>(y); x = static_cast<T>(y);
return true; return true;
} }
static bool assign_config_value(uint64_t& x, int64_t& y) { // Catches size_t and uint64_t (yes, they differ on some compilers).
template <class T>
static typename std::enable_if<std::is_unsigned<T>::value
&& sizeof(T) == sizeof(int64_t), bool>::type
assign_config_value(T& x, int64_t& y) {
if (y < 0) if (y < 0)
return false; return false;
x = static_cast<uint64_t>(y); x = static_cast<uint64_t>(y);
...@@ -134,7 +142,7 @@ protected: ...@@ -134,7 +142,7 @@ protected:
} }
static bool assign_config_value(float& x, double& y) { static bool assign_config_value(float& x, double& y) {
if (y < static_cast<double>(std::numeric_limits<float>::lowest()) if (y < static_cast<double>(std::numeric_limits<float>::lowest())
|| y > static_cast<double>(std::numeric_limits<float>::max())) || y > static_cast<double>(std::numeric_limits<float>::max()))
return false; return false;
x = static_cast<float>(y); x = static_cast<float>(y);
...@@ -151,8 +159,9 @@ private: ...@@ -151,8 +159,9 @@ private:
char short_name_; char short_name_;
}; };
template <class T, bool IsInsertable = detail::can_insert_elements<T>() template <class T,
&& !std::is_same<T, std::string>::value> bool IsInsertable = detail::can_insert_elements<T>()
&& !std::is_same<T, std::string>::value>
class config_option_impl : public config_option { class config_option_impl : public config_option {
public: public:
config_option_impl(T& ref, const char* ctg, const char* nm, const char* xp) config_option_impl(T& ref, const char* ctg, const char* nm, const char* xp)
...@@ -192,7 +201,7 @@ public: ...@@ -192,7 +201,7 @@ public:
typename std::conditional< typename std::conditional<
std::is_floating_point<T>::value, std::is_floating_point<T>::value,
double, double,
T T
>::type >::type
>::type; >::type;
if (get<cfg_type>(&x) && assign_config_value(ref_, get<cfg_type>(x))) if (get<cfg_type>(&x) && assign_config_value(ref_, get<cfg_type>(x)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment