From 94ad11d299915739c539a887d82b509343d53c78 Mon Sep 17 00:00:00 2001 From: rboston628 Date: Fri, 13 Oct 2023 10:57:39 -0400 Subject: [PATCH] type security to enumerated string, extra test of non-class enum --- .../inc/MantidKernel/EnumeratedString.h | 4 +++ Framework/Kernel/test/EnumeratedStringTest.h | 31 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Framework/Kernel/inc/MantidKernel/EnumeratedString.h b/Framework/Kernel/inc/MantidKernel/EnumeratedString.h index f5485b611cba..52e3a0f58c38 100644 --- a/Framework/Kernel/inc/MantidKernel/EnumeratedString.h +++ b/Framework/Kernel/inc/MantidKernel/EnumeratedString.h @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace Mantid { @@ -38,6 +39,9 @@ class EnumeratedString { * * @tparam an optional pointer to a statically defined string comparator. */ + + static_assert(std::is_enum_v); // cause a compiler error if E is not an enum + public: EnumeratedString() { ensureCompatibleSize(); } diff --git a/Framework/Kernel/test/EnumeratedStringTest.h b/Framework/Kernel/test/EnumeratedStringTest.h index 359af8f37e35..b02b53f4d2bf 100644 --- a/Framework/Kernel/test/EnumeratedStringTest.h +++ b/Framework/Kernel/test/EnumeratedStringTest.h @@ -35,10 +35,12 @@ class EnumeratedStringTest : public CxxTest::TestSuite { // test constructor from enumerator COOLGUY dude1(CoolGuys::Fred); + TS_ASSERT_EQUALS(dude1, "Frederic"); TS_ASSERT_EQUALS(dude1, CoolGuys(0)); TS_ASSERT_EQUALS(dude1, CoolGuys::Fred); TS_ASSERT_EQUALS(dude1, coolGuyNames[0]); TS_ASSERT_DIFFERS(dude1, CoolGuys::Bill); + TS_ASSERT_DIFFERS(dude1, "Jeremy"); // test constructor from string name COOLGUY dude2(coolGuyNames[1]); @@ -211,7 +213,7 @@ class EnumeratedStringTest : public CxxTest::TestSuite { // try removing enum_count -- should give a compiler error enum class Letters : size_t { a, b, enum_count }; static const std::vector letters{"a", "b"}; - enum Graphia : size_t { alpha, beta, enum_count }; + enum class Graphia : size_t { alpha, beta, enum_count }; static const std::vector graphia{"alpha", "beta"}; EnumeratedString l1("a"); EnumeratedString l2("alpha"); @@ -232,8 +234,8 @@ class EnumeratedStringTest : public CxxTest::TestSuite { void testSwitchAndIf() { g_log.notice("\ntestSwitchAndIf..."); - const size_t index = 3; - CAKE tasty = Cakes(index), scrumptious = Cakes(index); + const char index = 3; + CAKE tasty = Cakes(index); // test enumerated string against string if (tasty == cakeNames[index]) { @@ -262,6 +264,29 @@ class EnumeratedStringTest : public CxxTest::TestSuite { } } + void testUnderlyingType() { + g_log.notice("\ntestUnderlyingType..."); + + // use a non-class enum to compare against chars + enum LetterA : char { a, enum_count }; + static const std::vector letterA = {"a"}; + typedef EnumeratedString LETTERA; + LETTERA a1 = a; // note that a is in namespace, vars cannot be named this + TS_ASSERT_EQUALS(a1, a); // compare against enum + TS_ASSERT_EQUALS(a1, "a"); // compares against string + TS_ASSERT_EQUALS(a1, 0); // compare against literal + TS_ASSERT_EQUALS(a1, '\x00'); // char literal at 0 + TS_ASSERT_DIFFERS(a1, 'a'); // Letters::a corresponds to 0, not to 'a'= 97 + TS_ASSERT_DIFFERS(a1, '\x01'); // char literal at 1 + TS_ASSERT_DIFFERS(a1, 1); + switch (a1) { + case '\x00': + break; + default: + TS_FAIL("EnumeratedString in 'SWITCH' failed to match to underlying type"); + } + } + void testCaseInsensitiveNameComparison() { g_log.notice("\ntestCaseInsensitiveNameComparison...");