Skip to content

Commit

Permalink
Add const partial access
Browse files Browse the repository at this point in the history
Add partial access for const values, which directly returns the partial
type and avoids the temporary accessor object altogether.
  • Loading branch information
mx990 authored and azoitl committed Mar 21, 2024
1 parent b67458c commit 8289181
Show file tree
Hide file tree
Showing 9 changed files with 418 additions and 20 deletions.
13 changes: 9 additions & 4 deletions src/core/datatypes/forte_any_bit_partial.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<SourceValueType>(paValue);
if constexpr(std::is_same_v<CIEC_BOOL, PartialType>) {
partialValue = static_cast<PartialValueType>((sourceValue >> shiftIndex) & 0x1);
Expand All @@ -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) {
Expand All @@ -55,8 +59,9 @@ class CIEC_ANY_BIT_PARTIAL final : public PartialType {
if(mIndex <= scmMaxIndex) {
constexpr SourceValueType maskTemplate = std::numeric_limits<PartialValueType>::max();
const auto shiftIndex = mIndex * scmPartialDigits;
const SourceValueType mask = (maskTemplate << shiftIndex);
const SourceValueType partialPartValue = static_cast<SourceValueType>(static_cast<PartialValueType>(*this)) << shiftIndex;
const SourceValueType mask = static_cast<SourceValueType>(maskTemplate << shiftIndex);
const SourceValueType partialPartValue = static_cast<SourceValueType>(
static_cast<SourceValueType>(static_cast<PartialValueType>(*this)) << shiftIndex);
const SourceValueType sourceValue = static_cast<SourceValueType>(mOriginalValue);
SourceValueType mergedValue = sourceValue ^ ((sourceValue ^ partialPartValue) & mask);
mOriginalValue = SourceType(mergedValue);
Expand Down
29 changes: 25 additions & 4 deletions src/core/datatypes/forte_byte.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,34 @@ class CIEC_BYTE : public CIEC_ANY_BIT{
/*! \brief Partial access within a CIEC_BYTE (e.g. [BYTE].partial<CIEC_BOOL,1>())
*
*/
template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE> partial(size_t paIndex){
template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE> partial(size_t paIndex) {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE>(*this, paIndex);
}

template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE> partial(const CIEC_ANY_INT& paIndex){
size_t index = paIndex.getUnsignedValue();
return CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE>(*this, index);
template<class T>
T partial(size_t paIndex) const {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE>::partialValue(*this, paIndex);
}

template<class T>
T cpartial(size_t paIndex) const {
return partial<T>(paIndex);
}

template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_BYTE> partial(const CIEC_ANY_INT &paIndex) {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T partial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T cpartial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex);
}
};

Expand Down
29 changes: 25 additions & 4 deletions src/core/datatypes/forte_dword.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,34 @@ class CIEC_DWORD : public CIEC_ANY_BIT {
/*! \brief Partial access within a CIEC_DWORD (e.g. [DWORD].partial<CIEC_BOOL>(1))
*
*/
template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD> partial(size_t paIndex) {
template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD> partial(size_t paIndex) {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD>(*this, paIndex);
}

template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD> partial(const CIEC_ANY_INT& paIndex){
size_t index = paIndex.getUnsignedValue();
return CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD>(*this, index);
template<class T>
T partial(size_t paIndex) const {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD>::partialValue(*this, paIndex);
}

template<class T>
T cpartial(size_t paIndex) const {
return partial<T>(paIndex);
}

template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_DWORD> partial(const CIEC_ANY_INT &paIndex) {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T partial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T cpartial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex);
}
};

Expand Down
28 changes: 24 additions & 4 deletions src/core/datatypes/forte_lword.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,35 @@ class CIEC_LWORD : public CIEC_ANY_BIT{
/*! \brief Partial access within a CIEC_LWORD (e.g. [LWORD].partial<CIEC_BOOL>(1))
*
*/
template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD> partial(size_t paIndex){
template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD> partial(size_t paIndex) {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD>(*this, paIndex);
}

template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD> partial(const CIEC_ANY_INT& paIndex){
size_t index = paIndex.getUnsignedValue();
return CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD>(*this, index);
template<class T>
T partial(size_t paIndex) const {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD>::partialValue(*this, paIndex);
}

template<class T>
T cpartial(size_t paIndex) const {
return partial<T>(paIndex);
}

template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_LWORD> partial(const CIEC_ANY_INT &paIndex) {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T partial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T cpartial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex);
}
};

inline CIEC_LWORD operator ""_LWORD(unsigned long long int paValue) {
Expand Down
29 changes: 25 additions & 4 deletions src/core/datatypes/forte_word.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,34 @@ class CIEC_WORD : public CIEC_ANY_BIT{
/*! \brief Partial access within a CIEC_WORD (e.g. [WORD].partial<CIEC_BOOL>(1))
*
*/
template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD> partial(size_t paIndex) {
template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD> partial(size_t paIndex) {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD>(*this, paIndex);
}

template <class T> CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD> partial(const CIEC_ANY_INT& paIndex){
size_t index = paIndex.getUnsignedValue();
return CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD>(*this, index);
template<class T>
T partial(size_t paIndex) const {
return CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD>::partialValue(*this, paIndex);
}

template<class T>
T cpartial(size_t paIndex) const {
return partial<T>(paIndex);
}

template<class T>
CIEC_ANY_BIT_PARTIAL<T, CIEC_WORD> partial(const CIEC_ANY_INT &paIndex) {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T partial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex.getUnsignedValue());
}

template<class T>
T cpartial(const CIEC_ANY_INT &paIndex) const {
return partial<T>(paIndex);
}
};

Expand Down
26 changes: 26 additions & 0 deletions tests/core/datatypes/CIEC_PARTIAL/CIEC_BYTE_PARTIAL_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -66,13 +72,27 @@ 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);
test4X_A(nTestByte,0);

}

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);
Expand Down Expand Up @@ -193,6 +213,12 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESSOUT_OF_INDEX_ACCESS) {
BOOST_TEST(static_cast<CIEC_BOOL::TValueType>(nByte.partial<CIEC_BOOL>(CIEC_SINT(8))) == false);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_TO_SAME_PARTIAL) {
CIEC_BYTE nByte(0x02U);
nByte.partial<CIEC_BOOL>(CIEC_SINT(0)) = CIEC_BOOL(nByte.cpartial<CIEC_BOOL>(CIEC_SINT(0)) || true);
BOOST_TEST(static_cast<CIEC_BYTE::TValueType>(nByte) == 0x03U);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_TO_OTHER_PARTIAL) {
CIEC_BYTE nByte(0x01U);
nByte.partial<CIEC_BOOL>(CIEC_SINT(1)) = nByte.partial<CIEC_BOOL>(CIEC_SINT(0));
Expand Down
91 changes: 91 additions & 0 deletions tests/core/datatypes/CIEC_PARTIAL/CIEC_DWORD_PARTIAL_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<CIEC_BYTE>(0)),0);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(1)),0);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(2)),0);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(3)),0);

}

BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_WORD)
{
CIEC_DWORD nTestDWord;
Expand All @@ -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<CIEC_WORD>(0)),0);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_WORD>(1)),0);

}

BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_INITVALUES_CHECK_DWORD)
{
CIEC_DWORD nTestDWord;
Expand Down Expand Up @@ -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;
Expand All @@ -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<CIEC_BYTE>(0)), 0xBE);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(1)), 0xBA);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(2)), 0xFE);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_BYTE>(3)), 0xCA);

}

BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_WORD)
{
CIEC_DWORD nTestDWord;
Expand All @@ -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<CIEC_WORD>(0)), 0xBABE);
BOOST_CHECK_EQUAL((nTestDWord.partial<CIEC_WORD>(1)), 0xCAFE);

}

BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_DWORD_VALUE_CHECK_DWORD)
{
CIEC_DWORD nTestDWord;
Expand Down Expand Up @@ -1218,6 +1289,26 @@ BOOST_AUTO_TEST_CASE(PARTIAL_ACCESS_WRITE_WITH_IEC_TYPE_INDEX)
BOOST_TEST(static_cast<CIEC_DWORD::TValueType>(nDWord) == 3U);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_SAME_PARTIAL_BOOL) {
CIEC_DWORD nDWord(0x00000002U);
nDWord.partial<CIEC_BOOL>(CIEC_SINT(0)) = CIEC_BOOL(nDWord.cpartial<CIEC_BOOL>(CIEC_SINT(0)) || true);
BOOST_TEST(static_cast<CIEC_DWORD::TValueType>(nDWord) == 0x03U);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BYTE_TO_SAME_PARTIAL_BYTE) {
CIEC_DWORD nDWord(0xABCDEFFEU);
nDWord.partial<CIEC_BYTE>(CIEC_SINT(0)) = CIEC_BYTE(
static_cast<CIEC_BYTE::TValueType>(nDWord.cpartial<CIEC_BYTE>(CIEC_SINT(0))) | 0x01);
BOOST_TEST(static_cast<CIEC_DWORD::TValueType>(nDWord) == 0xABCDEFFFU);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_WORD_TO_SAME_PARTIAL_WORD) {
CIEC_DWORD nDWord(0xABCDEFFEU);
nDWord.partial<CIEC_WORD>(CIEC_SINT(0)) = CIEC_WORD(
static_cast<CIEC_WORD::TValueType>(nDWord.cpartial<CIEC_WORD>(CIEC_SINT(0))) | 0x1001);
BOOST_TEST(static_cast<CIEC_DWORD::TValueType>(nDWord) == 0xABCDFFFFU);
}

BOOST_AUTO_TEST_CASE(PARTIAL_COPY_PARTIAL_BOOL_TO_OTHER_PARTIAL_BOOL) {
CIEC_DWORD nDWord(0x00000001U);
nDWord.partial<CIEC_BOOL>(CIEC_SINT(1)) = nDWord.partial<CIEC_BOOL>(CIEC_SINT(0));
Expand Down
Loading

0 comments on commit 8289181

Please sign in to comment.