31 #ifndef NUMCPP_NO_USE_BOOST
37 #include <type_traits>
40 #include "boost/dynamic_bitset.hpp"
46 namespace edac::detail
57 std::enable_if_t<std::is_integral_v<IntType>,
int> = 0
62 return n != 0 && (n & (n - 1)) == 0;
79 std::enable_if_t<std::is_integral_v<IntType>,
int> = 0
85 throw std::invalid_argument(
"Input value must be greater than or equal to zero.");
90 return static_cast<std::size_t
>(n) << 1;
106 std::enable_if_t<std::is_integral_v<IntType>,
int> = 0
110 auto i = std::size_t{ 0 };
111 auto power = std::size_t{ 1 };
112 auto powers = std::vector<std::size_t>();
115 while (i <
static_cast<std::size_t
>(n))
117 powers.push_back(
power);
136 std::enable_if_t<std::is_integral_v<IntType>,
int> = 0
142 const auto upperBin = lowerBin + 1;
143 const auto dataBitBoundary = n - lowerBin - 1;
144 const auto numParityBits = numDataBits <= dataBitBoundary ? lowerBin + 1 : upperBin + 1;
148 throw std::runtime_error(
"input number of data bits is not a valid Hamming SECDED code configuration.");
151 return numParityBits;
169 std::enable_if_t<std::is_integral_v<IntType1>,
int> = 0,
170 std::enable_if_t<std::is_integral_v<IntType2>,
int> = 0
176 throw std::invalid_argument(
"All hamming parity bits are indexed by powers of two.");
179 std::size_t dataIndex = 1;
180 std::size_t totalIndex = 3;
181 auto parityBit_ =
static_cast<std::size_t
>(parityBit);
183 auto indices = std::vector<std::size_t>();
184 indices.reserve(numDataBits);
186 while (dataIndex <=
static_cast<std::size_t
>(numDataBits))
188 const auto currentBitIsData = !
isPowerOfTwo(totalIndex);
189 if (currentBitIsData && (totalIndex % (parityBit_ << 1)) >= parityBit_)
191 indices.push_back(dataIndex - 1);
194 dataIndex += currentBitIsData ? 1 : 0;
208 template<std::
size_t DataBits>
212 for (std::size_t i = 0; i < DataBits - 1; ++i)
230 for (std::size_t i = 0; i < data.size() - 1; ++i)
250 std::size_t DataBits,
252 std::enable_if_t<std::is_integral_v<IntType>,
int> = 0
274 std::size_t DataBits,
275 std::size_t EncodedBits,
276 std::enable_if_t<greaterThan_v<EncodedBits, DataBits>,
int> = 0
281 if (numParityBits + DataBits != EncodedBits)
283 throw std::runtime_error(
"DataBits and EncodedBits are not consistent");
286 return numParityBits;
298 std::size_t DataBits,
299 std::size_t EncodedBits,
300 std::enable_if_t<greaterThan_v<EncodedBits, DataBits>,
int> = 0
302 std::bitset<DataBits>
extractData(
const std::bitset<EncodedBits>& encodedBits) noexcept
304 auto dataBits = std::bitset<DataBits>();
306 std::size_t dataIndex = 0;
307 for (std::size_t encodedIndex = 0; encodedIndex < EncodedBits; ++encodedIndex)
311 dataBits[dataIndex++] = encodedBits[encodedIndex];
312 if (dataIndex == DataBits)
333 template<std::
size_t DataBits>
334 boost::dynamic_bitset<>
encode(
const std::bitset<DataBits>& dataBits)
337 const auto numEncodedBits = numParityBits + DataBits;
339 auto encodedBits = boost::dynamic_bitset<>(numEncodedBits);
348 std::size_t dataBitIndex = 0;
349 for (std::size_t bitIndex = 1; bitIndex <= numEncodedBits - 1; ++bitIndex)
353 encodedBits[bitIndex - 1] = dataBits[dataBitIndex++];
376 std::size_t DataBits,
377 std::size_t EncodedBits,
378 std::enable_if_t<greaterThan_v<EncodedBits, DataBits>,
int> = 0
380 int decode(std::bitset<EncodedBits> encodedBits, std::bitset<DataBits>& decodedBits)
382 const auto numParityBits = detail::checkBitsConsistent<DataBits, EncodedBits>();
385 decodedBits = detail::extractData<DataBits>(encodedBits);
389 const auto overallActual = encodedBits[EncodedBits - 1];
390 const auto overallCorrect = overallExpected == overallActual;
393 std::size_t indexOfError = 0;
397 const auto actual = encodedBits[parityBit - 1];
398 if (expected != actual)
400 indexOfError += parityBit;
405 if (overallCorrect && indexOfError != 0)
410 else if (!overallCorrect && indexOfError != 0)
413 encodedBits.flip(indexOfError - 1);
414 decodedBits = detail::extractData<DataBits>(encodedBits);
std::bitset< DataBits > extractData(const std::bitset< EncodedBits > &encodedBits) noexcept
Definition: hammingEncode.hpp:302
std::size_t nextPowerOfTwo(IntType n)
Definition: hammingEncode.hpp:81
std::size_t numSecdedParityBitsNeeded(IntType numDataBits)
Definition: hammingEncode.hpp:138
constexpr bool isPowerOfTwo(IntType n) noexcept
Tests if value is a power of two.
Definition: hammingEncode.hpp:59
std::vector< std::size_t > dataBitsCovered(IntType1 numDataBits, IntType2 parityBit)
Definition: hammingEncode.hpp:172
constexpr bool calculateParity(const std::bitset< DataBits > &data) noexcept
Definition: hammingEncode.hpp:209
std::vector< std::size_t > powersOfTwo(IntType n)
Definition: hammingEncode.hpp:108
std::size_t checkBitsConsistent()
Definition: hammingEncode.hpp:278
int decode(std::bitset< EncodedBits > encodedBits, std::bitset< DataBits > &decodedBits)
Definition: hammingEncode.hpp:380
boost::dynamic_bitset encode(const std::bitset< DataBits > &dataBits)
Definition: hammingEncode.hpp:334
Definition: Coordinate.hpp:45
constexpr dtype power(dtype inValue, uint8 inExponent) noexcept
Definition: Functions/power.hpp:52
dtype ceil(dtype inValue) noexcept
Definition: ceil.hpp:48
auto log2(dtype inValue) noexcept
Definition: log2.hpp:49
dtype floor(dtype inValue) noexcept
Definition: floor.hpp:48