Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ env:
DEBIAN_FRONTEND: noninteractive
CMAKE_GENERATOR: Ninja
DEFAULT_CXX_STANDARD: 20
DEFAULT_LLVM_VERSION: 18
DEFAULT_LLVM_VERSION: 19
DEFAULT_GCC_VERSION: 13
MULL_LLVM_VERSION: 17
HYPOTHESIS_PROFILE: default
Expand All @@ -29,7 +29,7 @@ jobs:
fail-fast: false
matrix:
compiler: [clang, gcc]
version: [12, 13, 16, 17, 18]
version: [12, 13, 16, 17, 18, 19]
cxx_standard: [17, 20]
stdlib: [libstdc++, libc++]
build_type: [Debug]
Expand All @@ -38,6 +38,15 @@ jobs:
cc: "clang"
cxx: "clang++"
cxx_flags: "-stdlib=libstdc++"
- version: 19
compiler: clang
install: sudo apt update && sudo apt install -y clang-19
toolchain_root: "/usr/lib/llvm-19"
- version: 19
compiler: clang
stdlib: libc++
install: sudo apt update && sudo apt install -y clang-19 libc++-19-dev libc++abi-19-dev
cxx_flags: "-stdlib=libc++"
- version: 18
compiler: clang
install: sudo apt update && sudo apt install -y clang-18
Expand Down Expand Up @@ -80,6 +89,8 @@ jobs:
cxx: "g++-12"
cxx_flags: ""
exclude:
- compiler: gcc
version: 19
- compiler: gcc
version: 18
- compiler: gcc
Expand Down Expand Up @@ -293,8 +304,8 @@ jobs:
- compiler: clang
cc: "clang"
cxx: "clang++"
install: sudo apt update && sudo apt install -y clang-18
toolchain_root: "/usr/lib/llvm-18"
install: sudo apt update && sudo apt install -y clang-19
toolchain_root: "/usr/lib/llvm-19"
- compiler: gcc
cc: "gcc-13"
cxx: "g++-13"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Some of the extras are available only with C++20 or later.

*stdx* supports:

- clang 14 through 18
- clang 14 through 19
- gcc 12 through 13

See the [full documentation](https://intel.github.io/cpp-std-extensions/).
25 changes: 13 additions & 12 deletions include/stdx/atomic_bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,8 @@ class atomic_bitset {
return set(lsb, static_cast<msb_t>(l + length - 1), value, order);
}

auto set(std::memory_order order = std::memory_order_seq_cst)
LIFETIMEBOUND -> atomic_bitset & {
auto set(std::memory_order order = std::memory_order_seq_cst) LIFETIMEBOUND
-> atomic_bitset & {
atomic::store(storage, mask, order);
return *this;
}
Expand All @@ -167,32 +167,33 @@ class atomic_bitset {
storage, static_cast<elem_t>(~(bit << pos)), order)};
}

auto
reset(lsb_t lsb, msb_t msb,
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
auto reset(lsb_t lsb, msb_t msb,
std::memory_order order = std::memory_order_seq_cst)
-> bitset_t {
auto const l = to_underlying(lsb);
auto const m = to_underlying(msb);
auto const shifted_value = bit_mask<elem_t>(m, l);
return bitset_t{atomic::fetch_and(storage, ~shifted_value, order)};
}

auto
reset(lsb_t lsb, length_t len,
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
auto reset(lsb_t lsb, length_t len,
std::memory_order order = std::memory_order_seq_cst)
-> bitset_t {
auto const l = to_underlying(lsb);
auto const length = to_underlying(len);
return reset(lsb, static_cast<msb_t>(l + length - 1), order);
}

auto reset(std::memory_order order = std::memory_order_seq_cst)
LIFETIMEBOUND -> atomic_bitset & {
auto
reset(std::memory_order order = std::memory_order_seq_cst) LIFETIMEBOUND
-> atomic_bitset & {
atomic::store(storage, elem_t{}, order);
return *this;
}

template <typename T>
auto flip(T idx,
std::memory_order order = std::memory_order_seq_cst) -> bitset_t {
auto flip(T idx, std::memory_order order = std::memory_order_seq_cst)
-> bitset_t {
auto const pos = static_cast<std::size_t>(to_underlying(idx));
return bitset_t{
atomic::fetch_xor(storage, static_cast<elem_t>(bit << pos), order)};
Expand Down
76 changes: 38 additions & 38 deletions include/stdx/bit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ using std::bit_cast;

#if __cpp_lib_byteswap < 202110L
template <typename T>
[[nodiscard]] constexpr auto
byteswap(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto byteswap(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if constexpr (sizeof(T) == sizeof(std::uint16_t)) {
return __builtin_bswap16(x);
} else if constexpr (sizeof(T) == sizeof(std::uint32_t)) {
Expand All @@ -67,8 +67,8 @@ using std::byteswap;

#if __cpp_lib_bitops < 201907L
template <typename T>
[[nodiscard]] constexpr auto
countl_zero(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto countl_zero(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
if (x == 0) {
return std::numeric_limits<T>::digits;
}
Expand All @@ -88,8 +88,8 @@ countl_zero(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
}

template <typename T>
[[nodiscard]] constexpr auto
countr_zero(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto countr_zero(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
if (x == 0) {
return std::numeric_limits<T>::digits;
}
Expand All @@ -104,20 +104,20 @@ countr_zero(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
}

template <typename T>
[[nodiscard]] constexpr auto
countl_one(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto countl_one(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
return countl_zero(T(~x));
}

template <typename T>
[[nodiscard]] constexpr auto
countr_one(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto countr_one(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
return countr_zero(T(~x));
}

template <typename T>
[[nodiscard]] constexpr auto
popcount(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto popcount(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
if constexpr (sizeof(T) <= sizeof(unsigned int)) {
return __builtin_popcount(x);
} else if constexpr (sizeof(T) <=
Expand All @@ -130,8 +130,8 @@ popcount(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {

namespace detail {
template <typename T>
[[nodiscard]] constexpr auto
rotl(T x, T s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto rotl(T x, T s) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
#ifdef __clang__
if constexpr (sizeof(T) == sizeof(std::uint8_t)) {
return __builtin_rotateleft8(x, s);
Expand All @@ -148,8 +148,8 @@ rotl(T x, T s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
#endif
}
template <typename T>
[[nodiscard]] constexpr auto
rotr(T x, T s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto rotr(T x, T s) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
#ifdef __clang__
if constexpr (sizeof(T) == sizeof(std::uint8_t)) {
return __builtin_rotateright8(x, s);
Expand All @@ -168,8 +168,8 @@ rotr(T x, T s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
} // namespace detail

template <typename T>
[[nodiscard]] constexpr auto
rotl(T x, int s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto rotl(T x, int s) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if (s == 0) {
return x;
}
Expand All @@ -180,8 +180,8 @@ rotl(T x, int s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
}

template <typename T>
[[nodiscard]] constexpr auto
rotr(T x, int s) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto rotr(T x, int s) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if (s == 0) {
return x;
}
Expand All @@ -204,29 +204,29 @@ using std::rotr;

#if __cpp_lib_int_pow2 < 202002L
template <typename T>
[[nodiscard]] constexpr auto
has_single_bit(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, bool> {
[[nodiscard]] constexpr auto has_single_bit(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, bool> {
return x and not(x & (x - 1));
}

template <typename T>
[[nodiscard]] constexpr auto
bit_width(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, int> {
[[nodiscard]] constexpr auto bit_width(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, int> {
return std::numeric_limits<T>::digits - countl_zero(x);
}

template <typename T>
[[nodiscard]] constexpr auto
bit_ceil(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto bit_ceil(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if (x <= 1U) {
return 1U;
}
return T(1U << bit_width(x));
}

template <typename T>
[[nodiscard]] constexpr auto
bit_floor(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto bit_floor(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if (x == 0) {
return x;
}
Expand All @@ -240,8 +240,8 @@ using std::has_single_bit;
#endif

template <typename T>
[[nodiscard]] constexpr auto
to_le(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto to_le(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if constexpr (stdx::endian::native == stdx::endian::big) {
return byteswap(x);
} else {
Expand All @@ -250,8 +250,8 @@ to_le(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
}

template <typename T>
[[nodiscard]] constexpr auto
to_be(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto to_be(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if constexpr (stdx::endian::native == stdx::endian::little) {
return byteswap(x);
} else {
Expand All @@ -260,8 +260,8 @@ to_be(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
}

template <typename T>
[[nodiscard]] constexpr auto
from_le(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto from_le(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if constexpr (stdx::endian::native == stdx::endian::big) {
return byteswap(x);
} else {
Expand All @@ -270,8 +270,8 @@ from_le(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
}

template <typename T>
[[nodiscard]] constexpr auto
from_be(T x) noexcept -> std::enable_if_t<std::is_unsigned_v<T>, T> {
[[nodiscard]] constexpr auto from_be(T x) noexcept
-> std::enable_if_t<std::is_unsigned_v<T>, T> {
if constexpr (stdx::endian::native == stdx::endian::little) {
return byteswap(x);
} else {
Expand Down Expand Up @@ -341,8 +341,8 @@ template <typename To, typename From> constexpr auto bit_unpack(From arg) {

namespace detail {
template <typename T, std::size_t Bit>
constexpr auto
mask_bits() -> std::enable_if_t<Bit <= std::numeric_limits<T>::digits, T> {
constexpr auto mask_bits()
-> std::enable_if_t<Bit <= std::numeric_limits<T>::digits, T> {
if constexpr (Bit == std::numeric_limits<T>::digits) {
return std::numeric_limits<T>::max();
} else {
Expand Down
10 changes: 5 additions & 5 deletions include/stdx/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ class bitset {
return *this;
}

constexpr auto set(lsb_t lsb, msb_t msb,
bool value = true) LIFETIMEBOUND -> bitset & {
constexpr auto set(lsb_t lsb, msb_t msb, bool value = true) LIFETIMEBOUND
-> bitset & {
auto const l = to_underlying(lsb);
auto const m = to_underlying(msb);
auto [l_index, l_offset] = indices(l);
Expand Down Expand Up @@ -272,8 +272,8 @@ class bitset {
return *this;
}

constexpr auto set(lsb_t lsb, length_t len,
bool value = true) LIFETIMEBOUND -> bitset & {
constexpr auto set(lsb_t lsb, length_t len, bool value = true) LIFETIMEBOUND
-> bitset & {
auto const l = to_underlying(lsb);
auto const length = to_underlying(len);
return set(lsb, static_cast<msb_t>(l + length - 1), value);
Expand Down Expand Up @@ -398,7 +398,7 @@ class bitset {

constexpr auto operator<<=(std::size_t pos) LIFETIMEBOUND->bitset & {
auto dst = storage_size - 1;
auto const start = dst - pos / storage_elem_size;
auto const start = dst - (pos / storage_elem_size);
pos %= storage_elem_size;

if (pos == 0) {
Expand Down
Loading