Squashed 'externals/mcl/' changes from a86a53843..761b7c05e
761b7c05e mcl: Build as PIC 4aad0b5e6 mcl/bit: Simplify sign_extend 0733afd2a mcl: Fix bug in non-template mcl::bit::ones e26df0587 mcl: bit_field: Fix incorrect argument order in replicate_element git-subtree-dir: externals/mcl git-subtree-split: 761b7c05e80d789acf572b52175b852c6509e753
This commit is contained in:
parent
7eb1d05f63
commit
5da4668a0d
5 changed files with 52 additions and 13 deletions
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
project(mcl LANGUAGES CXX VERSION 0.1.3)
|
project(mcl LANGUAGES CXX VERSION 0.1.7)
|
||||||
|
|
||||||
# Project options
|
# Project options
|
||||||
option(MCL_WARNINGS_AS_ERRORS "Warnings as errors" ON)
|
option(MCL_WARNINGS_AS_ERRORS "Warnings as errors" ON)
|
||||||
|
|
|
@ -31,7 +31,7 @@ constexpr T ones(size_t count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ~static_cast<T>(0) >> (bitsizeof<T> - count);
|
return static_cast<T>(~static_cast<T>(0)) >> (bitsizeof<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.
|
||||||
|
@ -143,11 +143,9 @@ 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");
|
||||||
|
|
||||||
constexpr T m = ones<bit_count, T>();
|
using S = std::make_signed_t<T>;
|
||||||
if (get_bit<bit_count - 1, T>(value)) {
|
constexpr size_t shift_amount = bitsizeof<T> - bit_count;
|
||||||
return value | ~m;
|
return static_cast<T>(static_cast<S>(value << shift_amount) >> shift_amount);
|
||||||
}
|
|
||||||
return 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.
|
||||||
|
@ -155,11 +153,9 @@ 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");
|
||||||
|
|
||||||
const T m = ones<T>(bit_count);
|
using S = std::make_signed_t<T>;
|
||||||
if (get_bit<T>(bit_count - 1, value)) {
|
const size_t shift_amount = bitsizeof<T> - bit_count;
|
||||||
return value | ~m;
|
return static_cast<T>(static_cast<S>(value << shift_amount) >> shift_amount);
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replicate an element across a value of type T.
|
/// Replicate an element across a value of type T.
|
||||||
|
@ -192,7 +188,7 @@ constexpr T replicate_element(size_t element_size, T value) {
|
||||||
if (element_size == bitsizeof<T>) {
|
if (element_size == bitsizeof<T>) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
return replicate_element<T>(static_cast<T>(value | (value << element_size)), element_size * 2);
|
return replicate_element<T>(element_size * 2, static_cast<T>(value | (value << element_size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<BitIntegral T>
|
template<BitIntegral T>
|
||||||
|
|
|
@ -63,6 +63,7 @@ target_include_directories(mcl
|
||||||
)
|
)
|
||||||
target_compile_options(mcl PRIVATE ${MCL_CXX_FLAGS})
|
target_compile_options(mcl PRIVATE ${MCL_CXX_FLAGS})
|
||||||
target_link_libraries(mcl PUBLIC $<BUILD_INTERFACE:fmt::fmt>)
|
target_link_libraries(mcl PUBLIC $<BUILD_INTERFACE:fmt::fmt>)
|
||||||
|
set_property(TARGET mcl PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
add_library(merry::mcl ALIAS mcl)
|
add_library(merry::mcl ALIAS mcl)
|
||||||
|
|
||||||
include(CreateTargetDirectoryGroups)
|
include(CreateTargetDirectoryGroups)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
add_executable(mcl-tests
|
add_executable(mcl-tests
|
||||||
|
bit/bit_field_tests.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
mp/metavalue_tests.cpp
|
mp/metavalue_tests.cpp
|
||||||
mp/typelist_tests.cpp
|
mp/typelist_tests.cpp
|
||||||
|
|
41
tests/bit/bit_field_tests.cpp
Normal file
41
tests/bit/bit_field_tests.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("mcl::bit::ones", "[bit]") {
|
||||||
|
const std::array cases{
|
||||||
|
std::make_tuple<size_t, u8>(0, 0x00),
|
||||||
|
std::make_tuple<size_t, u8>(1, 0x01),
|
||||||
|
std::make_tuple<size_t, u8>(2, 0x03),
|
||||||
|
std::make_tuple<size_t, u8>(3, 0x07),
|
||||||
|
std::make_tuple<size_t, u8>(4, 0x0f),
|
||||||
|
std::make_tuple<size_t, u8>(5, 0x1f),
|
||||||
|
std::make_tuple<size_t, u8>(6, 0x3f),
|
||||||
|
std::make_tuple<size_t, u8>(7, 0x7f),
|
||||||
|
std::make_tuple<size_t, u8>(8, 0xff),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto [count, expected] : cases) {
|
||||||
|
REQUIRE(mcl::bit::ones<u8>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u16>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u32>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u64>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<uptr>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<size_t>(count) == expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(mcl::bit::ones<3, u8>() == 0x7);
|
||||||
|
static_assert(mcl::bit::ones<15, u16>() == 0x7fff);
|
||||||
|
static_assert(mcl::bit::ones<16, u16>() == 0xffff);
|
||||||
|
static_assert(mcl::bit::ones<31, u32>() == 0x7fff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<32, u32>() == 0xffff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<63, u64>() == 0x7fff'ffff'ffff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<64, u64>() == 0xffff'ffff'ffff'ffff);
|
Loading…
Reference in a new issue