Core module
Small, generally-useful functions and types.
Modules
- module Metafunctions and type traits
- Type traits and metaprogramming utilities.
Classes
-
template <typename First, typename Second>class muu::compressed_pair
- A pair that uses Empty Base Class Optimization to elide storage for one or both of its members where possible.
- struct muu::half
- A 16-bit "half-precision" IEEE754 floating point type.
-
template <typename T>struct muu::integral_range
- A half-open range of integral values (ints, enums, pointers).
-
template <typename T>class muu::scope_fail
- Performs actions when going out of scope due to an exception being thrown.
-
template <typename T>class muu::scope_guard
- Performs actions when going out of scope.
-
template <typename T>class muu::scope_success
- Performs actions when going out of scope only if no exceptions have been thrown.
-
template <typename T, size_t Extent = dynamic_class muu::span
extent, size_t Alignment = 0> - A non-owning view of contiguous elements.
-
template <typename ValueType, typename Tag, template<typename> typename... Traits>struct muu::strong_typedef
- A utility class for creating 'strong typedefs'.
-
template <typename T, size_t Align = impl::tptr_min_align<T>>class muu::tagged_ptr
- Specialized pointer capable of storing data in the unused bits of a pointer's value.
- struct muu::uuid
- A 128-bit universally-unique identifier (UUID).
Typedefs
-
using byteptr_range = integral_range<std::
byte*> - Convenience alias for
integral_
.range<std:: byte*> - using float128_t = __float128
- A 128-bit quad-precision float.
- using index_range = integral_range<size_t>
- Convenience alias for
integral_
.range<size_t> - using int128_t = __int128_t
- A 128-bit signed integer.
- using intptr_range = integral_range<intptr_t>
- Convenience alias for
integral_
.range<intptr_t> - using uint128_t = __uint128_t
- A 128-bit unsigned integer.
- using uintptr_range = integral_range<uintptr_t>
- Convenience alias for
integral_
.range<uintptr_t>
Functions
- auto aligned_alloc(size_t size, size_t alignment) -> void* noexcept
- Allocates memory on a specific alignment boundary.
- void aligned_free(void* ptr) noexcept
- Frees memory that was allocated using muu::
aligned_alloc(). -
template <size_t Alignment, typename T>auto apply_alignment(T val) -> T constexpr noexcept
- Rounds an unsigned value up to the next multiple of the given alignment.
-
template <size_t Alignment, typename T>auto apply_alignment(T* ptr) -> T* constexpr noexcept
- Rounds a pointer up to the byte offset that is the next multiple of the given alignment.
-
template <typename T>auto apply_alignment(T val, size_t alignment) -> T constexpr noexcept
- Rounds an unsigned value up to the next multiple of the given alignment.
-
template <typename T>auto apply_alignment(T* ptr, size_t alignment) -> T* constexpr noexcept
- Rounds a pointer up to the byte offset that is the next multiple of the given alignment.
-
template <typename T, typename Offset>auto apply_offset(T* ptr, Offset offset) -> T* constexpr noexcept
- Applies a byte offset to a pointer.
-
template <size_t N, typename T>auto assume_aligned(T* ptr) -> T* constexpr noexcept
- Equivalent to C++20's std::assume_aligned.
-
template <typename T, typename U>auto between(const T& val, const U& low, const U& high) -> bool constexpr noexcept
- Returns true if a value is between two bounds (inclusive).
-
template <typename To, typename From>auto bit_cast(const From& from) -> To constexpr noexcept
- Equivalent to C++20's std::bit_cast.
-
template <typename T>auto bit_ceil(T val) -> T constexpr noexcept
- Finds the smallest integral power of two not less than the given value.
-
template <typename T>auto bit_fill_left(size_t count) -> T constexpr noexcept
- Returns an unsigned integer filled from the left with the desired number of consecutive ones.
-
template <typename T>auto bit_fill_right(size_t count) -> T constexpr noexcept
- Returns an unsigned integer filled from the right with the desired number of consecutive ones.
-
template <typename T>auto bit_floor(T val) -> T constexpr noexcept
- Finds the largest integral power of two not greater than the given value.
-
template <typename Return = void, typename T, typename U, typename... V>auto bit_pack(T val1, U val2, V... vals) -> auto constexpr noexcept
- Bitwise-packs integers left-to-right into a larger integer.
-
template <typename T>auto bit_width(T val) -> T constexpr noexcept
- Finds the smallest number of bits needed to represent the given value.
-
template <typename T>auto byte_reverse(T val) -> T constexpr noexcept
- Reverses the byte order of an unsigned integral type.
-
template <size_t Index, typename T>auto byte_select(T val) -> uint8_t constexpr noexcept
- Gets a specific byte from an integer.
-
template <typename T>auto byte_select(T val, size_t index) -> uint8_t constexpr noexcept
- Gets a specific byte from an integer.
-
template <typename T>auto clamp(const T& val, const T& low, const T& high) -> const T& constexpr noexcept
- Returns a value clamped between two bounds (inclusive).
-
template <typename T>auto countl_one(T val) -> int constexpr noexcept
- Counts the number of consecutive 1 bits, starting from the left.
-
template <typename T>auto countl_zero(T val) -> int constexpr noexcept
- Counts the number of consecutive 0 bits, starting from the left.
-
template <typename T>auto countr_one(T val) -> int constexpr noexcept
- Counts the number of consecutive 1 bits, starting from the right.
-
template <typename T>auto countr_zero(T val) -> int constexpr noexcept
- Counts the number of consecutive 0 bits, starting from the right.
-
template <auto N1, auto N2, typename Func>void for_product(Func&& func) constexpr noexcept(…)
- Generates a series of sequential function calls by pack expansion.
-
template <auto N, typename Func>void for_sequence(Func&& func) constexpr noexcept(…)
- Generates a series of sequential function calls by pack expansion.
-
template <typename T>auto has_single_bit(T val) -> bool constexpr noexcept
- Checks if an integral value has only a single bit set.
- auto is_constant_evaluated() -> bool constexpr noexcept
- Equivalent to C++20's std::is_constant_evaluated.
-
template <class T>auto launder(T* ptr) -> T* constexpr noexcept
- Equivalent to C++17's std::launder.
-
template <typename T, typename... U>auto max(const T& val1, const T& val2, const U&... vals) -> const T& constexpr noexcept
- Returns the maximum of two or more values.
-
template <typename T, typename... U>auto min(const T& val1, const T& val2, const U&... vals) -> const T& constexpr noexcept
- Returns the minimum of two or more values.
-
template <typename To, typename From>auto pointer_cast(From from) -> To constexpr noexcept
- Casts between pointers, choosing the most appropriate conversion path.
-
template <typename T>auto popcount(T val) -> int constexpr noexcept
- Counts the number of set bits (the 'population count') of an unsigned integer.
-
template <typename F, typename S>void swap(compressed_pair<F, S>& lhs, compressed_pair<F, S>& rhs) noexcept(…)
- Swaps two compressed pairs.
-
template <size_t... ByteIndices, typename T>auto swizzle(T val) -> auto constexpr noexcept
- Select and re-pack arbitrary bytes from an integer.
-
template <typename T>auto to_address(T* p) -> T* constexpr noexcept
- Obtain the address represented by p without forming a reference to the pointee.
-
template <typename Ptr>auto to_address(const Ptr& p) -> auto constexpr noexcept
- Obtain the address represented by p without forming a reference to the pointee.
-
template <typename T>auto unwrap(T val) -> std::
underlying_type_t<T> constexpr noexcept - Unwraps an enum to it's raw integer equivalent.
Typedef documentation
using byteptr_range = integral_range<std:: byte*>
#include <muu/integral_range.h>
Convenience alias for integral_
.
using float128_t = __float128
#include <muu/fwd.h>
A 128-bit quad-precision float.
using index_range = integral_range<size_t>
#include <muu/integral_range.h>
Convenience alias for integral_
.
using int128_t = __int128_t
#include <muu/fwd.h>
A 128-bit signed integer.
using intptr_range = integral_range<intptr_t>
#include <muu/integral_range.h>
Convenience alias for integral_
.
using uint128_t = __uint128_t
#include <muu/fwd.h>
A 128-bit unsigned integer.
using uintptr_range = integral_range<uintptr_t>
#include <muu/integral_range.h>
Convenience alias for integral_
.
Function documentation
void* aligned_alloc(size_t size,
size_t alignment) noexcept
#include <muu/aligned_alloc.h>
Allocates memory on a specific alignment boundary.
void aligned_free(void* ptr) noexcept
#include <muu/aligned_alloc.h>
Frees memory that was allocated using muu::
#include <muu/apply_alignment.h>
template <size_t Alignment, typename T>
T apply_alignment(T val) constexpr noexcept
Rounds an unsigned value up to the next multiple of the given alignment.
Template parameters | |
---|---|
Alignment | The alignment to round up to. Must be a power of two. |
T | An unsigned integer or enum type. |
Parameters | |
val | The unsigned value being aligned. |
#include <muu/apply_alignment.h>
template <size_t Alignment, typename T>
T* apply_alignment(T* ptr) constexpr noexcept
Rounds a pointer up to the byte offset that is the next multiple of the given alignment.
Template parameters | |
---|---|
Alignment | The alignment to round up to. Must be a power of two. |
T | An object type (or void). |
Parameters | |
ptr | The pointer being aligned. |
#include <muu/apply_alignment.h>
template <typename T>
T apply_alignment(T val,
size_t alignment) constexpr noexcept
Rounds an unsigned value up to the next multiple of the given alignment.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The unsigned value being aligned. |
alignment | The alignment to round up to. Must be a power of two. |
#include <muu/apply_alignment.h>
template <typename T>
T* apply_alignment(T* ptr,
size_t alignment) constexpr noexcept
Rounds a pointer up to the byte offset that is the next multiple of the given alignment.
Template parameters | |
---|---|
T | An object type (or void). |
Parameters | |
ptr | The pointer being aligned. |
alignment | The alignment to round up to. Must be a power of two. |
#include <muu/core.h>
template <typename T, typename Offset>
T* apply_offset(T* ptr,
Offset offset) constexpr noexcept
Applies a byte offset to a pointer.
Template parameters | |
---|---|
T | The type being pointed to. |
Offset | An integer type. |
Parameters | |
ptr | The pointer to offset. |
offset | The number of bytes to add to the pointer's address. |
Returns | The cv-correct equivalent of (T*)((std:: . |
#include <muu/assume_aligned.h>
template <size_t N, typename T>
T* assume_aligned(T* ptr) constexpr noexcept
Equivalent to C++20's std::assume_aligned.
#include <muu/core.h>
template <typename T, typename U>
bool between(const T& val,
const U& low,
const U& high) constexpr noexcept
Returns true if a value is between two bounds (inclusive).
#include <muu/bit_cast.h>
template <typename To, typename From>
To bit_cast(const From& from) constexpr noexcept
Equivalent to C++20's std::bit_cast.
#include <muu/bit_ceil.h>
template <typename T>
T bit_ceil(T val) constexpr noexcept
Finds the smallest integral power of two not less than the given value.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The input value. |
Returns | The smallest integral power of two that is not smaller than val . |
#include <muu/bit_fill.h>
template <typename T>
T bit_fill_left(size_t count) constexpr noexcept
Returns an unsigned integer filled from the left with the desired number of consecutive ones.
Template parameters | |
---|---|
T | An unsigned integer type. |
Parameters | |
count | Number of consecutive ones. |
Returns | An instance of T left-filled with the desired number of ones. |
const auto val1 = bit_fill_left<uint32_t>(5); const auto val2 = 0b11111000000000000000000000000000u; assert(val1 == val2);
#include <muu/bit_fill.h>
template <typename T>
T bit_fill_right(size_t count) constexpr noexcept
Returns an unsigned integer filled from the right with the desired number of consecutive ones.
Template parameters | |
---|---|
T | An unsigned integer type. |
Parameters | |
count | Number of consecutive ones. |
Returns | An instance of T right-filled with the desired number of ones. |
const auto val1 = bit_fill_right<uint32_t>(5); const auto val2 = 0b00000000000000000000000000011111u; assert(val1 == val2);
#include <muu/bit_floor.h>
template <typename T>
T bit_floor(T val) constexpr noexcept
Finds the largest integral power of two not greater than the given value.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The input value. |
Returns | Zero if val is zero; otherwise, the largest integral power of two that is not greater than val . |
#include <muu/bit_pack.h>
template <typename Return = void, typename T, typename U, typename... V>
auto bit_pack(T val1,
U val2,
V... vals) constexpr noexcept
Bitwise-packs integers left-to-right into a larger integer.
Template parameters | |
---|---|
Return | An integer or enum type, or leave as void to choose an unsigned type based on the total size of the inputs. |
T | An integer or enum type. |
U | An integer or enum type. |
V | Integer or enum types. |
Parameters | |
val1 | The left-most value to be packed. |
val2 | The second-left-most value to be packed. |
vals | Any remaining values to be packed. |
Returns | An integral value containing the input values packed bitwise left-to-right. If the total size of the inputs was less than the return type, the output will be zero-padded on the left. |
auto val1 = bit_pack(0xAABB_u16, 0xCCDD_u16); assert(val1 == 0xAABBCCDD_u32); auto val2 = bit_pack(0xAABB_u16, 0xCCDD_u16, 0xEEFF_u16); assert(val2 == 0x0000AABBCCDDEEFF_u64); // ^^^^ input was 48 bits, zero-padded to 64 on the left
#include <muu/bit.h>
template <typename T>
T bit_width(T val) constexpr noexcept
Finds the smallest number of bits needed to represent the given value.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The input value. |
Returns | If val is not zero, calculates the number of bits needed to store val (i.e. 1 + log2(x) ). Returns 0 if val is zero. |
#include <muu/byte_reverse.h>
template <typename T>
T byte_reverse(T val) constexpr noexcept
Reverses the byte order of an unsigned integral type.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | An unsigned integer or enum value. |
Returns | A copy of the input value with the byte order reversed. |
const auto i = 0xAABBCCDDu; const auto j = byte_reverse(i); std::cout << std::hex << i << "\n" << j;
AABBCCDD DDCCBBAA
#include <muu/bit.h>
template <size_t Index, typename T>
uint8_t byte_select(T val) constexpr noexcept
Gets a specific byte from an integer.
Template parameters | |
---|---|
Index | Index of the byte to retrieve. |
T | An integer or enum type. |
Parameters | |
val | An integer or enum value. |
Returns | The value of the selected byte. |
const auto i = 0xAABBCCDDu; // ^ ^ ^ ^ // byte indices: 3 2 1 0 std::cout << std::hex; std::cout << "0: " << byte_select<0>(i) << "\n"; std::cout << "1: " << byte_select<1>(i) << "\n"; std::cout << "2: " << byte_select<2>(i) << "\n"; std::cout << "3: " << byte_select<3>(i) << "\n";
0: DD 1: CC 2: BB 3: AA (on a little-endian system)
#include <muu/bit.h>
template <typename T>
uint8_t byte_select(T val,
size_t index) constexpr noexcept
Gets a specific byte from an integer.
Template parameters | |
---|---|
T | An integer or enum type. |
Parameters | |
val | An integer or enum value. |
index | Index of the byte to retrieve. |
Returns | The value of the selected byte, or 0 if the index was out-of-range. |
const auto i = 0xAABBCCDDu; // ^ ^ ^ ^ // byte indices: 3 2 1 0 std::cout << std::hex; std::cout << "0: " << byte_select(i, 0) << "\n"; std::cout << "1: " << byte_select(i, 1) << "\n"; std::cout << "2: " << byte_select(i, 2) << "\n"; std::cout << "3: " << byte_select(i, 3) << "\n";
0: DD 1: CC 2: BB 3: AA (on a little-endian system)
#include <muu/core.h>
template <typename T>
const T& clamp(const T& val,
const T& low,
const T& high) constexpr noexcept
Returns a value clamped between two bounds (inclusive).
#include <muu/countl.h>
template <typename T>
int countl_one(T val) constexpr noexcept
Counts the number of consecutive 1 bits, starting from the left.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The value to test. |
Returns | The number of consecutive ones from the left end of an integer's bits. |
#include <muu/countl.h>
template <typename T>
int countl_zero(T val) constexpr noexcept
Counts the number of consecutive 0 bits, starting from the left.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The value to test. |
Returns | The number of consecutive zeros from the left end of an integer's bits. |
#include <muu/countr.h>
template <typename T>
int countr_one(T val) constexpr noexcept
Counts the number of consecutive 1 bits, starting from the right.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The value to test. |
Returns | The number of consecutive ones from the right end of an integer's bits. |
#include <muu/countr.h>
template <typename T>
int countr_zero(T val) constexpr noexcept
Counts the number of consecutive 0 bits, starting from the right.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The input value. |
Returns | The number of consecutive zeros from the right end of an integer's bits. |
#include <muu/for_sequence.h>
template <auto N1, auto N2, typename Func>
void for_product(Func&& func) constexpr noexcept(…)
Generates a series of sequential function calls by pack expansion.
Template parameters | |
---|---|
N1 | The length of the LHS sequence. Cannot be negative. |
N2 | The length of the RHS sequence. Cannot be negative. |
Func | A callable type with the signature void(auto, auto) . |
Generates a std::
auto vals_1 = std::pair{ 1, 2 }; auto vals_2 = std::pair{ 3, 4 }; for_product<2, 2>([&](auto i, auto j) { const auto lhs = std::get<decltype(i)::value>(vals_1); const auto rhs = std::get<decltype(j)::value>(vals_2); std::cout << lhs << " * " << rhs << " = " << lhs * rhs; });
1 * 3 = 3 1 * 4 = 4 2 * 3 = 6 2 * 4 = 8
#include <muu/for_sequence.h>
template <auto N, typename Func>
void for_sequence(Func&& func) constexpr noexcept(…)
Generates a series of sequential function calls by pack expansion.
Template parameters | |
---|---|
N | The length of the sequence (the number of calls). Cannot be negative. |
Func | A callable type with the signature void(auto) . |
Generates a std::
auto vals = std::tuple{ 0, "1"sv, 2.3f }; for_sequence<3>([&](auto i) { std::cout << std::get<decltype(i)::value>(vals) << "\n"; });
0 1 2.3
#include <muu/popcount.h>
template <typename T>
bool has_single_bit(T val) constexpr noexcept
Checks if an integral value has only a single bit set.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The value to test. |
Returns | True if the input value had only a single bit set (and thus was a power of two). |
bool is_constant_evaluated() constexpr noexcept
#include <muu/is_constant_evaluated.h>
Equivalent to C++20's std::is_constant_evaluated.
#include <muu/launder.h>
template <class T>
T* launder(T* ptr) constexpr noexcept
Equivalent to C++17's std::launder.
#include <muu/core.h>
template <typename T, typename... U>
const T& max(const T& val1,
const T& val2,
const U&... vals) constexpr noexcept
Returns the maximum of two or more values.
#include <muu/core.h>
template <typename T, typename... U>
const T& min(const T& val1,
const T& val2,
const U&... vals) constexpr noexcept
Returns the minimum of two or more values.
#include <muu/pointer_cast.h>
template <typename To, typename From>
To pointer_cast(From from) constexpr noexcept
Casts between pointers, choosing the most appropriate conversion path.
Template parameters | |
---|---|
To | A pointer or integral type large enough to store a pointer |
From | A pointer, array, nullptr_t, or an integral type large enough to store a pointer. |
Parameters | |
from | The value being cast. |
Returns | The input casted to the desired type. |
Doing low-level work with pointers often requires a lot of tedious boilerplate, particularly when moving to/from raw byte representations or dealing with const
. By using pointer_cast
instead you can eliminate a lot of that boilerplate, since it will do 'the right thing' via some combination of:
From | To | Cast | Note |
---|---|---|---|
T* | void* | static_cast | |
void* | T* | static_cast | |
T* | const T* | static_cast | |
T* | volatile T* | static_cast | |
T* | const volatile T* | static_cast | |
const T* | T* | const_cast | |
volatile T* | T* | const_cast | |
const volatile T* | T* | const_cast | |
Derived* | Base* | static_cast | |
Base* | Derived* | dynamic_cast | Polymorphic bases |
Base* | Derived* | static_cast | Non-polymorphic bases |
T* | (u)intptr_t | reinterpret_cast | |
(u)intptr_t | T* | reinterpret_cast | |
void* | T(*)() | reinterpret_cast | Where supported |
T(*)() | void* | reinterpret_cast | Where supported |
T(*)() | T(*)()noexcept | reinterpret_cast | |
T(*)()noexcept | T(*)() | static_cast | |
IUnknown* | IUnknown* | QueryInterface | Windows only |
#include <muu/popcount.h>
template <typename T>
int popcount(T val) constexpr noexcept
Counts the number of set bits (the 'population count') of an unsigned integer.
Template parameters | |
---|---|
T | An unsigned integer or enum type. |
Parameters | |
val | The input value. |
Returns | The number of bits that were set to 1 in val . |
#include <muu/compressed_pair.h>
template <typename F, typename S>
void swap(compressed_pair<F, S>& lhs,
compressed_pair<F, S>& rhs) noexcept(…)
Swaps two compressed pairs.
#include <muu/bit.h>
template <size_t... ByteIndices, typename T>
auto swizzle(T val) constexpr noexcept
Select and re-pack arbitrary bytes from an integer.
Template parameters | |
---|---|
ByteIndices | Indices of the bytes from the source integer in the (little-endian) order they're to be packed. |
T | An integer or enum type. |
Parameters | |
val | An integer or enum value. |
Returns | An integral value containing the selected bytes packed bitwise left-to-right. If the total size of the inputs was less than the return type, the output will be zero-padded on the left. |
const auto i = 0xAABBCCDDu; // ^ ^ ^ ^ // byte indices: 3 2 1 0 std::cout << std::hex << std::setfill('0'); std::cout << " <0>: " << std::setw(8) << swizzle<0>(i) << "\n"; std::cout << " <1, 0>: " << std::setw(8) << swizzle<1, 0>(i) << "\n"; std::cout << "<3, 2, 3>: " << std::setw(8) << swizzle<3, 2, 3>(i) << "\n";
<0>: 000000DD <1, 0>: 0000CCDD <3, 2, 3>: 00AABBAA (on a little-endian system)
#include <muu/core.h>
template <typename T>
T* to_address(T* p) constexpr noexcept
Obtain the address represented by p without forming a reference to the pointee.
#include <muu/core.h>
template <typename Ptr>
auto to_address(const Ptr& p) constexpr noexcept
Obtain the address represented by p without forming a reference to the pointee.
#include <muu/core.h>
template <typename T>
std:: underlying_type_t<T> unwrap(T val) constexpr noexcept
Unwraps an enum to it's raw integer equivalent.
Template parameters | |
---|---|
T | An enum type. |
Parameters | |
val | The value to unwrap. |
Returns | Enum inputs:
static_cast<std:: Everything else: T&& (a no-op). |