From 8289181b8c45dcb0e51854dd6d191ad04026b11a Mon Sep 17 00:00:00 2001 From: Martin Jobst Date: Tue, 19 Mar 2024 17:41:00 +0100 Subject: [PATCH 1/3] Add const partial access Add partial access for const values, which directly returns the partial type and avoids the temporary accessor object altogether. --- src/core/datatypes/forte_any_bit_partial.h | 13 +- src/core/datatypes/forte_byte.h | 29 +++- src/core/datatypes/forte_dword.h | 29 +++- src/core/datatypes/forte_lword.h | 28 +++- src/core/datatypes/forte_word.h | 29 +++- .../CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp | 26 ++++ .../CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp | 91 ++++++++++++ .../CIEC_PARTIAL/CIEC_LWORD_PARTIAL_test.cpp | 140 ++++++++++++++++++ .../CIEC_PARTIAL/CIEC_WORD_PARTIAL_test.cpp | 53 +++++++ 9 files changed, 418 insertions(+), 20 deletions(-) diff --git a/src/core/datatypes/forte_any_bit_partial.h b/src/core/datatypes/forte_any_bit_partial.h index 9a80fcb0..d8ea002a 100644 --- a/src/core/datatypes/forte_any_bit_partial.h +++ b/src/core/datatypes/forte_any_bit_partial.h @@ -31,9 +31,13 @@ class CIEC_ANY_BIT_PARTIAL final : public PartialType { using PartialType::operator=; CIEC_ANY_BIT_PARTIAL(SourceType &paValue, const size_t paIndex) : mOriginalValue(paValue), mIndex(paIndex) { + *this = partialValue(paValue, paIndex); + } + + static PartialType partialValue(const SourceType &paValue, const size_t paIndex) { PartialValueType partialValue = 0; if(paIndex <= scmMaxIndex) { - const auto shiftIndex = mIndex * scmPartialDigits; + const auto shiftIndex = paIndex * scmPartialDigits; const SourceValueType sourceValue = static_cast(paValue); if constexpr(std::is_same_v) { partialValue = static_cast((sourceValue >> shiftIndex) & 0x1); @@ -43,7 +47,7 @@ class CIEC_ANY_BIT_PARTIAL final : public PartialType { } else { DEVLOG_ERROR("Attempted partial index %d outside the range of allowed indices %d\n", paIndex, scmMaxIndex); } - *this = PartialType(partialValue); + return PartialType(partialValue); } CIEC_ANY_BIT_PARTIAL& operator=(const CIEC_ANY_BIT_PARTIAL &paValue) { @@ -55,8 +59,9 @@ class CIEC_ANY_BIT_PARTIAL final : public PartialType { if(mIndex <= scmMaxIndex) { constexpr SourceValueType maskTemplate = std::numeric_limits::max(); const auto shiftIndex = mIndex * scmPartialDigits; - const SourceValueType mask = (maskTemplate << shiftIndex); - const SourceValueType partialPartValue = static_cast(static_cast(*this)) << shiftIndex; + const SourceValueType mask = static_cast(maskTemplate << shiftIndex); + const SourceValueType partialPartValue = static_cast( + static_cast(static_cast(*this)) << shiftIndex); const SourceValueType sourceValue = static_cast(mOriginalValue); SourceValueType mergedValue = sourceValue ^ ((sourceValue ^ partialPartValue) & mask); mOriginalValue = SourceType(mergedValue); diff --git a/src/core/datatypes/forte_byte.h b/src/core/datatypes/forte_byte.h index 02795c62..742266b1 100644 --- a/src/core/datatypes/forte_byte.h +++ b/src/core/datatypes/forte_byte.h @@ -96,13 +96,34 @@ class CIEC_BYTE : public CIEC_ANY_BIT{ /*! \brief Partial access within a CIEC_BYTE (e.g. [BYTE].partial()) * */ - template CIEC_ANY_BIT_PARTIAL partial(size_t paIndex){ + template + CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { return CIEC_ANY_BIT_PARTIAL(*this, paIndex); } - template CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT& paIndex){ - size_t index = paIndex.getUnsignedValue(); - return CIEC_ANY_BIT_PARTIAL(*this, index); + template + T partial(size_t paIndex) const { + return CIEC_ANY_BIT_PARTIAL::partialValue(*this, paIndex); + } + + template + T cpartial(size_t paIndex) const { + return partial(paIndex); + } + + template + CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT &paIndex) { + return partial(paIndex.getUnsignedValue()); + } + + template + T partial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex.getUnsignedValue()); + } + + template + T cpartial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex); } }; diff --git a/src/core/datatypes/forte_dword.h b/src/core/datatypes/forte_dword.h index d7aaa6aa..5f2770ed 100644 --- a/src/core/datatypes/forte_dword.h +++ b/src/core/datatypes/forte_dword.h @@ -120,13 +120,34 @@ class CIEC_DWORD : public CIEC_ANY_BIT { /*! \brief Partial access within a CIEC_DWORD (e.g. [DWORD].partial(1)) * */ - template CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { + template + CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { return CIEC_ANY_BIT_PARTIAL(*this, paIndex); } - template CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT& paIndex){ - size_t index = paIndex.getUnsignedValue(); - return CIEC_ANY_BIT_PARTIAL(*this, index); + template + T partial(size_t paIndex) const { + return CIEC_ANY_BIT_PARTIAL::partialValue(*this, paIndex); + } + + template + T cpartial(size_t paIndex) const { + return partial(paIndex); + } + + template + CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT &paIndex) { + return partial(paIndex.getUnsignedValue()); + } + + template + T partial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex.getUnsignedValue()); + } + + template + T cpartial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex); } }; diff --git a/src/core/datatypes/forte_lword.h b/src/core/datatypes/forte_lword.h index 0315981f..94f430cf 100644 --- a/src/core/datatypes/forte_lword.h +++ b/src/core/datatypes/forte_lword.h @@ -131,15 +131,35 @@ class CIEC_LWORD : public CIEC_ANY_BIT{ /*! \brief Partial access within a CIEC_LWORD (e.g. [LWORD].partial(1)) * */ - template CIEC_ANY_BIT_PARTIAL partial(size_t paIndex){ + template + CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { return CIEC_ANY_BIT_PARTIAL(*this, paIndex); } - template CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT& paIndex){ - size_t index = paIndex.getUnsignedValue(); - return CIEC_ANY_BIT_PARTIAL(*this, index); + template + T partial(size_t paIndex) const { + return CIEC_ANY_BIT_PARTIAL::partialValue(*this, paIndex); } + template + T cpartial(size_t paIndex) const { + return partial(paIndex); + } + + template + CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT &paIndex) { + return partial(paIndex.getUnsignedValue()); + } + + template + T partial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex.getUnsignedValue()); + } + + template + T cpartial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex); + } }; inline CIEC_LWORD operator ""_LWORD(unsigned long long int paValue) { diff --git a/src/core/datatypes/forte_word.h b/src/core/datatypes/forte_word.h index d26b9612..ace2b8c0 100644 --- a/src/core/datatypes/forte_word.h +++ b/src/core/datatypes/forte_word.h @@ -108,13 +108,34 @@ class CIEC_WORD : public CIEC_ANY_BIT{ /*! \brief Partial access within a CIEC_WORD (e.g. [WORD].partial(1)) * */ - template CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { + template + CIEC_ANY_BIT_PARTIAL partial(size_t paIndex) { return CIEC_ANY_BIT_PARTIAL(*this, paIndex); } - template CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT& paIndex){ - size_t index = paIndex.getUnsignedValue(); - return CIEC_ANY_BIT_PARTIAL(*this, index); + template + T partial(size_t paIndex) const { + return CIEC_ANY_BIT_PARTIAL::partialValue(*this, paIndex); + } + + template + T cpartial(size_t paIndex) const { + return partial(paIndex); + } + + template + CIEC_ANY_BIT_PARTIAL partial(const CIEC_ANY_INT &paIndex) { + return partial(paIndex.getUnsignedValue()); + } + + template + T partial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex.getUnsignedValue()); + } + + template + T cpartial(const CIEC_ANY_INT &paIndex) const { + return partial(paIndex); } }; diff --git a/tests/core/datatypes/CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp b/tests/core/datatypes/CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp index 26015806..e546ebe4 100644 --- a/tests/core/datatypes/CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp +++ b/tests/core/datatypes/CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp @@ -35,7 +35,13 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_INITVALUES) { test4X_0(nTestByte,4); test4X_0(nTestByte,0); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_INITVALUES_CONST) { + const CIEC_BYTE nTestByte; + test4X_0(nTestByte,4); + test4X_0(nTestByte,0); } BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_CONST_INIT) { @@ -66,6 +72,13 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE1_CHECK_BIT) { } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE1_CHECK_BIT_CONST) { + const CIEC_BYTE nTestByte(0xBE); + test4X_B(nTestByte,4); + test4X_E(nTestByte,0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE2_CHECK_BIT) { CIEC_BYTE nTestByte(0xBA); test4X_B(nTestByte,4); @@ -73,6 +86,13 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE2_CHECK_BIT) { } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE2_CHECK_BIT_CONST) { + const CIEC_BYTE nTestByte(0xBA); + test4X_B(nTestByte,4); + test4X_A(nTestByte,0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_BYTE_VALUE_CHANGE_CHECK_BYTE) { CIEC_BYTE nTestByte(0xBE); @@ -193,6 +213,12 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESSOUT_OF_INDEX_ACCESS) { BOOST_TEST(static_cast(nByte.partial(CIEC_SINT(8))) == false); } +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_TO_SAME_PARTIAL) { + CIEC_BYTE nByte(0x02U); + nByte.partial(CIEC_SINT(0)) = CIEC_BOOL(nByte.cpartial(CIEC_SINT(0)) || true); + BOOST_TEST(static_cast(nByte) == 0x03U); +} + BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_TO_OTHER_PARTIAL) { CIEC_BYTE nByte(0x01U); nByte.partial(CIEC_SINT(1)) = nByte.partial(CIEC_SINT(0)); diff --git a/tests/core/datatypes/CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp b/tests/core/datatypes/CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp index 9ca343d2..0e5a0984 100644 --- a/tests/core/datatypes/CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp +++ b/tests/core/datatypes/CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp @@ -47,6 +47,21 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_BIT_CONST) +{ + const CIEC_DWORD nTestDWord; + + test4X_0(nTestDWord,28); + test4X_0(nTestDWord,24); + test4X_0(nTestDWord,20); + test4X_0(nTestDWord,16); + test4X_0(nTestDWord,12); + test4X_0(nTestDWord,8); + test4X_0(nTestDWord,4); + test4X_0(nTestDWord,0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_BYTE) { CIEC_DWORD nTestDWord; @@ -58,6 +73,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_BYTE_CONST) +{ + const CIEC_DWORD nTestDWord; + + BOOST_CHECK_EQUAL((nTestDWord.partial(0)),0); + BOOST_CHECK_EQUAL((nTestDWord.partial(1)),0); + BOOST_CHECK_EQUAL((nTestDWord.partial(2)),0); + BOOST_CHECK_EQUAL((nTestDWord.partial(3)),0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_WORD) { CIEC_DWORD nTestDWord; @@ -67,6 +93,15 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_WORD) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_WORD_CONST) +{ + const CIEC_DWORD nTestDWord; + + BOOST_CHECK_EQUAL((nTestDWord.partial(0)),0); + BOOST_CHECK_EQUAL((nTestDWord.partial(1)),0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_DWORD) { CIEC_DWORD nTestDWord; @@ -103,6 +138,22 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_BIT_CONST) +{ + const CIEC_DWORD nTestDWord = 0xCAFEBABE_DWORD; + + test4X_C(nTestDWord,28) + test4X_A(nTestDWord,24) + test4X_F(nTestDWord,20) + test4X_E(nTestDWord,16) + + test4X_B(nTestDWord,12) + test4X_A(nTestDWord,8) + test4X_B(nTestDWord,4) + test4X_E(nTestDWord,0) + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_BYTE) { CIEC_DWORD nTestDWord; @@ -116,6 +167,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_BYTE_CONST) +{ + const CIEC_DWORD nTestDWord = 0xCAFEBABE_DWORD; + + BOOST_CHECK_EQUAL((nTestDWord.partial(0)), 0xBE); + BOOST_CHECK_EQUAL((nTestDWord.partial(1)), 0xBA); + BOOST_CHECK_EQUAL((nTestDWord.partial(2)), 0xFE); + BOOST_CHECK_EQUAL((nTestDWord.partial(3)), 0xCA); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_WORD) { CIEC_DWORD nTestDWord; @@ -127,6 +189,15 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_WORD) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_WORD_CONST) +{ + const CIEC_DWORD nTestDWord = 0xCAFEBABE_DWORD; + + BOOST_CHECK_EQUAL((nTestDWord.partial(0)), 0xBABE); + BOOST_CHECK_EQUAL((nTestDWord.partial(1)), 0xCAFE); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_DWORD) { CIEC_DWORD nTestDWord; @@ -1218,6 +1289,26 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WRITE_WITH_IEC_TYPE_INDEX) BOOST_TEST(static_cast(nDWord) == 3U); } +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_SAME_PARTIAL_BOOL) { + CIEC_DWORD nDWord(0x00000002U); + nDWord.partial(CIEC_SINT(0)) = CIEC_BOOL(nDWord.cpartial(CIEC_SINT(0)) || true); + BOOST_TEST(static_cast(nDWord) == 0x03U); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BYTE_TO_SAME_PARTIAL_BYTE) { + CIEC_DWORD nDWord(0xABCDEFFEU); + nDWord.partial(CIEC_SINT(0)) = CIEC_BYTE( + static_cast(nDWord.cpartial(CIEC_SINT(0))) | 0x01); + BOOST_TEST(static_cast(nDWord) == 0xABCDEFFFU); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_WORD_TO_SAME_PARTIAL_WORD) { + CIEC_DWORD nDWord(0xABCDEFFEU); + nDWord.partial(CIEC_SINT(0)) = CIEC_WORD( + static_cast(nDWord.cpartial(CIEC_SINT(0))) | 0x1001); + BOOST_TEST(static_cast(nDWord) == 0xABCDFFFFU); +} + BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_OTHER_PARTIAL_BOOL) { CIEC_DWORD nDWord(0x00000001U); nDWord.partial(CIEC_SINT(1)) = nDWord.partial(CIEC_SINT(0)); diff --git a/tests/core/datatypes/CIEC_PARTIAL/CIEC_LWORD_PARTIAL_test.cpp b/tests/core/datatypes/CIEC_PARTIAL/CIEC_LWORD_PARTIAL_test.cpp index 934b4a4f..efe862a9 100644 --- a/tests/core/datatypes/CIEC_PARTIAL/CIEC_LWORD_PARTIAL_test.cpp +++ b/tests/core/datatypes/CIEC_PARTIAL/CIEC_LWORD_PARTIAL_test.cpp @@ -60,6 +60,32 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_BIT_CONST) +{ + const CIEC_LWORD nTestLWord; + + test4X_0(nTestLWord, 60); + test4X_0(nTestLWord, 56); + test4X_0(nTestLWord, 52); + test4X_0(nTestLWord, 48); + + test4X_0(nTestLWord, 44); + test4X_0(nTestLWord, 40); + test4X_0(nTestLWord, 36); + test4X_0(nTestLWord, 32); + + test4X_0(nTestLWord, 28); + test4X_0(nTestLWord, 24); + test4X_0(nTestLWord, 20); + test4X_0(nTestLWord, 16); + + test4X_0(nTestLWord, 12); + test4X_0(nTestLWord, 8); + test4X_0(nTestLWord, 4); + test4X_0(nTestLWord, 0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_BYTE) { CIEC_LWORD nTestLWord; @@ -75,6 +101,21 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_BYTE_CONST) +{ + const CIEC_LWORD nTestLWord; + + BOOST_CHECK_EQUAL((nTestLWord.partial(0)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(1)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(2)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(3)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(4)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(5)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(6)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(7)),0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_WORD) { CIEC_LWORD nTestLWord; @@ -86,6 +127,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_WORD) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_WORD_CONST) +{ + const CIEC_LWORD nTestLWord; + + BOOST_CHECK_EQUAL((nTestLWord.partial(0)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(1)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(2)),0); + BOOST_CHECK_EQUAL((nTestLWord.partial(3)),0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_INITVALUES_CHECK_DWORD) { CIEC_LWORD nTestLWord; @@ -133,6 +185,32 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_BIT_CONST) +{ + const CIEC_LWORD nTestLWord = 0xDEADBEEFCAFEBABE_LWORD; + + test4X_D(nTestLWord, 60) + test4X_E(nTestLWord, 56) + test4X_A(nTestLWord, 52) + test4X_D(nTestLWord, 48) + + test4X_B(nTestLWord, 44) + test4X_E(nTestLWord, 40) + test4X_E(nTestLWord, 36) + test4X_F(nTestLWord, 32) + + test4X_C(nTestLWord, 28) + test4X_A(nTestLWord, 24) + test4X_F(nTestLWord, 20) + test4X_E(nTestLWord, 16) + + test4X_B(nTestLWord, 12) + test4X_A(nTestLWord, 8) + test4X_B(nTestLWord, 4) + test4X_E(nTestLWord, 0) + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_BYTE) { CIEC_LWORD nTestLWord; @@ -150,6 +228,21 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_BYTE_CONST) +{ + const CIEC_LWORD nTestLWord = 0xDEADBEEFCAFEBABE_LWORD; + + BOOST_CHECK_EQUAL((nTestLWord.partial(0)), 0xBE); + BOOST_CHECK_EQUAL((nTestLWord.partial(1)), 0xBA); + BOOST_CHECK_EQUAL((nTestLWord.partial(2)), 0xFE); + BOOST_CHECK_EQUAL((nTestLWord.partial(3)), 0xCA); + BOOST_CHECK_EQUAL((nTestLWord.partial(4)), 0xEF); + BOOST_CHECK_EQUAL((nTestLWord.partial(5)), 0xBE); + BOOST_CHECK_EQUAL((nTestLWord.partial(6)), 0xAD); + BOOST_CHECK_EQUAL((nTestLWord.partial(7)), 0xDE); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_WORD) { CIEC_LWORD nTestLWord; @@ -163,6 +256,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_WORD) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_WORD_CONST) +{ + const CIEC_LWORD nTestLWord = 0xDEADBEEFCAFEBABE_LWORD; + + BOOST_CHECK_EQUAL((nTestLWord.partial(0)), 0xBABE); + BOOST_CHECK_EQUAL((nTestLWord.partial(1)), 0xCAFE); + BOOST_CHECK_EQUAL((nTestLWord.partial(2)), 0xBEEF); + BOOST_CHECK_EQUAL((nTestLWord.partial(3)), 0xDEAD); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_DWORD) { CIEC_LWORD nTestLWord; @@ -174,6 +278,15 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_DWORD) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_VALUE_CHECK_DWORD_CONST) +{ + const CIEC_LWORD nTestLWord = 0xDEADBEEFCAFEBABE_LWORD; + + BOOST_CHECK_EQUAL((nTestLWord.partial(0)), 0xCAFEBABEU); + BOOST_CHECK_EQUAL((nTestLWord.partial(1)), 0xDEADBEEFU); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_LWORD_ASSIGN_BIT_CHECK_BIT) { CIEC_LWORD nTestLWord; @@ -844,6 +957,33 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WRITE_WITH_IEC_TYPE_INDEX) BOOST_TEST(static_cast(nLWord) == 3U); } +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_SAME_PARTIAL_BOOL) { + CIEC_LWORD nLWord(0x000000000000002U); + nLWord.partial(CIEC_SINT(0)) = CIEC_BOOL(nLWord.cpartial(CIEC_SINT(0)) || true); + BOOST_TEST(static_cast(nLWord) == 0x03U); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BYTE_TO_SAME_PARTIAL_BYTE) { + CIEC_LWORD nLWord(0xABCDEFABCDEF00FEU); + nLWord.partial(CIEC_SINT(0)) = CIEC_BYTE( + static_cast(nLWord.cpartial(CIEC_SINT(0))) | 0x01); + BOOST_TEST(static_cast(nLWord) == 0xABCDEFABCDEF00FFU); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_WORD_TO_SAME_PARTIAL_WORD) { + CIEC_LWORD nLWord(0xABCDEFABCDEF00FEU); + nLWord.partial(CIEC_SINT(0)) = CIEC_WORD( + static_cast(nLWord.cpartial(CIEC_SINT(0))) | 0x1001); + BOOST_TEST(static_cast(nLWord) == 0xABCDEFABCDEF10FFU); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_DWORD_TO_SAME_PARTIAL_DWORD) { + CIEC_LWORD nLWord(0xABCDEFABCDEF00FEU); + nLWord.partial(CIEC_SINT(0)) = CIEC_DWORD( + static_cast(nLWord.cpartial(CIEC_SINT(0))) | 0x1001); + BOOST_TEST(static_cast(nLWord) == 0xABCDEFABCDEF10FFU); +} + BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_OTHER_PARTIAL_BOOL) { CIEC_LWORD nLWord(0x000000000000001U); nLWord.partial(CIEC_SINT(1)) = nLWord.partial(CIEC_SINT(0)); diff --git a/tests/core/datatypes/CIEC_PARTIAL/CIEC_WORD_PARTIAL_test.cpp b/tests/core/datatypes/CIEC_PARTIAL/CIEC_WORD_PARTIAL_test.cpp index 18765b8c..dcea65cf 100644 --- a/tests/core/datatypes/CIEC_PARTIAL/CIEC_WORD_PARTIAL_test.cpp +++ b/tests/core/datatypes/CIEC_PARTIAL/CIEC_WORD_PARTIAL_test.cpp @@ -42,6 +42,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_INITVALUES_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_INITVALUES_CHECK_BIT_CONST) +{ + const CIEC_WORD nTestWord; + + test4X_0(nTestWord, 12) + test4X_0(nTestWord, 8) + test4X_0(nTestWord, 4) + test4X_0(nTestWord, 0) + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_INITVALUES_CHECK_BYTE) { CIEC_WORD nTestWord; @@ -51,6 +62,15 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_INITVALUES_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_INITVALUES_CHECK_BYTE_CONST) +{ + const CIEC_WORD nTestWord; + + BOOST_CHECK_EQUAL((nTestWord.partial(0)),0); + BOOST_CHECK_EQUAL((nTestWord.partial(1)),0); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_CONST_INIT) { const CIEC_BYTE nTestByte(0x42); @@ -82,6 +102,15 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_VALUE_CHECK_BYTE) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_VALUE_CHECK_BYTE_CONST) +{ + const CIEC_WORD nTestWord = 0xBABE_WORD; + + BOOST_CHECK_EQUAL((nTestWord.partial(0)), 0xBE); + BOOST_CHECK_EQUAL((nTestWord.partial(1)), 0xBA); + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_VALUE_CHECK_BIT) { CIEC_WORD nTestWord; @@ -95,6 +124,17 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_VALUE_CHECK_BIT) } +BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_VALUE_CHECK_BIT_CONST) +{ + const CIEC_WORD nTestWord = 0xBABE_WORD; + + test4X_B(nTestWord, 12) + test4X_A(nTestWord, 8) + test4X_B(nTestWord, 4) + test4X_E(nTestWord, 0) + +} + BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WORD_ASSIGN_BIT_CHECK_BIT) { CIEC_WORD nTestWord; @@ -271,6 +311,19 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WRITE_WITH_IEC_TYPE_INDEX) BOOST_TEST(static_cast(nWord) == 3U); } +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_SAME_PARTIAL_BOOL) { + CIEC_WORD nWord(0x0002U); + nWord.partial(CIEC_SINT(0)) = CIEC_BOOL(nWord.cpartial(CIEC_SINT(0)) || true); + BOOST_TEST(static_cast(nWord) == 0x03U); +} + +BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BYTE_TO_SAME_PARTIAL_BYTE) { + CIEC_WORD nWord(0xABFEU); + nWord.partial(CIEC_SINT(0)) = CIEC_BYTE( + static_cast(nWord.cpartial(CIEC_SINT(0))) | 0x01); + BOOST_TEST(static_cast(nWord) == 0xABFFU); +} + BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_OTHER_PARTIAL_BOOL) { CIEC_WORD nWord(0x0001U); nWord.partial(CIEC_SINT(1)) = nWord.partial(CIEC_SINT(0)); From f916f46b0153b1ebccd2d02a9e5a541c9e9c0959 Mon Sep 17 00:00:00 2001 From: Martin Jobst Date: Thu, 21 Mar 2024 17:33:25 +0100 Subject: [PATCH 2/3] Add missing STRING_TO_CHAR function --- src/core/datatypes/convert/StringToConvertFunctions.h | 4 ++++ tests/core/datatypes/convert/convert_functionstests.cpp | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/core/datatypes/convert/StringToConvertFunctions.h b/src/core/datatypes/convert/StringToConvertFunctions.h index 61d95c10..074c617c 100644 --- a/src/core/datatypes/convert/StringToConvertFunctions.h +++ b/src/core/datatypes/convert/StringToConvertFunctions.h @@ -96,6 +96,10 @@ inline const CIEC_LREAL func_STRING_AS_LREAL(const CIEC_STRING &paVal){ return func_STRING_AS_X_helper(paVal); } +inline const CIEC_CHAR func_STRING_TO_CHAR(const CIEC_STRING &paVal){ + return paVal.length() > 0 ? paVal[1] : 0_CHAR; +} + #ifdef FORTE_USE_WSTRING_DATATYPE inline const CIEC_WSTRING func_STRING_TO_WSTRING(const CIEC_STRING &paVal){ return func_STRING_AS_X_helper(paVal); diff --git a/tests/core/datatypes/convert/convert_functionstests.cpp b/tests/core/datatypes/convert/convert_functionstests.cpp index d22ff41f..ecc00608 100644 --- a/tests/core/datatypes/convert/convert_functionstests.cpp +++ b/tests/core/datatypes/convert/convert_functionstests.cpp @@ -427,7 +427,13 @@ BOOST_AUTO_TEST_SUITE(convert_functions) BOOST_TEST( static_cast(timeInNs) == static_cast(INT64_C(172800000000000) + INT64_C(18000000000000) + INT64_C(2580000000000) + INT64_C(12000000000) + INT64_C(44000000) + INT64_C(27000) + INT64_C(31))); } - + + BOOST_AUTO_TEST_CASE(CONVERT_STRING_TO_CHAR) { + BOOST_TEST(static_cast(func_STRING_TO_CHAR(""_STRING)) == '\0'); + BOOST_TEST(static_cast(func_STRING_TO_CHAR("a"_STRING)) == 'a'); + BOOST_TEST(static_cast(func_STRING_TO_CHAR("abc"_STRING)) == 'a'); + } + /**** BYTE_BCD_TO_* ****/ BOOST_AUTO_TEST_CASE(BYTE_BCD_TO_USINT) { using SourceType = CIEC_BYTE; From 2ee5548324f184811d8739e431702d16f6ca922f Mon Sep 17 00:00:00 2001 From: Martin Jobst Date: Thu, 21 Mar 2024 17:03:16 +0100 Subject: [PATCH 3/3] Support EQ and NE for array and struct --- src/core/datatypes/forte_array.cpp | 17 --------- src/core/datatypes/forte_array.h | 26 ++++++++++++-- src/core/datatypes/forte_array_common.h | 19 +++++++++- src/core/datatypes/forte_struct.h | 10 ++++++ src/core/iec61131_functions.h | 8 +++-- tests/core/iec61131_functionstests.cpp | 47 +++++++++++++++++++++++++ 6 files changed, 105 insertions(+), 22 deletions(-) diff --git a/src/core/datatypes/forte_array.cpp b/src/core/datatypes/forte_array.cpp index 5eba2cda..cb04edef 100644 --- a/src/core/datatypes/forte_array.cpp +++ b/src/core/datatypes/forte_array.cpp @@ -40,23 +40,6 @@ void CIEC_ARRAY::setValue(const CIEC_ANY &paValue) { } } -bool CIEC_ARRAY::equals(const CIEC_ANY &paOther) const { - if (paOther.getDataTypeID() == CIEC_ANY::e_ARRAY) { - auto &otherArray = static_cast(paOther); - if (getLowerBound() != otherArray.getLowerBound() || getUpperBound() != otherArray.getUpperBound()) { - return false; - } - - for (intmax_t i = getLowerBound(), end = getUpperBound(); i <= end; ++i) { - if (!operator[](i).equals(otherArray[i])) { - return false; - } - } - return true; - } - return false; -} - int CIEC_ARRAY::toString(char *paValue, size_t paBufferSize) const { int nBytesUsed = -1; diff --git a/src/core/datatypes/forte_array.h b/src/core/datatypes/forte_array.h index 900355e2..90eb3ba1 100644 --- a/src/core/datatypes/forte_array.h +++ b/src/core/datatypes/forte_array.h @@ -27,7 +27,24 @@ /** \brief A common supertype for all CIEC_ARRAY variants, providing the minimal interface an array must provide */ class CIEC_ARRAY : public CIEC_ANY_DERIVED { -public: + friend bool operator==(const CIEC_ARRAY &paLeft, const CIEC_ARRAY &paRight) { + if (paLeft.getLowerBound() != paRight.getLowerBound() || paLeft.getUpperBound() != paRight.getUpperBound()) { + return false; + } + + for (intmax_t i = paLeft.getLowerBound(), end = paLeft.getUpperBound(); i <= end; ++i) { + if (!paLeft[i].equals(paRight[i])) { + return false; + } + } + return true; + } + + friend bool operator!=(const CIEC_ARRAY &paLeft, const CIEC_ARRAY &paRight) { + return !(paLeft == paRight); + } + + public: using value_type = CIEC_ANY; using pointer = value_type *; using const_pointer = const value_type *; @@ -93,7 +110,12 @@ class CIEC_ARRAY : public CIEC_ANY_DERIVED { void setValue(const CIEC_ANY &paValue) override; - [[nodiscard]] bool equals(const CIEC_ANY &paOther) const override; + [[nodiscard]] bool equals(const CIEC_ANY &paOther) const override { + if (paOther.getDataTypeID() == CIEC_ANY::e_ARRAY) { + return *this == static_cast(paOther); + } + return false; + } [[nodiscard]] int toString(char *paValue, size_t paBufferSize) const override; diff --git a/src/core/datatypes/forte_array_common.h b/src/core/datatypes/forte_array_common.h index 09e8dd01..786a03b1 100644 --- a/src/core/datatypes/forte_array_common.h +++ b/src/core/datatypes/forte_array_common.h @@ -29,7 +29,24 @@ */ template class CIEC_ARRAY_COMMON : public CIEC_ARRAY { -public: + friend bool operator==(const CIEC_ARRAY_COMMON &paLeft, const CIEC_ARRAY_COMMON &paRight) { + if (paLeft.getLowerBound() != paRight.getLowerBound() || paLeft.getUpperBound() != paRight.getUpperBound()) { + return false; + } + + for (intmax_t i = paLeft.getLowerBound(), end = paLeft.getUpperBound(); i <= end; ++i) { + if (!func_EQ(paLeft[i], paRight[i])) { + return false; + } + } + return true; + } + + friend bool operator!=(const CIEC_ARRAY_COMMON &paLeft, const CIEC_ARRAY_COMMON &paRight) { + return !(paLeft == paRight); + } + + public: using value_type = T; using pointer = value_type *; using const_pointer = const value_type *; diff --git a/src/core/datatypes/forte_struct.h b/src/core/datatypes/forte_struct.h index 6a4e3809..874d25ac 100644 --- a/src/core/datatypes/forte_struct.h +++ b/src/core/datatypes/forte_struct.h @@ -20,6 +20,16 @@ #include "forte_any_derived.h" class CIEC_STRUCT : public CIEC_ANY_DERIVED{ + template , int> = 0> + friend bool operator==(const T &paLeft, const T &paRight) { + return paLeft.equals(paRight); + } + + template , int> = 0> + friend bool operator!=(const T &paLeft, const T &paRight) { + return !(paLeft == paRight); + } + public: //! Indicator for invalid array member index positions static constexpr size_t csmNIndex = -1; diff --git a/src/core/iec61131_functions.h b/src/core/iec61131_functions.h index 6080e3a8..b2511b8e 100644 --- a/src/core/iec61131_functions.h +++ b/src/core/iec61131_functions.h @@ -425,7 +425,9 @@ CIEC_BOOL func_EQ(const T &paIn1, const U &paIn2, const Args& ... args) { template CIEC_BOOL func_EQ(const T &paIN1, const U &paIN2) { - if constexpr (forte::core::mpl::are_of_subtype_v) { //ANY_BITs can be also partial accesses + if constexpr (forte::core::mpl::has_equality_v) { + return CIEC_BOOL(paIN1 == paIN2); + } else if constexpr (forte::core::mpl::are_of_subtype_v) { //ANY_BITs can be also partial accesses using tTClass = typename forte::core::mpl::get_equivalent_CIEC_class_t; using tUClass = typename forte::core::mpl::get_equivalent_CIEC_class_t; using tImplicitCastType = typename forte::core::mpl::get_castable_type_t; @@ -539,7 +541,9 @@ CIEC_BOOL func_LT(const T &paIN1, const T &paIN2) { template CIEC_BOOL func_NE(const T &paIN1, const U &paIN2) { - if constexpr (forte::core::mpl::are_of_subtype_v) { //ANY_BITs can be also partial accesses + if constexpr (forte::core::mpl::has_equality_v) { + return CIEC_BOOL(paIN1 != paIN2); + } else if constexpr (forte::core::mpl::are_of_subtype_v) { //ANY_BITs can be also partial accesses using tTClass = typename forte::core::mpl::get_equivalent_CIEC_class_t; using tUClass = typename forte::core::mpl::get_equivalent_CIEC_class_t; using tImplicitCastType = typename forte::core::mpl::get_castable_type_t; diff --git a/tests/core/iec61131_functionstests.cpp b/tests/core/iec61131_functionstests.cpp index 5190d4fc..05a63bdc 100644 --- a/tests/core/iec61131_functionstests.cpp +++ b/tests/core/iec61131_functionstests.cpp @@ -52,6 +52,9 @@ class CIEC_EndianessTestStruct : public CIEC_STRUCT { CIEC_EndianessTestStruct() = default; + CIEC_EndianessTestStruct(CIEC_BOOL paVar1, CIEC_DINT paVar2, CIEC_LWORD paVar3) + : Var1(paVar1), Var2(paVar2), Var3(paVar3) {} + size_t getStructSize() const override { return 3; } @@ -438,6 +441,28 @@ BOOST_AUTO_TEST_CASE(eq_false_variadic_4) BOOST_TEST(func_EQ(number1, number2, number3, number4) == false); } +BOOST_AUTO_TEST_CASE(eq_array_fixed) +{ + CIEC_ARRAY_FIXED array1 = {17_INT, 4_INT}; + CIEC_ARRAY_FIXED array2 = {17_INT, 4_INT}; + CIEC_ARRAY_FIXED array3 = {21_INT, 42_INT}; + CIEC_ARRAY_FIXED array4 = {17_INT, 4_INT, 21_INT}; + CIEC_ARRAY_FIXED array5 = {17_DINT, 4_DINT}; + BOOST_TEST(func_EQ(array1, array2) == true); + BOOST_TEST(func_EQ(array1, array3) == false); + BOOST_TEST(func_EQ(array1, array4) == false); + BOOST_TEST(func_EQ(array1, array5) == false); +} + +BOOST_AUTO_TEST_CASE(eq_struct) +{ + CIEC_EndianessTestStruct struct1(true_BOOL, 17_DINT, 4_LWORD); + CIEC_EndianessTestStruct struct2(true_BOOL, 17_DINT, 4_LWORD); + CIEC_EndianessTestStruct struct3(true_BOOL, 21_DINT, 42_LWORD); + BOOST_TEST(func_EQ(struct1, struct2) == true); + BOOST_TEST(func_EQ(struct1, struct3) == false); +} + BOOST_AUTO_TEST_CASE(gt_true) { BOOST_TEST(func_GT(100_SINT, 90_INT) == true); } @@ -580,6 +605,28 @@ BOOST_AUTO_TEST_CASE(ne_false_mixed_types) BOOST_TEST(func_NE(nLint1, nInt2) == true); } +BOOST_AUTO_TEST_CASE(ne_array_fixed) +{ + CIEC_ARRAY_FIXED array1 = {17_INT, 4_INT}; + CIEC_ARRAY_FIXED array2 = {17_INT, 4_INT}; + CIEC_ARRAY_FIXED array3 = {21_INT, 42_INT}; + CIEC_ARRAY_FIXED array4 = {17_INT, 4_INT, 21_INT}; + CIEC_ARRAY_FIXED array5 = {17_DINT, 4_DINT}; + BOOST_TEST(func_NE(array1, array2) == false); + BOOST_TEST(func_NE(array1, array3) == true); + BOOST_TEST(func_NE(array1, array4) == true); + BOOST_TEST(func_NE(array1, array5) == true); +} + +BOOST_AUTO_TEST_CASE(ne_struct) +{ + CIEC_EndianessTestStruct struct1(true_BOOL, 17_DINT, 4_LWORD); + CIEC_EndianessTestStruct struct2(true_BOOL, 17_DINT, 4_LWORD); + CIEC_EndianessTestStruct struct3(true_BOOL, 21_DINT, 42_LWORD); + BOOST_TEST(func_NE(struct1, struct2) == false); + BOOST_TEST(func_NE(struct1, struct3) == true); +} + BOOST_AUTO_TEST_CASE(implicit_bool_casts) { bool bSame = std::is_same::type>::value;