base: Use if constexpr to simplify the templates in __to_number.
The c++-17 feature "if constexpr" allows you to put code inside a normal if which would normally have to be separated out using templates. The condition of the if must be compile time evaluated, and the not-taken path is discarded by the compiler. Change-Id: I026381b2dbb140ef7f1b5cb23803782683ec419c Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48503 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Daniel Carvalho <odanrc@yahoo.com.br> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -110,27 +110,9 @@ tokenize(std::vector<std::string> &vector, const std::string &s,
|
||||
* @name String to number helper functions for signed and unsigned
|
||||
* integeral type, as well as enums and floating-point types.
|
||||
*/
|
||||
template <class T>
|
||||
typename std::enable_if_t<std::is_integral<T>::value &&
|
||||
std::is_signed<T>::value, T>
|
||||
__to_number(const std::string &value)
|
||||
{
|
||||
// Cannot parse scientific numbers
|
||||
if (value.find('e') != std::string::npos) {
|
||||
throw std::invalid_argument("Cannot convert scientific to integral");
|
||||
}
|
||||
// start big and narrow it down if needed, determine the base dynamically
|
||||
long long r = std::stoll(value, nullptr, 0);
|
||||
if (r < std::numeric_limits<T>::lowest()
|
||||
|| r > std::numeric_limits<T>::max()) {
|
||||
throw std::out_of_range("Out of range");
|
||||
}
|
||||
return static_cast<T>(r);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename std::enable_if_t<std::is_integral<T>::value &&
|
||||
!std::is_signed<T>::value, T>
|
||||
typename std::enable_if_t<std::is_integral_v<T>, T>
|
||||
__to_number(const std::string &value)
|
||||
{
|
||||
// Cannot parse scientific numbers
|
||||
@@ -138,21 +120,26 @@ __to_number(const std::string &value)
|
||||
throw std::invalid_argument("Cannot convert scientific to integral");
|
||||
}
|
||||
// start big and narrow it down if needed, determine the base dynamically
|
||||
unsigned long long r = std::stoull(value, nullptr, 0);
|
||||
if (r > std::numeric_limits<T>::max())
|
||||
throw std::out_of_range("Out of range");
|
||||
return static_cast<T>(r);
|
||||
if constexpr (std::is_signed_v<T>) {
|
||||
long long r = std::stoll(value, nullptr, 0);
|
||||
if (r < std::numeric_limits<T>::lowest()
|
||||
|| r > std::numeric_limits<T>::max()) {
|
||||
throw std::out_of_range("Out of range");
|
||||
}
|
||||
return static_cast<T>(r);
|
||||
} else {
|
||||
unsigned long long r = std::stoull(value, nullptr, 0);
|
||||
if (r > std::numeric_limits<T>::max())
|
||||
throw std::out_of_range("Out of range");
|
||||
return static_cast<T>(r);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename std::enable_if_t<std::is_enum<T>::value, T>
|
||||
__to_number(const std::string &value)
|
||||
{
|
||||
// Cannot parse scientific numbers
|
||||
if (value.find('e') != std::string::npos) {
|
||||
throw std::invalid_argument("Cannot convert scientific to integral");
|
||||
}
|
||||
auto r = __to_number<typename std::underlying_type<T>::type>(value);
|
||||
auto r = __to_number<typename std::underlying_type_t<T>>(value);
|
||||
return static_cast<T>(r);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user