From 2ab4104fcaa57d8944276c6079b60fbc942d3630 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 5 Oct 2026 11:17:20 -0700 Subject: [PATCH] [bit-utils] replace `BytesForBitSize()` macro with `constexpr` template (#13671) This commit replaces the `BytesForBitSize()` macro with a `constexpr` function template parameterized by `UintType`. This provides compile-time type checking (ensuring `UintType` is an unsigned integer) and avoids truncating the result to `uint8_t` when used with larger bit sizes (such as `uint16_t` in `BitSet`). --- src/core/common/bit_set.hpp | 2 +- src/core/common/bit_utils.hpp | 9 ++++++++- src/core/thread/lowpan.cpp | 2 +- src/core/thread/mle_types.hpp | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/core/common/bit_set.hpp b/src/core/common/bit_set.hpp index baf907e94..4d0cfc15e 100644 --- a/src/core/common/bit_set.hpp +++ b/src/core/common/bit_set.hpp @@ -247,7 +247,7 @@ public: } private: - static constexpr uint16_t kMaskSize = BytesForBitSize(kNumBits); + static constexpr uint16_t kMaskSize = BytesForBitSize(kNumBits); uint8_t mMask[kMaskSize]; }; diff --git a/src/core/common/bit_utils.hpp b/src/core/common/bit_utils.hpp index 582aaae43..ae0857da4 100644 --- a/src/core/common/bit_utils.hpp +++ b/src/core/common/bit_utils.hpp @@ -54,11 +54,18 @@ static constexpr uint8_t kBitsPerByte = 8; ///< Number of bits in a byte. /** * Determines number of bytes to represent a given number of bits. * + * @tparam UintType The value type (MUST be `uint8_t`, `uint16_t`, `uint32_t`, or `uint64_t`). + * * @param[in] aBitSize The bit-size (number of bits). * * @returns Number of bytes to represent @p aBitSize. */ -#define BytesForBitSize(aBitSize) static_cast(((aBitSize) + (kBitsPerByte - 1)) / kBitsPerByte) +template constexpr UintType BytesForBitSize(UintType aBitSize) +{ + static_assert(TypeTraits::IsUint::kValue, "UintType must be an unsigned int (8, 16, 32, or 64 bit len)"); + + return ((aBitSize + (kBitsPerByte - 1)) / kBitsPerByte); +} /** * Counts the number of `1` bits in the binary representation of a given `uint32_t` bit-mask value. diff --git a/src/core/thread/lowpan.cpp b/src/core/thread/lowpan.cpp index 56f201380..e9df61447 100644 --- a/src/core/thread/lowpan.cpp +++ b/src/core/thread/lowpan.cpp @@ -861,7 +861,7 @@ Error Lowpan::Decompressor::DecompressExtensionHeader(void) } // length - hdr[1] = BytesForBitSize(sizeof(hdr) + len) - 1; + hdr[1] = BytesForBitSize(sizeof(hdr) + len) - 1; SuccessOrExit(mMessage.AppendBytes(hdr, sizeof(hdr))); mMessage.MoveOffset(sizeof(hdr)); diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index ee218d527..cb5df68fb 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -627,7 +627,7 @@ public: /** * The size of the Router ID mask in bytes. */ - static constexpr uint8_t kMaskSize = BytesForBitSize(kMaxRouterId + 1); + static constexpr uint8_t kMaskSize = BytesForBitSize(kMaxRouterId + 1); /** * Indicates whether or not the mask is valid (count of allocated Router IDs is within the limit).