mirror of
https://github.com/azahar-emu/mcl
synced 2025-11-06 15:10:05 +01:00
mcl: clang-format: Adopt WebKit style bracing
This commit is contained in:
parent
d5a46fa705
commit
416a2c6b56
@ -34,7 +34,7 @@ BraceWrapping:
|
|||||||
AfterClass: false
|
AfterClass: false
|
||||||
AfterControlStatement: Never
|
AfterControlStatement: Never
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
AfterFunction: false
|
AfterFunction: true
|
||||||
AfterNamespace: false
|
AfterNamespace: false
|
||||||
AfterObjCDeclaration: false
|
AfterObjCDeclaration: false
|
||||||
AfterStruct: false
|
AfterStruct: false
|
||||||
@ -62,7 +62,7 @@ ColumnLimit: 0
|
|||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
ConstructorInitializerIndentWidth: 8
|
ConstructorInitializerIndentWidth: 4
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
Cpp11BracedListStyle: true
|
Cpp11BracedListStyle: true
|
||||||
DeriveLineEnding: true
|
DeriveLineEnding: true
|
||||||
|
|||||||
@ -16,7 +16,8 @@ namespace mcl::detail {
|
|||||||
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args);
|
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args);
|
||||||
|
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
[[noreturn]] void assert_terminate(fmt::string_view msg, Ts... args) {
|
[[noreturn]] void assert_terminate(fmt::string_view msg, Ts... args)
|
||||||
|
{
|
||||||
assert_terminate_impl(msg, fmt::make_format_args(args...));
|
assert_terminate_impl(msg, fmt::make_format_args(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,14 @@
|
|||||||
namespace mcl::bit {
|
namespace mcl::bit {
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
inline size_t count_ones(T x) {
|
inline size_t count_ones(T x)
|
||||||
|
{
|
||||||
return std::bitset<bitsizeof<T>>(x).count();
|
return std::bitset<bitsizeof<T>>(x).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr size_t count_leading_zeros(T x) {
|
constexpr size_t count_leading_zeros(T x)
|
||||||
|
{
|
||||||
size_t result = bitsizeof<T>;
|
size_t result = bitsizeof<T>;
|
||||||
while (x != 0) {
|
while (x != 0) {
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
@ -28,7 +30,8 @@ constexpr size_t count_leading_zeros(T x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr int highest_set_bit(T x) {
|
constexpr int highest_set_bit(T x)
|
||||||
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
while (x != 0) {
|
while (x != 0) {
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
@ -38,7 +41,8 @@ constexpr int highest_set_bit(T x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr size_t lowest_set_bit(T x) {
|
constexpr size_t lowest_set_bit(T x)
|
||||||
|
{
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
return bitsizeof<T>;
|
return bitsizeof<T>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,8 @@ namespace mcl::bit {
|
|||||||
|
|
||||||
/// Create a mask with `count` number of one bits.
|
/// Create a mask with `count` number of one bits.
|
||||||
template<size_t count, BitIntegral T>
|
template<size_t count, BitIntegral T>
|
||||||
constexpr T ones() {
|
constexpr T ones()
|
||||||
|
{
|
||||||
static_assert(count <= bitsizeof<T>, "count larger than bitsize of T");
|
static_assert(count <= bitsizeof<T>, "count larger than bitsize of T");
|
||||||
|
|
||||||
if constexpr (count == 0) {
|
if constexpr (count == 0) {
|
||||||
@ -25,7 +26,8 @@ constexpr T ones() {
|
|||||||
|
|
||||||
/// Create a mask with `count` number of one bits.
|
/// Create a mask with `count` number of one bits.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T ones(size_t count) {
|
constexpr T ones(size_t count)
|
||||||
|
{
|
||||||
ASSERT_MSG(count <= bitsizeof<T>, "count larger than bitsize of T");
|
ASSERT_MSG(count <= bitsizeof<T>, "count larger than bitsize of T");
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
@ -36,7 +38,8 @@ constexpr T ones(size_t count) {
|
|||||||
|
|
||||||
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
constexpr T mask() {
|
constexpr T mask()
|
||||||
|
{
|
||||||
static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||||
static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
||||||
static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
||||||
@ -46,7 +49,8 @@ constexpr T mask() {
|
|||||||
|
|
||||||
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T mask(size_t begin_bit, size_t end_bit) {
|
constexpr T mask(size_t begin_bit, size_t end_bit)
|
||||||
|
{
|
||||||
ASSERT_MSG(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
ASSERT_MSG(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||||
ASSERT_MSG(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
ASSERT_MSG(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
||||||
ASSERT_MSG(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
ASSERT_MSG(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
||||||
@ -56,91 +60,104 @@ constexpr T mask(size_t begin_bit, size_t end_bit) {
|
|||||||
|
|
||||||
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
constexpr T get_bits(T value) {
|
constexpr T get_bits(T value)
|
||||||
|
{
|
||||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
return (value & m) >> begin_bit;
|
return (value & m) >> begin_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T get_bits(size_t begin_bit, size_t end_bit, T value) {
|
constexpr T get_bits(size_t begin_bit, size_t end_bit, T value)
|
||||||
|
{
|
||||||
const T m = mask<T>(begin_bit, end_bit);
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
return (value & m) >> begin_bit;
|
return (value & m) >> begin_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
constexpr T clear_bits(T value) {
|
constexpr T clear_bits(T value)
|
||||||
|
{
|
||||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
return value & ~m;
|
return value & ~m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value) {
|
constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value)
|
||||||
|
{
|
||||||
const T m = mask<T>(begin_bit, end_bit);
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
return value & ~m;
|
return value & ~m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
constexpr T set_bits(T value, T new_bits) {
|
constexpr T set_bits(T value, T new_bits)
|
||||||
|
{
|
||||||
constexpr T m = mask<begin_bit, end_bit, T>();
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
return (value & ~m) | ((new_bits << begin_bit) & m);
|
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits) {
|
constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits)
|
||||||
|
{
|
||||||
const T m = mask<T>(begin_bit, end_bit);
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
return (value & ~m) | ((new_bits << begin_bit) & m);
|
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract bit at bit_position from value of type T.
|
/// Extract bit at bit_position from value of type T.
|
||||||
template<size_t bit_position, BitIntegral T>
|
template<size_t bit_position, BitIntegral T>
|
||||||
constexpr bool get_bit(T value) {
|
constexpr bool get_bit(T value)
|
||||||
|
{
|
||||||
constexpr T m = mask<bit_position, bit_position, T>();
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
return (value & m) != 0;
|
return (value & m) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract bit at bit_position from value of type T.
|
/// Extract bit at bit_position from value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr bool get_bit(size_t bit_position, T value) {
|
constexpr bool get_bit(size_t bit_position, T value)
|
||||||
|
{
|
||||||
const T m = mask<T>(bit_position, bit_position);
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
return (value & m) != 0;
|
return (value & m) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears bit at bit_position of value of type T.
|
/// Clears bit at bit_position of value of type T.
|
||||||
template<size_t bit_position, BitIntegral T>
|
template<size_t bit_position, BitIntegral T>
|
||||||
constexpr T clear_bit(T value) {
|
constexpr T clear_bit(T value)
|
||||||
|
{
|
||||||
constexpr T m = mask<bit_position, bit_position, T>();
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
return value & ~m;
|
return value & ~m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears bit at bit_position of value of type T.
|
/// Clears bit at bit_position of value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T clear_bit(size_t bit_position, T value) {
|
constexpr T clear_bit(size_t bit_position, T value)
|
||||||
|
{
|
||||||
const T m = mask<T>(bit_position, bit_position);
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
return value & ~m;
|
return value & ~m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies bit at bit_position of value of type T.
|
/// Modifies bit at bit_position of value of type T.
|
||||||
template<size_t bit_position, BitIntegral T>
|
template<size_t bit_position, BitIntegral T>
|
||||||
constexpr T set_bit(T value, bool new_bit) {
|
constexpr T set_bit(T value, bool new_bit)
|
||||||
|
{
|
||||||
constexpr T m = mask<bit_position, bit_position, T>();
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies bit at bit_position of value of type T.
|
/// Modifies bit at bit_position of value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T set_bit(size_t bit_position, T value, bool new_bit) {
|
constexpr T set_bit(size_t bit_position, T value, bool new_bit)
|
||||||
|
{
|
||||||
const T m = mask<T>(bit_position, bit_position);
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||||
template<size_t bit_count, BitIntegral T>
|
template<size_t bit_count, BitIntegral T>
|
||||||
constexpr T sign_extend(T value) {
|
constexpr T sign_extend(T value)
|
||||||
|
{
|
||||||
static_assert(bit_count != 0, "cannot sign-extend zero-sized value");
|
static_assert(bit_count != 0, "cannot sign-extend zero-sized value");
|
||||||
|
|
||||||
using S = std::make_signed_t<T>;
|
using S = std::make_signed_t<T>;
|
||||||
@ -150,7 +167,8 @@ constexpr T sign_extend(T value) {
|
|||||||
|
|
||||||
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T sign_extend(size_t bit_count, T value) {
|
constexpr T sign_extend(size_t bit_count, T value)
|
||||||
|
{
|
||||||
ASSERT_MSG(bit_count != 0, "cannot sign-extend zero-sized value");
|
ASSERT_MSG(bit_count != 0, "cannot sign-extend zero-sized value");
|
||||||
|
|
||||||
using S = std::make_signed_t<T>;
|
using S = std::make_signed_t<T>;
|
||||||
@ -160,7 +178,8 @@ constexpr T sign_extend(size_t bit_count, T value) {
|
|||||||
|
|
||||||
/// Replicate an element across a value of type T.
|
/// Replicate an element across a value of type T.
|
||||||
template<size_t element_size, BitIntegral T>
|
template<size_t element_size, BitIntegral T>
|
||||||
constexpr T replicate_element(T value) {
|
constexpr T replicate_element(T value)
|
||||||
|
{
|
||||||
static_assert(element_size <= bitsizeof<T>, "element_size is too large");
|
static_assert(element_size <= bitsizeof<T>, "element_size is too large");
|
||||||
static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
||||||
|
|
||||||
@ -173,7 +192,8 @@ constexpr T replicate_element(T value) {
|
|||||||
|
|
||||||
/// Replicate an element of type U across a value of type T.
|
/// Replicate an element of type U across a value of type T.
|
||||||
template<BitIntegral U, BitIntegral T>
|
template<BitIntegral U, BitIntegral T>
|
||||||
constexpr T replicate_element(T value) {
|
constexpr T replicate_element(T value)
|
||||||
|
{
|
||||||
static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large");
|
static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large");
|
||||||
|
|
||||||
return replicate_element<bitsizeof<U>, T>(value);
|
return replicate_element<bitsizeof<U>, T>(value);
|
||||||
@ -181,7 +201,8 @@ constexpr T replicate_element(T value) {
|
|||||||
|
|
||||||
/// Replicate an element across a value of type T.
|
/// Replicate an element across a value of type T.
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T replicate_element(size_t element_size, T value) {
|
constexpr T replicate_element(size_t element_size, T value)
|
||||||
|
{
|
||||||
ASSERT_MSG(element_size <= bitsizeof<T>, "element_size is too large");
|
ASSERT_MSG(element_size <= bitsizeof<T>, "element_size is too large");
|
||||||
ASSERT_MSG(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
ASSERT_MSG(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
||||||
|
|
||||||
@ -192,7 +213,8 @@ constexpr T replicate_element(size_t element_size, T value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr bool most_significant_bit(T value) {
|
constexpr bool most_significant_bit(T value)
|
||||||
|
{
|
||||||
return get_bit<bitsizeof<T> - 1, T>(value);
|
return get_bit<bitsizeof<T> - 1, T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,8 @@
|
|||||||
namespace mcl::bit {
|
namespace mcl::bit {
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T rotate_right(T x, size_t amount) {
|
constexpr T rotate_right(T x, size_t amount)
|
||||||
|
{
|
||||||
amount %= bitsizeof<T>;
|
amount %= bitsizeof<T>;
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
return x;
|
return x;
|
||||||
@ -20,7 +21,8 @@ constexpr T rotate_right(T x, size_t amount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
constexpr T rotate_left(T x, size_t amount) {
|
constexpr T rotate_left(T x, size_t amount)
|
||||||
|
{
|
||||||
amount %= bitsizeof<T>;
|
amount %= bitsizeof<T>;
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
return x;
|
return x;
|
||||||
|
|||||||
@ -8,18 +8,21 @@
|
|||||||
|
|
||||||
namespace mcl::bit {
|
namespace mcl::bit {
|
||||||
|
|
||||||
constexpr u16 swap_bytes_16(u16 value) {
|
constexpr u16 swap_bytes_16(u16 value)
|
||||||
|
{
|
||||||
return static_cast<u16>(u32{value} >> 8 | u32{value} << 8);
|
return static_cast<u16>(u32{value} >> 8 | u32{value} << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 swap_bytes_32(u32 value) {
|
constexpr u32 swap_bytes_32(u32 value)
|
||||||
|
{
|
||||||
return ((value & 0xff000000u) >> 24)
|
return ((value & 0xff000000u) >> 24)
|
||||||
| ((value & 0x00ff0000u) >> 8)
|
| ((value & 0x00ff0000u) >> 8)
|
||||||
| ((value & 0x0000ff00u) << 8)
|
| ((value & 0x0000ff00u) << 8)
|
||||||
| ((value & 0x000000ffu) << 24);
|
| ((value & 0x000000ffu) << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u64 swap_bytes_64(u64 value) {
|
constexpr u64 swap_bytes_64(u64 value)
|
||||||
|
{
|
||||||
return ((value & 0xff00000000000000ull) >> 56)
|
return ((value & 0xff00000000000000ull) >> 56)
|
||||||
| ((value & 0x00ff000000000000ull) >> 40)
|
| ((value & 0x00ff000000000000ull) >> 40)
|
||||||
| ((value & 0x0000ff0000000000ull) >> 24)
|
| ((value & 0x0000ff0000000000ull) >> 24)
|
||||||
@ -30,19 +33,22 @@ constexpr u64 swap_bytes_64(u64 value) {
|
|||||||
| ((value & 0x00000000000000ffull) << 56);
|
| ((value & 0x00000000000000ffull) << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 swap_halves_32(u32 value) {
|
constexpr u32 swap_halves_32(u32 value)
|
||||||
|
{
|
||||||
return ((value & 0xffff0000u) >> 16)
|
return ((value & 0xffff0000u) >> 16)
|
||||||
| ((value & 0x0000ffffu) << 16);
|
| ((value & 0x0000ffffu) << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u64 swap_halves_64(u64 value) {
|
constexpr u64 swap_halves_64(u64 value)
|
||||||
|
{
|
||||||
return ((value & 0xffff000000000000ull) >> 48)
|
return ((value & 0xffff000000000000ull) >> 48)
|
||||||
| ((value & 0x0000ffff00000000ull) >> 16)
|
| ((value & 0x0000ffff00000000ull) >> 16)
|
||||||
| ((value & 0x00000000ffff0000ull) << 16)
|
| ((value & 0x00000000ffff0000ull) << 16)
|
||||||
| ((value & 0x000000000000ffffull) << 48);
|
| ((value & 0x000000000000ffffull) << 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u64 swap_words_64(u64 value) {
|
constexpr u64 swap_words_64(u64 value)
|
||||||
|
{
|
||||||
return ((value & 0xffffffff00000000ull) >> 32)
|
return ((value & 0xffffffff00000000ull) >> 32)
|
||||||
| ((value & 0x00000000ffffffffull) << 32);
|
| ((value & 0x00000000ffffffffull) << 32);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,8 @@ namespace mcl {
|
|||||||
|
|
||||||
/// Reinterpret objects of one type as another by bit-casting between object representations.
|
/// Reinterpret objects of one type as another by bit-casting between object representations.
|
||||||
template<class Dest, class Source>
|
template<class Dest, class Source>
|
||||||
inline Dest bit_cast(const Source& source) noexcept {
|
inline Dest bit_cast(const Source& source) noexcept
|
||||||
|
{
|
||||||
static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal");
|
static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal");
|
||||||
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
||||||
static_assert(std::is_trivially_copyable_v<Source>, "source type must be trivially copyable");
|
static_assert(std::is_trivially_copyable_v<Source>, "source type must be trivially copyable");
|
||||||
@ -24,7 +25,8 @@ inline Dest bit_cast(const Source& source) noexcept {
|
|||||||
/// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations.
|
/// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations.
|
||||||
/// Note that here we do not verify if source pointed to by source_ptr has enough bytes to read from.
|
/// Note that here we do not verify if source pointed to by source_ptr has enough bytes to read from.
|
||||||
template<class Dest, class SourcePtr>
|
template<class Dest, class SourcePtr>
|
||||||
inline Dest bit_cast_pointee(const SourcePtr source_ptr) noexcept {
|
inline Dest bit_cast_pointee(const SourcePtr source_ptr) noexcept
|
||||||
|
{
|
||||||
static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer");
|
static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer");
|
||||||
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,8 @@ class intrusive_list_iterator;
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
class intrusive_list_node {
|
class intrusive_list_node {
|
||||||
public:
|
public:
|
||||||
bool is_sentinel() const {
|
bool is_sentinel() const
|
||||||
|
{
|
||||||
return is_sentinel_;
|
return is_sentinel_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +43,8 @@ class intrusive_list_sentinel final : public intrusive_list_node<T> {
|
|||||||
using intrusive_list_node<T>::is_sentinel_;
|
using intrusive_list_node<T>::is_sentinel_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
intrusive_list_sentinel() {
|
intrusive_list_sentinel()
|
||||||
|
{
|
||||||
next = this;
|
next = this;
|
||||||
prev = this;
|
prev = this;
|
||||||
is_sentinel_ = true;
|
is_sentinel_ = true;
|
||||||
@ -72,50 +74,56 @@ public:
|
|||||||
intrusive_list_iterator& operator=(const intrusive_list_iterator& other) = default;
|
intrusive_list_iterator& operator=(const intrusive_list_iterator& other) = default;
|
||||||
|
|
||||||
explicit intrusive_list_iterator(node_pointer list_node)
|
explicit intrusive_list_iterator(node_pointer list_node)
|
||||||
: node(list_node) {
|
: node(list_node) {}
|
||||||
}
|
|
||||||
explicit intrusive_list_iterator(pointer data)
|
explicit intrusive_list_iterator(pointer data)
|
||||||
: node(data) {
|
: node(data) {}
|
||||||
}
|
|
||||||
explicit intrusive_list_iterator(reference data)
|
explicit intrusive_list_iterator(reference data)
|
||||||
: node(&data) {
|
: node(&data) {}
|
||||||
}
|
|
||||||
|
|
||||||
intrusive_list_iterator& operator++() {
|
intrusive_list_iterator& operator++()
|
||||||
|
{
|
||||||
node = node->next;
|
node = node->next;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
intrusive_list_iterator& operator--() {
|
intrusive_list_iterator& operator--()
|
||||||
|
{
|
||||||
node = node->prev;
|
node = node->prev;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
intrusive_list_iterator operator++(int) {
|
intrusive_list_iterator operator++(int)
|
||||||
|
{
|
||||||
intrusive_list_iterator it(*this);
|
intrusive_list_iterator it(*this);
|
||||||
++*this;
|
++*this;
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
intrusive_list_iterator operator--(int) {
|
intrusive_list_iterator operator--(int)
|
||||||
|
{
|
||||||
intrusive_list_iterator it(*this);
|
intrusive_list_iterator it(*this);
|
||||||
--*this;
|
--*this;
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const intrusive_list_iterator& other) const {
|
bool operator==(const intrusive_list_iterator& other) const
|
||||||
|
{
|
||||||
return node == other.node;
|
return node == other.node;
|
||||||
}
|
}
|
||||||
bool operator!=(const intrusive_list_iterator& other) const {
|
bool operator!=(const intrusive_list_iterator& other) const
|
||||||
|
{
|
||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
reference operator*() const {
|
reference operator*() const
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!node->is_sentinel());
|
DEBUG_ASSERT(!node->is_sentinel());
|
||||||
return static_cast<reference>(*node);
|
return static_cast<reference>(*node);
|
||||||
}
|
}
|
||||||
pointer operator->() const {
|
pointer operator->() const
|
||||||
|
{
|
||||||
return std::addressof(operator*());
|
return std::addressof(operator*());
|
||||||
}
|
}
|
||||||
|
|
||||||
node_pointer AsNodePointer() const {
|
node_pointer AsNodePointer() const
|
||||||
|
{
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +153,8 @@ public:
|
|||||||
* @param location The location to insert the node.
|
* @param location The location to insert the node.
|
||||||
* @param new_node The node to add.
|
* @param new_node The node to add.
|
||||||
*/
|
*/
|
||||||
iterator insert(iterator location, pointer new_node) {
|
iterator insert(iterator location, pointer new_node)
|
||||||
|
{
|
||||||
return insert_before(location, new_node);
|
return insert_before(location, new_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +165,8 @@ public:
|
|||||||
* @param location The location to insert the new node.
|
* @param location The location to insert the new node.
|
||||||
* @param new_node The node to insert into the list.
|
* @param new_node The node to insert into the list.
|
||||||
*/
|
*/
|
||||||
iterator insert_before(iterator location, pointer new_node) {
|
iterator insert_before(iterator location, pointer new_node)
|
||||||
|
{
|
||||||
auto existing_node = location.AsNodePointer();
|
auto existing_node = location.AsNodePointer();
|
||||||
|
|
||||||
new_node->next = existing_node;
|
new_node->next = existing_node;
|
||||||
@ -173,7 +183,8 @@ public:
|
|||||||
* @param position Location to insert the node in front of.
|
* @param position Location to insert the node in front of.
|
||||||
* @param new_node The node to be inserted into the list.
|
* @param new_node The node to be inserted into the list.
|
||||||
*/
|
*/
|
||||||
iterator insert_after(iterator position, pointer new_node) {
|
iterator insert_after(iterator position, pointer new_node)
|
||||||
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
return insert(begin(), new_node);
|
return insert(begin(), new_node);
|
||||||
|
|
||||||
@ -184,7 +195,8 @@ public:
|
|||||||
* Add an entry to the start of the list.
|
* Add an entry to the start of the list.
|
||||||
* @param node Node to add to the list.
|
* @param node Node to add to the list.
|
||||||
*/
|
*/
|
||||||
void push_front(pointer node) {
|
void push_front(pointer node)
|
||||||
|
{
|
||||||
insert(begin(), node);
|
insert(begin(), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +204,8 @@ public:
|
|||||||
* Add an entry to the end of the list
|
* Add an entry to the end of the list
|
||||||
* @param node Node to add to the list.
|
* @param node Node to add to the list.
|
||||||
*/
|
*/
|
||||||
void push_back(pointer node) {
|
void push_back(pointer node)
|
||||||
|
{
|
||||||
insert(end(), node);
|
insert(end(), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +213,8 @@ public:
|
|||||||
* Erases the node at the front of the list.
|
* Erases the node at the front of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
void pop_front() {
|
void pop_front()
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
erase(begin());
|
erase(begin());
|
||||||
}
|
}
|
||||||
@ -209,7 +223,8 @@ public:
|
|||||||
* Erases the node at the back of the list.
|
* Erases the node at the back of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
void pop_back() {
|
void pop_back()
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
erase(--end());
|
erase(--end());
|
||||||
}
|
}
|
||||||
@ -218,7 +233,8 @@ public:
|
|||||||
* Removes a node from this list
|
* Removes a node from this list
|
||||||
* @param it An iterator that points to the node to remove from list.
|
* @param it An iterator that points to the node to remove from list.
|
||||||
*/
|
*/
|
||||||
pointer remove(iterator& it) {
|
pointer remove(iterator& it)
|
||||||
|
{
|
||||||
DEBUG_ASSERT(it != end());
|
DEBUG_ASSERT(it != end());
|
||||||
|
|
||||||
pointer node = &*it++;
|
pointer node = &*it++;
|
||||||
@ -237,7 +253,8 @@ public:
|
|||||||
* Removes a node from this list
|
* Removes a node from this list
|
||||||
* @param it A constant iterator that points to the node to remove from list.
|
* @param it A constant iterator that points to the node to remove from list.
|
||||||
*/
|
*/
|
||||||
pointer remove(const iterator& it) {
|
pointer remove(const iterator& it)
|
||||||
|
{
|
||||||
iterator copy = it;
|
iterator copy = it;
|
||||||
return remove(copy);
|
return remove(copy);
|
||||||
}
|
}
|
||||||
@ -246,7 +263,8 @@ public:
|
|||||||
* Removes a node from this list.
|
* Removes a node from this list.
|
||||||
* @param node A pointer to the node to remove.
|
* @param node A pointer to the node to remove.
|
||||||
*/
|
*/
|
||||||
pointer remove(pointer node) {
|
pointer remove(pointer node)
|
||||||
|
{
|
||||||
return remove(iterator(node));
|
return remove(iterator(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +272,8 @@ public:
|
|||||||
* Removes a node from this list.
|
* Removes a node from this list.
|
||||||
* @param node A reference to the node to remove.
|
* @param node A reference to the node to remove.
|
||||||
*/
|
*/
|
||||||
pointer remove(reference node) {
|
pointer remove(reference node)
|
||||||
|
{
|
||||||
return remove(iterator(node));
|
return remove(iterator(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +281,8 @@ public:
|
|||||||
* Is this list empty?
|
* Is this list empty?
|
||||||
* @returns true if there are no nodes in this list.
|
* @returns true if there are no nodes in this list.
|
||||||
*/
|
*/
|
||||||
bool empty() const {
|
bool empty() const
|
||||||
|
{
|
||||||
return root->next == root.get();
|
return root->next == root.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +290,8 @@ public:
|
|||||||
* Gets the total number of elements within this list.
|
* Gets the total number of elements within this list.
|
||||||
* @return the number of elements in this list.
|
* @return the number of elements in this list.
|
||||||
*/
|
*/
|
||||||
size_type size() const {
|
size_type size() const
|
||||||
|
{
|
||||||
return static_cast<size_type>(std::distance(begin(), end()));
|
return static_cast<size_type>(std::distance(begin(), end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +299,8 @@ public:
|
|||||||
* Retrieves a reference to the node at the front of the list.
|
* Retrieves a reference to the node at the front of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
reference front() {
|
reference front()
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
return *begin();
|
return *begin();
|
||||||
}
|
}
|
||||||
@ -287,7 +309,8 @@ public:
|
|||||||
* Retrieves a constant reference to the node at the front of the list.
|
* Retrieves a constant reference to the node at the front of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
const_reference front() const {
|
const_reference front() const
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
return *begin();
|
return *begin();
|
||||||
}
|
}
|
||||||
@ -296,7 +319,8 @@ public:
|
|||||||
* Retrieves a reference to the node at the back of the list.
|
* Retrieves a reference to the node at the back of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
reference back() {
|
reference back()
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
return *--end();
|
return *--end();
|
||||||
}
|
}
|
||||||
@ -305,7 +329,8 @@ public:
|
|||||||
* Retrieves a constant reference to the node at the back of the list.
|
* Retrieves a constant reference to the node at the back of the list.
|
||||||
* @note Must not be called on an empty list.
|
* @note Must not be called on an empty list.
|
||||||
*/
|
*/
|
||||||
const_reference back() const {
|
const_reference back() const
|
||||||
|
{
|
||||||
DEBUG_ASSERT(!empty());
|
DEBUG_ASSERT(!empty());
|
||||||
return *--end();
|
return *--end();
|
||||||
}
|
}
|
||||||
@ -331,7 +356,8 @@ public:
|
|||||||
* Erases a node from the list, indicated by an iterator.
|
* Erases a node from the list, indicated by an iterator.
|
||||||
* @param it The iterator that points to the node to erase.
|
* @param it The iterator that points to the node to erase.
|
||||||
*/
|
*/
|
||||||
iterator erase(iterator it) {
|
iterator erase(iterator it)
|
||||||
|
{
|
||||||
remove(it);
|
remove(it);
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
@ -340,7 +366,8 @@ public:
|
|||||||
* Erases a node from this list.
|
* Erases a node from this list.
|
||||||
* @param node A pointer to the node to erase from this list.
|
* @param node A pointer to the node to erase from this list.
|
||||||
*/
|
*/
|
||||||
iterator erase(pointer node) {
|
iterator erase(pointer node)
|
||||||
|
{
|
||||||
return erase(iterator(node));
|
return erase(iterator(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,7 +375,8 @@ public:
|
|||||||
* Erases a node from this list.
|
* Erases a node from this list.
|
||||||
* @param node A reference to the node to erase from this list.
|
* @param node A reference to the node to erase from this list.
|
||||||
*/
|
*/
|
||||||
iterator erase(reference node) {
|
iterator erase(reference node)
|
||||||
|
{
|
||||||
return erase(iterator(node));
|
return erase(iterator(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +384,8 @@ public:
|
|||||||
* Exchanges contents of this list with another list instance.
|
* Exchanges contents of this list with another list instance.
|
||||||
* @param other The other list to swap with.
|
* @param other The other list to swap with.
|
||||||
*/
|
*/
|
||||||
void swap(intrusive_list& other) noexcept {
|
void swap(intrusive_list& other) noexcept
|
||||||
|
{
|
||||||
root.swap(other.root);
|
root.swap(other.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +400,8 @@ private:
|
|||||||
* @param rhs The second list.
|
* @param rhs The second list.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void swap(intrusive_list<T>& lhs, intrusive_list<T>& rhs) noexcept {
|
void swap(intrusive_list<T>& lhs, intrusive_list<T>& rhs) noexcept
|
||||||
|
{
|
||||||
lhs.swap(rhs);
|
lhs.swap(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,12 +13,14 @@ template<typename T>
|
|||||||
struct reverse_adapter {
|
struct reverse_adapter {
|
||||||
T& iterable;
|
T& iterable;
|
||||||
|
|
||||||
constexpr auto begin() {
|
constexpr auto begin()
|
||||||
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
return rbegin(iterable);
|
return rbegin(iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto end() {
|
constexpr auto end()
|
||||||
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
return rend(iterable);
|
return rend(iterable);
|
||||||
}
|
}
|
||||||
@ -27,7 +29,8 @@ struct reverse_adapter {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr detail::reverse_adapter<T> reverse(T&& iterable) {
|
constexpr detail::reverse_adapter<T> reverse(T&& iterable)
|
||||||
|
{
|
||||||
return detail::reverse_adapter<T>{iterable};
|
return detail::reverse_adapter<T>{iterable};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ struct contains;
|
|||||||
|
|
||||||
template<template<class...> class LT, class... Ts, class T>
|
template<template<class...> class LT, class... Ts, class T>
|
||||||
struct contains<LT<Ts...>, T>
|
struct contains<LT<Ts...>, T>
|
||||||
: bool_value<(false || ... || std::is_same_v<Ts, T>)> {};
|
: bool_value<(false || ... || std::is_same_v<Ts, T>)> {};
|
||||||
|
|
||||||
/// Does list L contain an element which is same as type T?
|
/// Does list L contain an element which is same as type T?
|
||||||
template<class L, class T>
|
template<class L, class T>
|
||||||
|
|||||||
@ -20,8 +20,10 @@ template<typename Function>
|
|||||||
class scope_exit final {
|
class scope_exit final {
|
||||||
public:
|
public:
|
||||||
explicit scope_exit(Function&& fn)
|
explicit scope_exit(Function&& fn)
|
||||||
: function(std::move(fn)) {}
|
: function(std::move(fn)) {}
|
||||||
~scope_exit() noexcept {
|
|
||||||
|
~scope_exit() noexcept
|
||||||
|
{
|
||||||
function();
|
function();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,8 +35,10 @@ template<typename Function>
|
|||||||
class scope_fail final {
|
class scope_fail final {
|
||||||
public:
|
public:
|
||||||
explicit scope_fail(Function&& fn)
|
explicit scope_fail(Function&& fn)
|
||||||
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
||||||
~scope_fail() noexcept {
|
|
||||||
|
~scope_fail() noexcept
|
||||||
|
{
|
||||||
if (std::uncaught_exceptions() > exception_count) {
|
if (std::uncaught_exceptions() > exception_count) {
|
||||||
function();
|
function();
|
||||||
}
|
}
|
||||||
@ -49,8 +53,10 @@ template<typename Function>
|
|||||||
class scope_success final {
|
class scope_success final {
|
||||||
public:
|
public:
|
||||||
explicit scope_success(Function&& fn)
|
explicit scope_success(Function&& fn)
|
||||||
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
||||||
~scope_success() {
|
|
||||||
|
~scope_success()
|
||||||
|
{
|
||||||
if (std::uncaught_exceptions() <= exception_count) {
|
if (std::uncaught_exceptions() <= exception_count) {
|
||||||
function();
|
function();
|
||||||
}
|
}
|
||||||
@ -64,17 +70,20 @@ private:
|
|||||||
// We use ->* here as it has the highest precedence of the operators we can use.
|
// We use ->* here as it has the highest precedence of the operators we can use.
|
||||||
|
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
auto operator->*(scope_exit_tag, Function&& function) {
|
auto operator->*(scope_exit_tag, Function&& function)
|
||||||
|
{
|
||||||
return scope_exit<std::decay_t<Function>>{std::forward<Function>(function)};
|
return scope_exit<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
auto operator->*(scope_fail_tag, Function&& function) {
|
auto operator->*(scope_fail_tag, Function&& function)
|
||||||
|
{
|
||||||
return scope_fail<std::decay_t<Function>>{std::forward<Function>(function)};
|
return scope_fail<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
auto operator->*(scope_success_tag, Function&& function) {
|
auto operator->*(scope_success_tag, Function&& function)
|
||||||
|
{
|
||||||
return scope_success<std::decay_t<Function>>{std::forward<Function>(function)};
|
return scope_success<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
namespace mcl::detail {
|
namespace mcl::detail {
|
||||||
|
|
||||||
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args) {
|
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args)
|
||||||
|
{
|
||||||
fmt::print(stderr, "assertion failed: ");
|
fmt::print(stderr, "assertion failed: ");
|
||||||
fmt::vprint(stderr, msg, args);
|
fmt::vprint(stderr, msg, args);
|
||||||
std::fflush(stderr);
|
std::fflush(stderr);
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
#include <mcl/bit/bit_field.hpp>
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include <mcl/stdint.hpp>
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
TEST_CASE("mcl::bit::ones", "[bit]") {
|
TEST_CASE("mcl::bit::ones", "[bit]")
|
||||||
|
{
|
||||||
const std::array cases{
|
const std::array cases{
|
||||||
std::make_tuple<size_t, u8>(0, 0x00),
|
std::make_tuple<size_t, u8>(0, 0x00),
|
||||||
std::make_tuple<size_t, u8>(1, 0x01),
|
std::make_tuple<size_t, u8>(1, 0x01),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user