31 #ifndef NUMCPP_NO_USE_BOOST
37 #include <type_traits>
40 #include "boost/dynamic_bitset.hpp"
57 template<
typename IntType, enable_if_t<is_
integral_v<IntType>,
int> = 0>
61 return n != 0 && (n & (n - 1)) == 0;
76 template<
typename IntType, enable_if_t<is_
integral_v<IntType>,
int> = 0>
81 throw std::invalid_argument(
"Input value must be greater than or equal to zero.");
86 return static_cast<std::size_t
>(n) << 1;
100 template<
typename IntType, enable_if_t<is_
integral_v<IntType>,
int> = 0>
103 auto i = std::size_t{ 0 };
104 auto power = std::size_t{ 1 };
105 auto powers = std::vector<std::size_t>();
108 while (i <
static_cast<std::size_t
>(n))
110 powers.push_back(
power);
127 template<
typename IntType, enable_if_t<is_
integral_v<IntType>,
int> = 0>
132 const auto upperBin = lowerBin + 1;
133 const auto dataBitBoundary = n - lowerBin - 1;
134 const auto numParityBits = numDataBits <= dataBitBoundary ? lowerBin + 1 : upperBin + 1;
138 throw std::runtime_error(
139 "input number of data bits is not a valid Hamming SECDED code configuration.");
142 return numParityBits;
157 template<
typename IntType1,
165 throw std::invalid_argument(
"All hamming parity bits are indexed by powers of two.");
168 std::size_t dataIndex = 1;
169 std::size_t totalIndex = 3;
170 auto parityBit_ =
static_cast<std::size_t
>(parityBit);
172 auto indices = std::vector<std::size_t>();
173 indices.reserve(numDataBits);
175 while (dataIndex <=
static_cast<std::size_t
>(numDataBits))
177 const auto currentBitIsData = !
isPowerOfTwo(totalIndex);
178 if (currentBitIsData && (totalIndex % (parityBit_ << 1)) >= parityBit_)
180 indices.push_back(dataIndex - 1);
183 dataIndex += currentBitIsData ? 1 : 0;
197 template<std::
size_t DataBits>
201 for (std::size_t i = 0; i < DataBits - 1; ++i)
219 for (std::size_t i = 0; i < data.size() - 1; ++i)
238 template<std::
size_t DataBits,
typename IntType, enable_if_t<is_
integral_v<IntType>,
int> = 0>
258 template<std::size_t DataBits,
259 std::size_t EncodedBits,
264 if (numParityBits + DataBits != EncodedBits)
266 throw std::runtime_error(
"DataBits and EncodedBits are not consistent");
269 return numParityBits;
280 template<std::size_t DataBits,
281 std::size_t EncodedBits,
283 std::bitset<DataBits>
extractData(
const std::bitset<EncodedBits>& encodedBits) noexcept
285 auto dataBits = std::bitset<DataBits>();
287 std::size_t dataIndex = 0;
288 for (std::size_t encodedIndex = 0; encodedIndex < EncodedBits; ++encodedIndex)
292 dataBits[dataIndex++] = encodedBits[encodedIndex];
293 if (dataIndex == DataBits)
312 template<std::
size_t DataBits>
313 boost::dynamic_bitset<>
encode(
const std::bitset<DataBits>& dataBits)
316 const auto numEncodedBits = numParityBits + DataBits;
318 auto encodedBits = boost::dynamic_bitset<>(numEncodedBits);
328 std::size_t dataBitIndex = 0;
329 for (std::size_t bitIndex = 1; bitIndex <= numEncodedBits - 1;
334 encodedBits[bitIndex - 1] = dataBits[dataBitIndex++];
356 template<std::size_t DataBits,
357 std::size_t EncodedBits,
359 int decode(std::bitset<EncodedBits> encodedBits, std::bitset<DataBits>& decodedBits)
361 const auto numParityBits = detail::checkBitsConsistent<DataBits, EncodedBits>();
364 decodedBits = detail::extractData<DataBits>(encodedBits);
368 const auto overallActual = encodedBits[EncodedBits - 1];
369 const auto overallCorrect = overallExpected == overallActual;
372 std::size_t indexOfError = 0;
376 const auto actual = encodedBits[parityBit - 1];
377 if (expected != actual)
379 indexOfError += parityBit;
384 if (overallCorrect && indexOfError != 0)
389 else if (!overallCorrect && indexOfError != 0)
392 encodedBits.flip(indexOfError - 1);
393 decodedBits = detail::extractData<DataBits>(encodedBits);
std::bitset< DataBits > extractData(const std::bitset< EncodedBits > &encodedBits) noexcept
Definition: hammingEncode.hpp:283
std::size_t nextPowerOfTwo(IntType n)
Definition: hammingEncode.hpp:77
std::size_t numSecdedParityBitsNeeded(IntType numDataBits)
Definition: hammingEncode.hpp:128
constexpr bool isPowerOfTwo(IntType n) noexcept
Tests if value is a power of two.
Definition: hammingEncode.hpp:58
std::vector< std::size_t > dataBitsCovered(IntType1 numDataBits, IntType2 parityBit)
Definition: hammingEncode.hpp:161
constexpr bool calculateParity(const std::bitset< DataBits > &data) noexcept
Definition: hammingEncode.hpp:198
std::vector< std::size_t > powersOfTwo(IntType n)
Definition: hammingEncode.hpp:101
std::size_t checkBitsConsistent()
Definition: hammingEncode.hpp:261
int decode(std::bitset< EncodedBits > encodedBits, std::bitset< DataBits > &decodedBits)
Definition: hammingEncode.hpp:359
boost::dynamic_bitset encode(const std::bitset< DataBits > &dataBits)
Definition: hammingEncode.hpp:313
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
typename std::enable_if< B, T >::type enable_if_t
Definition: TypeTraits.hpp:40