Hello Ciro Santilli,
I'd like you to do a code review. Please visit
https://gem5-review.googlesource.com/c/public/gem5/+/16382
to review the following change.
Change subject: base: Fix enums checkpointing
......................................................................
base: Fix enums checkpointing
Creating an extra version of string to number converters (__to_number)
in base/str.hh; it will be used by enums only when unserializing
them. The reason not to have a single helper for both enums and
integers is that std::numeric_limits trait is not specialized for enums.
We fix this by using the std::underlying_type trait.
Change-Id: I819e35c0df8c094de7b7a6390152964fa47d513d
Signed-off-by: Giacomo Travaglini <giacomo.travagl...@arm.com>
Reviewed-by: Ciro Santilli <ciro.santi...@arm.com>
---
M src/base/str.hh
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/src/base/str.hh b/src/base/str.hh
index 61022bd..1d7c780 100644
--- a/src/base/str.hh
+++ b/src/base/str.hh
@@ -40,6 +40,7 @@
#include <locale>
#include <stdexcept>
#include <string>
+#include <type_traits>
#include <vector>
#include "base/logging.hh"
@@ -108,8 +109,7 @@
* integeral type, as well as enums and floating-point types.
*/
template <class T>
-typename std::enable_if<(std::is_integral<T>::value ||
- std::is_enum<T>::value) &&
+typename std::enable_if<std::is_integral<T>::value &&
std::is_signed<T>::value, T>::type
__to_number(const std::string &value)
{
@@ -121,8 +121,7 @@
}
template <class T>
-typename std::enable_if<(std::is_integral<T>::value ||
- std::is_enum<T>::value) &&
+typename std::enable_if<std::is_integral<T>::value &&
!std::is_signed<T>::value, T>::type
__to_number(const std::string &value)
{
@@ -134,6 +133,30 @@
}
template <class T>
+typename std::enable_if<std::is_enum<T>::value, T>::type
+__to_number(const std::string &value)
+{
+ // start big and narrow it down if needed, determine the base
dynamically
+ long long r = std::stoll(value, nullptr, 0);
+
+ // Check if value is out of range. The check is different depending on
+ // whether it is a signed or unsigned enum
+ if (std::is_signed<typename std::underlying_type<T>::type>::value) {
+ if (r < std::numeric_limits<
+ typename std::underlying_type<T>::type>::min() ||
+ r > std::numeric_limits<
+ typename std::underlying_type<T>::type>::max())
+ throw std::out_of_range("Out of range");
+ } else {
+ if (r > std::numeric_limits<
+ typename std::underlying_type<T>::type>::max())
+ throw std::out_of_range("Out of range");
+ }
+
+ return static_cast<T>(r);
+}
+
+template <class T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
__to_number(const std::string &value)
{
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/16382
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I819e35c0df8c094de7b7a6390152964fa47d513d
Gerrit-Change-Number: 16382
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <giacomo.travagl...@arm.com>
Gerrit-Reviewer: Ciro Santilli <ciro.santi...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev