summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/coretmpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/coretmpl.h')
-rw-r--r--src/lib/util/coretmpl.h106
1 files changed, 95 insertions, 11 deletions
diff --git a/src/lib/util/coretmpl.h b/src/lib/util/coretmpl.h
index 8b6bafa30fb..95d8230f565 100644
--- a/src/lib/util/coretmpl.h
+++ b/src/lib/util/coretmpl.h
@@ -32,15 +32,6 @@
#include <utility>
#include <vector>
-// Generate a N-bit mask at compile time. N better be constant.
-// Works even for signed types
-
-template<typename T> constexpr T make_bitmask(unsigned int N)
-{
- return T((N < (8 * sizeof(T)) ? (std::make_unsigned_t<T>(1) << N) : std::make_unsigned_t<T>(0)) - 1);
-}
-
-
// ======================> simple_list
// a simple_list is a singly-linked list whose 'next' pointer is owned
@@ -939,17 +930,108 @@ constexpr typename std::enable_if_t<std::is_enum<E>::value && std::is_integral<T
}
-// useful functions to deal with bit shuffling
+/// \defgroup bitutils Useful functions for bit shuffling
+/// \{
+
+/// \brief Generate a right-aligned bit mask
+///
+/// Generates a right aligned mask of the specified width. Works with
+/// signed and unsigned integer types.
+/// \tparam T Desired output type.
+/// \tparam U Type of the input (generally resolved by the compiler).
+/// \param [in] n Width of the mask to generate in bits.
+/// \return Right-aligned mask of the specified width.
+
+template <typename T, typename U> constexpr T make_bitmask(U n)
+{
+ return T((n < (8 * sizeof(T)) ? (std::make_unsigned_t<T>(1) << n) : std::make_unsigned_t<T>(0)) - 1);
+}
+
+
+/// \brief Extract a single bit from an integer
+///
+/// Extracts a single bit from an integer into the least significant bit
+/// position.
+///
+/// \param [in] x The integer to extract the bit from.
+/// \param [in] n The bit to extract, where zero is the least
+/// significant bit of the input.
+/// \return Zero if the specified bit is unset, or one if it is set.
+/// \sa bitswap
template <typename T, typename U> constexpr T BIT(T x, U n) noexcept { return (x >> n) & T(1); }
+
+/// \brief Extract a bit field from an integer
+///
+/// Extracts and right-aligns a bit field from an integer.
+///
+/// \param [in] x The integer to extract the bit field from.
+/// \param [in] n The least significant bit position of the field to
+/// extract, where zero is the least significant bit of the input.
+/// \param [in] w The width of the field to extract in bits.
+/// \return The field [n..(n+w-1)] from the input.
+/// \sa bitswap
+template <typename T, typename U, typename V> constexpr T BIT(T x, U n, V w)
+{
+ return (x >> n) & make_bitmask<T>(w);
+}
+
+
+/// \brief Extract and right-align a single bit field
+///
+/// This overload is used to terminate a recursive template
+/// implementation. It is functionally equivalent to the BIT
+/// function for extracting a single bit.
+///
+/// \param [in] val The integer to extract the bit from.
+/// \param [in] b The bit to extract, where zero is the least
+/// significant bit of the input.
+/// \return The specified bit of the input extracted to the least
+/// significant position.
template <typename T, typename U> constexpr T bitswap(T val, U b) noexcept { return BIT(val, b) << 0U; }
+
+/// \brief Extract bits in arbitrary order
+///
+/// Extracts bits from an integer. Specify the bits in the order they
+/// should be arranged in the output, from most significant to least
+/// significant. The extracted bits will be packed into a right-aligned
+/// field in the output.
+///
+/// \param [in] val The integer to extract bits from.
+/// \param [in] b The first bit to extract from the input
+/// extract, where zero is the least significant bit of the input.
+/// This bit will appear in the most significant position of the
+/// right-aligned output field.
+/// \param [in] c The remaining bits to extract, where zero is the
+/// least significant bit of the input.
+/// \return The extracted bits packed into a right-aligned field.
template <typename T, typename U, typename... V> constexpr T bitswap(T val, U b, V... c) noexcept
{
return (BIT(val, b) << sizeof...(c)) | bitswap(val, c...);
}
-// explicit version that checks number of bit position arguments
+
+/// \brief Extract bits in arbitrary order with explicit count
+///
+/// Extracts bits from an integer. Specify the bits in the order they
+/// should be arranged in the output, from most significant to least
+/// significant. The extracted bits will be packed into a right-aligned
+/// field in the output. The number of bits to extract must be supplied
+/// as a template argument.
+///
+/// A compile error will be generated if the number of bit positions
+/// supplied does not match the specified number of bits to extract, or
+/// if the output type is too small to hold the extracted bits. This
+/// guards against some simple errors.
+///
+/// \tparam B The number of bits to extract. Must match the number of
+/// bit positions supplied.
+/// \param [in] val The integer to extract bits from.
+/// \param [in] b Bits to extract, where zero is the least significant
+/// bit of the input. Specify bits in the order they should appear in
+/// the output field, from most significant to least significant.
+/// \return The extracted bits packed into a right-aligned field.
template <unsigned B, typename T, typename... U> T bitswap(T val, U... b) noexcept
{
static_assert(sizeof...(b) == B, "wrong number of bits");
@@ -957,6 +1039,8 @@ template <unsigned B, typename T, typename... U> T bitswap(T val, U... b) noexce
return bitswap(val, b...);
}
+/// \}
+
// constexpr absolute value of an integer
template <typename T>