base: Add a default output function for bitunion types.
authorGabe Black <gabeblack@google.com>
Tue, 27 Mar 2018 23:55:18 +0000 (16:55 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 28 Mar 2018 20:24:16 +0000 (20:24 +0000)
This way printing bitunions with, for instance, DPRINTF actually prints
something useful. More specialized overloads will still allow printing
particular bitunion types in ways that might make more sense for that
particular type.

Change-Id: I92beb0ce07683ba8b318cf25aa73e0057e4a60ef
Reviewed-on: https://gem5-review.googlesource.com/9461
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/base/bitunion.hh
src/base/bituniontest.cc

index 569d65031f1698847140c23be9d97194621ae162..b2a2ba806d7ed546c90e64493f0a5e81737e44d8 100644 (file)
@@ -32,7 +32,9 @@
 #define __BASE_BITUNION_HH__
 
 #include <functional>
+#include <iostream>
 #include <type_traits>
+#include <typeinfo>
 
 #include "base/bitfield.hh"
 
@@ -414,4 +416,48 @@ namespace std
     };
 }
 
+
+namespace BitfieldBackend
+{
+namespace
+{
+    template<typename T>
+    std::ostream &
+    bitfieldBackendPrinter(std::ostream &os, const T &t)
+    {
+        os << t;
+        return os;
+    }
+
+    //Since BitUnions are generally numerical values and not character codes,
+    //these specializations attempt to ensure that they get cast to integers
+    //of the appropriate type before printing.
+    template <>
+    std::ostream &
+    bitfieldBackendPrinter(std::ostream &os, const char &t)
+    {
+        os << (const int)t;
+        return os;
+    }
+
+    template <>
+    std::ostream &
+    bitfieldBackendPrinter(std::ostream &os, const unsigned char &t)
+    {
+        os << (const unsigned int)t;
+        return os;
+    }
+}
+}
+
+//A default << operator which casts a bitunion to its underlying type and
+//passes it to BitfieldBackend::bitfieldBackendPrinter.
+template <typename T>
+std::ostream &
+operator << (std::ostream &os, const BitUnionType<T> &bu)
+{
+    return BitfieldBackend::bitfieldBackendPrinter(
+            os, (BitUnionBaseType<T>)bu);
+}
+
 #endif // __BASE_BITUNION_HH__
index 8781d2d5ec2216e31181f700fd2abc6fffa1a750..d7ed95bb87c28608d7242df481f833bd548c8334 100644 (file)
@@ -270,3 +270,17 @@ TEST_F(BitUnionData, Templating)
     is64 = std::is_same<BitUnionBaseType<Dummy32>, uint64_t>::value;
     EXPECT_FALSE(is64);
 }
+
+TEST_F(BitUnionData, Output)
+{
+    sixtyFour = 1234567812345678;
+    std::stringstream ss;
+    ss << sixtyFour;
+    EXPECT_EQ(ss.str(), "1234567812345678");
+    ss.str("");
+
+    EmptyEight eight = 65;
+    ss << eight;
+    EXPECT_EQ(ss.str(), "65");
+    ss.str("");
+}