From: Gabe Black Date: Mon, 8 Jan 2018 02:38:04 +0000 (-0800) Subject: base: Enable specializing templates on BitUnion types. X-Git-Tag: v19.0.0.0~2368 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0d56fdef7a60691c59e1782a5c5c0a532dcdeeea;p=gem5.git base: Enable specializing templates on BitUnion types. Previously these relied on reaching into private internal definitions in the BitUnion types. Change-Id: Ia6c94de92986b85ec9e5fcb197459d450111fb36 Reviewed-on: https://gem5-review.googlesource.com/7202 Reviewed-by: Jason Lowe-Power Maintainer: Gabe Black --- diff --git a/src/base/bitunion.hh b/src/base/bitunion.hh index 1715e34d6..718a06838 100644 --- a/src/base/bitunion.hh +++ b/src/base/bitunion.hh @@ -351,4 +351,41 @@ namespace BitfieldBackend #define BitUnion16(name) __BitUnion(uint16_t, name) #define BitUnion8(name) __BitUnion(uint8_t, name) + +//These templates make it possible to define other templates related to +//BitUnions without having to refer to internal typedefs or the BitfieldBackend +//namespace. + +//To build a template specialization which works for all BitUnions, accept a +//template argument T, and then use BitUnionType as an argument in the +//template. To refer to the basic type the BitUnion wraps, use +//BitUnionBaseType. + +//For example: +//template +//void func(BitUnionType u) { BitUnionBaseType b = u; } + +//Also, BitUnionBaseType can be used on a BitUnion type directly. + +template +using BitUnionType = BitfieldBackend::BitUnionOperators; + +namespace BitfieldBackend +{ + template + struct BitUnionBaseType + { + typedef typename BitUnionType::__StorageType Type; + }; + + template + struct BitUnionBaseType > + { + typedef typename BitUnionType::__StorageType Type; + }; +} + +template +using BitUnionBaseType = typename BitfieldBackend::BitUnionBaseType::Type; + #endif // __BASE_BITUNION_HH__ diff --git a/src/base/bituniontest.cc b/src/base/bituniontest.cc index ed7b77b66..8781d2d5e 100644 --- a/src/base/bituniontest.cc +++ b/src/base/bituniontest.cc @@ -31,6 +31,7 @@ #include #include +#include #include "base/bitunion.hh" #include "base/cprintf.hh" @@ -140,6 +141,17 @@ class BitUnionData : public testing::Test { Split split; void SetUp() override { sixtyFour = 0; split = 0; } + + template + uint64_t templatedFunction(T) { return 0; } + + template + uint64_t + templatedFunction(BitUnionType u) + { + BitUnionBaseType b = u; + return b; + } }; TEST_F(BitUnionData, NormalBitfield) @@ -239,3 +251,22 @@ TEST_F(BitUnionData, Custom) EXPECT_EQ(split, 0xf0f0); EXPECT_EQ((uint64_t)split.split, 0xff); } + +TEST_F(BitUnionData, Templating) +{ + sixtyFour = 0xff; + EXPECT_EQ(templatedFunction(sixtyFour), 0xff); + EXPECT_EQ(templatedFunction((uint64_t)sixtyFour), 0); + + BitUnion(uint64_t, Dummy64) + EndBitUnion(Dummy64); + + BitUnion(uint32_t, Dummy32) + EndBitUnion(Dummy32); + + bool is64; + is64 = std::is_same, uint64_t>::value; + EXPECT_TRUE(is64); + is64 = std::is_same, uint64_t>::value; + EXPECT_FALSE(is64); +}