From 7c87de05001885eaaf920e9753523015fe6d54c8 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Tue, 24 Jun 2025 21:29:56 -0400 Subject: [PATCH 1/7] First couple sections of new doc --- README.md | 292 +++++++++++++++++++++++++++------------------- doc/benchmarks.md | 118 +++++++++++++++++++ 2 files changed, 291 insertions(+), 119 deletions(-) create mode 100644 doc/benchmarks.md diff --git a/README.md b/README.md index a8f81b4c..63367f06 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,179 @@ ![Actions](https://github.com/PeterCDMcLean/BitLib/actions/workflows/cmake-multi-platform.yml/badge.svg?branch=master)[![Coverage Status](https://coveralls.io/repos/github/PeterCDMcLean/BitLib/badge.svg?branch=master)](https://coveralls.io/github/PeterCDMcLean/BitLib?branch=master) +# Overview + +This project provides convenient and efficient stl-like containers and algorithms for bit access. + +# Table of Contents + +- [Contributors](#contributors) +- [Requirements](#requirements) +- [Example](#example) +- [CMake](#cmake) +- [Sized Literal](#literal) +- [Containers](#containers) + - [bit_array](#bit_array) + - [bit_vector](#bit_vector) +- [Views](#views) + - [bit_array_ref](#bit_array_ref) + - [bit_span](#bit_span) + - [mdspan with bit_default_accessor](#mdspan) +- [Iterators and References](#iterators_and_references) + - [bit_iterator](#bit_iterator) + - [bit_reference](#bit_reference) + - [bit_word_pointer_adapter](#bit_word_pointer_adapter) + - [bit_word_reference_adapter](#bit_word_reference_adapter) +- [Algorithms](#algorithms) +- [Testing](#testing) +- [License](#license) + +# Contributors +- Vincent Reverdy +- Bryce Kille +- Peter McLean + +# Requirements + +_gcc_ or _clang_ + +`C++23` + +# Example + +# CMake +### options +bitlib provides the following cmake options and their defaults +```cmake +option(BITLIB_HWY "Build with google highway SIMD extensions" OFF) +option(BITLIB_BENCHMARK "Build bitlib benchmarks" OFF) +option(BITLIB_EXAMPLE "Build bitlib examples" OFF) +option(BITLIB_TEST "Build bitlib tests" OFF) +option(BITLIB_TEST_WERROR "Build bitlib tests with -Werror" OFF) +option(BITLIB_MDSPAN "Accessor Support for mdspan" ON) +``` + +Options can be set through command line switches: +``` +cmake -G .. -DBITLIB_MDSPAN=OFF +``` +or within cmake files before the bitlib targets have been added +```cmake +set(BITLIB_MDSPAN OFF CACHE BOOL "Disable mdspan" FORCE) +``` + +The bitlib targets are added through one of two ways: + +### add_subdirectory +```cmake +add_subdirectory(..../bitlib) +add_executable(example) +target_sources(example PRIVATE example.cpp) +target_link_libraries(example PRIVATE bitlib::bitlib) +``` + +### FetchContent +```cmake +include(FetchContent) +FetchContent_Declare( + bitlib + GIT_REPOSITORY https://github.com/bkille/bitlib.git + GIT_TAG origin/master +) +FetchContent_MakeAvailable(bitlib) + +add_executable(example) +target_sources(example PRIVATE example.cpp) +target_link_libraries(example PRIVATE bitlib::bitlib) +``` + +# Literal + +This provides a sized literal for compile-time bit_array. + +There are three components of the literal: +``` + [base_prefix][size']data + | | | + |---> | <--| +ex: 0xC'7B; +``` + - base prefix + - size + * before first apostrophe `'` + - data + +### Base +Similar to standard C++ literals, the base is optionally prefixed: + +- default base 10 +- `0b` binary base +- `0x` hexadecimal base +- `0` octal base + +### Size +This user-defined literal repurposes the apostrophe `'` numeric separator in the C++ standard. +The digits of the numeric leading up to the first apostrophe are the number of bits in the literal. +All digits that follow the first apostrophe are digits in the actual numeric. +Any apostophes after the first are considered standard numeric separators. + +> [!IMPORTANT] +> The size is expressed in the same base as the rest of the literal + +### Data + +Numeric literal in the base described + +> [!CAUTION] +> This literal does not support negative literals + +> [!CAUTION] +> This literal does not support literals above 64 bits + +### Examples + +``` +#include "bitlib/bit.hpp" + +auto dec_lit = 31'123456; // 31 bit base 10 literal +auto hex_lit = 0x1F'1E240; // 31 bit hex literal +auto bin_lit = 0b11111'11110001001000000; //31 bit binary literal +auto oct_lit = 037'361100; // 31 bit octal literal +``` + +# Containers +## bit_array +## bit_vector +# Views +## bit_array_ref +## bit_span +## mdspan with bit_default_accessor +# Iterators and References +## bit_iterator +## bit_reference +## bit_word_pointer_adapter +## bit_word_reference_adapter +# Algorithms +accumulate +copy_backward +copy +count +equal +fill +find +move +reverse +rotate +shift +swap_ranges +to_string +transform + + + + + + **This repository acts as an efficient replacement of `std::vector`. It provides implementations of many of the functions in [``](https://en.cppreference.com/w/cpp/algorithm) optimized for containers of bits, in addition to providing a `bit_vector` class which has roughly the same interface as `std::vector`**. This project is built on "[bit iterators](https://github.com/vreverdy/bit)" developed by Vincent Reverdy and many of the implementations in `include/bit-algorithms` come from some of my previous work with Vincent [here](https://github.com/vreverdy/bit-algorithms). @@ -136,122 +309,3 @@ Value: 01000100 --> Sequence: 00100010 # Documentation Given that the majority of the library is focused on having the same interface as the C++ STL iterators, containers, and algorithms, users should use the official [STL documentation website](https://en.cppreference.com/). We do plan on adding our own documentation in the future, however. - - -# Performance Benchmarks -I used Google's [benchmark](https://github.com/google/benchmark) library for computing benchmarks. Each benchmark is formatted as `{bit, BitArray, std}::function` (size) [(alignment-tags)]. - - * `bit` is for this library, `BitArray` is for the popular C-based [BitArray library](https://github.com/noporpoise/BitArray), [dynamic_bitset](https://github.com/pinam45/dynamic_bitset) is a header-only library similar to Boost's dynamic_bitset, and`std` is the standard library operating on the infamous `vector`. -* (size) denotes the size of the container in bits. `small = 1 << 8`, `medium= 1 << 16`, `large = 1 << 24`, `huge = 1 << 31` -* (alignment-tags) refers to the memory alignment of the bit-iterators. `U` means the iterator does not fall on a word boundary, `R` means the iterator is placed at random, and `A` means the iterator is aligned with a word boundary. - -For example, `bit::rotate (large) (ARA)` refers to our library's implementation of the `rotate` algorithm operating on a container of 65536 bits, where `first` and `last` are aligned but `n_first` is selected at random. - -``` ---------------------------------------------------------------------------------------- -Benchmark Time CPU Iterations ---------------------------------------------------------------------------------------- -bit::set (large) 1.90 ns 1.90 ns 367974893 -dynamic_bitset::set (large) 2.37 ns 2.37 ns 296837879 -bitarray::set (large) 2.19 ns 2.19 ns 319133940 -std::set (large) 2.39 ns 2.39 ns 293135332 -bit::shift_left (small) 26.8 ns 26.8 ns 25929070 -bit::shift_left (small) (UU) 22.4 ns 22.4 ns 31233265 -dynamic_bitset::shift_left (small) 13.1 ns 13.1 ns 53627207 -bitarray::shift_left (small) 38.2 ns 38.2 ns 18339126 -std::shift_left (small) 345 ns 345 ns 2029283 -bit::shift_left (large) 371224 ns 371211 ns 1886 -bit::shift_left (large) (UU) 371536 ns 371530 ns 1880 -dynamic_bitset::shift_left (large) 638896 ns 638880 ns 1097 -bitarray::shift_left (large) 3156273 ns 3156003 ns 222 -std::shift_left (large) 105227752 ns 105223527 ns 7 -bit::shift_right (small) 26.9 ns 26.9 ns 25976563 -bit::shift_right (small) (UU) 39.3 ns 39.3 ns 17962533 -dynamic_bitset::shift_right (small) 12.2 ns 12.2 ns 57419526 -bitarray::shift_right (small) 38.1 ns 38.1 ns 18325350 -std::shift_right (small) 504 ns 504 ns 1386280 -bit::shift_right (large) 413297 ns 413269 ns 1693 -bit::shift_right (large) (UU) 413692 ns 413655 ns 1682 -dynamic_bitset::shift_right (large) 557287 ns 557305 ns 1257 -bitarray::shift_right (large) 3156463 ns 3156516 ns 222 -std::shift_right (large) 210100788 ns 210083631 ns 3 -bit::reverse (small) (UU) 43.4 ns 43.4 ns 16112098 -bitarray::reverse (small) (UU) 95.1 ns 95.1 ns 7387177 -std::reverse (small) 419 ns 419 ns 1677069 -bit::reverse (large) 1245260 ns 1245160 ns 563 -bit::reverse (large) (UU) 1800771 ns 1800680 ns 389 -bitarray::reverse (large) 16899481 ns 16898587 ns 41 -bitarray::reverse (large) (UU) 22719408 ns 22720393 ns 31 -std::reverse (large) 293563397 ns 293542850 ns 2 -bit::transform(UnaryOp) (small) 8.75 ns 8.75 ns 80079214 -bit::transform(UnaryOp) (small) (UU) 16.6 ns 16.6 ns 42254961 -dynamic_bitset::transform(UnaryOp) (small) 4.00 ns 4.00 ns 169219246 -bitarray::transform(UnaryOp) (small) 8.39 ns 8.39 ns 83877004 -std::transform(UnaryOp) (small) 763 ns 763 ns 917975 -bit::transform(UnaryOp) (large) 373982 ns 373950 ns 1853 -bit::transform(UnaryOp) (large) (UU) 2059234 ns 2059268 ns 339 -dynamic_bitset::transform(UnaryOp) (large) 379368 ns 379368 ns 1805 -bitarray::transform(UnaryOp) (large) 739552 ns 739544 ns 881 -std::transform(UnaryOp) (large) 197977698 ns 197969224 ns 4 -bit::transform(BinaryOp) (small) 4.38 ns 4.38 ns 160002060 -bit::transform(BinaryOp) (small) (UU) 42.1 ns 42.1 ns 16549758 -dynamic_bitset::transform(BinaryOp) (small) 4.36 ns 4.36 ns 160692979 -bitarray::transform(BinaryOp) (small) 10.7 ns 10.7 ns 66178974 -std::transform(BinaryOp) (small) 855 ns 855 ns 832115 -bit::transform(BinaryOp) (large) 763642 ns 763574 ns 912 -bit::transform(BinaryOp) (large) (UU) 10966202 ns 10966406 ns 64 -dynamic_bitset::transform(BinaryOp) (large) 758617 ns 758574 ns 906 -bitarray::transform(BinaryOp) (large) 518286 ns 518267 ns 1177 -std::transform(BinaryOp) (large) 802270688 ns 802303941 ns 1 -bit::rotate (small) 131 ns 131 ns 16525922 -std::rotate (small) 1782 ns 1782 ns 417293 -bit::rotate (large) 7333284 ns 7333170 ns 96 -std::rotate (large) 514697313 ns 514718779 ns 1 -bit::count (small) 8.14 ns 8.14 ns 86522765 -dynamic_bitset::count (small) 6.29 ns 6.29 ns 108878018 -bitarray::count (small) 5.47 ns 5.47 ns 133692569 -std::count (small) 234 ns 234 ns 2997782 -bit::count (large) 365194 ns 365159 ns 1919 -dynamic_bitset::count (large) 365279 ns 365269 ns 1919 -bitarray::count (large) 917302 ns 917185 ns 764 -std::count (large) 58934071 ns 58931785 ns 12 -bit::swap_ranges (small) 9.58 ns 9.57 ns 73128377 -bit::swap_ranges (small) (UU) 19.7 ns 19.7 ns 35498474 -std::swap_ranges (small) 756 ns 756 ns 912041 -bit::swap_ranges (large) 852205 ns 852241 ns 821 -bit::swap_ranges (large) (UU) 5691899 ns 5692145 ns 123 -std::swap_ranges (large) 522198664 ns 522161939 ns 1 -bit::copy (small) (UU) 25.0 ns 25.0 ns 28200772 -std::copy (small) 707 ns 707 ns 990757 -bit::copy (large) (UU) 5952278 ns 5951729 ns 116 -std::copy (large) 189551338 ns 189554366 ns 4 -bit::equal (small) (UU) 13.1 ns 13.1 ns 53616228 -std::equal (small) 886 ns 886 ns 790035 -bit::equal (large) (UU) 1960399 ns 1960375 ns 357 -std::equal (large) 234389098 ns 234398907 ns 3 -bit::move (small) (UU) 23.5 ns 23.5 ns 29764745 -std::move (small) 706 ns 706 ns 992054 -bit::move (large) (UU) 5135837 ns 5135619 ns 136 -std::move (large) 188961979 ns 188953500 ns 4 -bit::copy_backward (small) (UU) 39.0 ns 39.0 ns 17977387 -std::copy_backward (small) 527 ns 527 ns 1313265 -bit::copy_backward (large) (UU) 9163333 ns 9163038 ns 76 -std::copy_backward (large) 444362971 ns 444350668 ns 2 -bit::fill (small) (UU) 6.48 ns 6.48 ns 108934237 -dynamic_bitset::fill (small) 4.79 ns 4.79 ns 146205764 -bitarray::fill (small) 14.5 ns 14.5 ns 48030428 -std::fill (small) 9.15 ns 9.15 ns 76612702 -bit::fill (large) (UU) 440400 ns 440396 ns 1590 -dynamic_bitset::fill (large) 429375 ns 429359 ns 1631 -bitarray::fill (large) 369732 ns 369736 ns 1964 -std::fill (large) 356517 ns 356488 ns 1894 -bit::find (small) (UU) 3.10 ns 3.10 ns 228714994 -dynamic_bitset::find (small) 3.05 ns 3.05 ns 229830138 -bitarray::find (small) 7.38 ns 7.38 ns 99039746 -std::find (small) 110 ns 110 ns 6311725 -bit::find (large) (UU) 182002 ns 182006 ns 3850 -dynamic_bitset::find (large) 259896 ns 259908 ns 2696 -bitarray::find (large) 252434 ns 252445 ns 2774 -std::find (large) 28570723 ns 28567762 ns 25 -``` - diff --git a/doc/benchmarks.md b/doc/benchmarks.md new file mode 100644 index 00000000..e799d361 --- /dev/null +++ b/doc/benchmarks.md @@ -0,0 +1,118 @@ + +# Performance Benchmarks +I used Google's [benchmark](https://github.com/google/benchmark) library for computing benchmarks. Each benchmark is formatted as `{bit, BitArray, std}::function` (size) [(alignment-tags)]. + + * `bit` is for this library, `BitArray` is for the popular C-based [BitArray library](https://github.com/noporpoise/BitArray), [dynamic_bitset](https://github.com/pinam45/dynamic_bitset) is a header-only library similar to Boost's dynamic_bitset, and`std` is the standard library operating on the infamous `vector`. +* (size) denotes the size of the container in bits. `small = 1 << 8`, `medium= 1 << 16`, `large = 1 << 24`, `huge = 1 << 31` +* (alignment-tags) refers to the memory alignment of the bit-iterators. `U` means the iterator does not fall on a word boundary, `R` means the iterator is placed at random, and `A` means the iterator is aligned with a word boundary. + +For example, `bit::rotate (large) (ARA)` refers to our library's implementation of the `rotate` algorithm operating on a container of 65536 bits, where `first` and `last` are aligned but `n_first` is selected at random. + +``` +--------------------------------------------------------------------------------------- +Benchmark Time CPU Iterations +--------------------------------------------------------------------------------------- +bit::set (large) 1.90 ns 1.90 ns 367974893 +dynamic_bitset::set (large) 2.37 ns 2.37 ns 296837879 +bitarray::set (large) 2.19 ns 2.19 ns 319133940 +std::set (large) 2.39 ns 2.39 ns 293135332 +bit::shift_left (small) 26.8 ns 26.8 ns 25929070 +bit::shift_left (small) (UU) 22.4 ns 22.4 ns 31233265 +dynamic_bitset::shift_left (small) 13.1 ns 13.1 ns 53627207 +bitarray::shift_left (small) 38.2 ns 38.2 ns 18339126 +std::shift_left (small) 345 ns 345 ns 2029283 +bit::shift_left (large) 371224 ns 371211 ns 1886 +bit::shift_left (large) (UU) 371536 ns 371530 ns 1880 +dynamic_bitset::shift_left (large) 638896 ns 638880 ns 1097 +bitarray::shift_left (large) 3156273 ns 3156003 ns 222 +std::shift_left (large) 105227752 ns 105223527 ns 7 +bit::shift_right (small) 26.9 ns 26.9 ns 25976563 +bit::shift_right (small) (UU) 39.3 ns 39.3 ns 17962533 +dynamic_bitset::shift_right (small) 12.2 ns 12.2 ns 57419526 +bitarray::shift_right (small) 38.1 ns 38.1 ns 18325350 +std::shift_right (small) 504 ns 504 ns 1386280 +bit::shift_right (large) 413297 ns 413269 ns 1693 +bit::shift_right (large) (UU) 413692 ns 413655 ns 1682 +dynamic_bitset::shift_right (large) 557287 ns 557305 ns 1257 +bitarray::shift_right (large) 3156463 ns 3156516 ns 222 +std::shift_right (large) 210100788 ns 210083631 ns 3 +bit::reverse (small) (UU) 43.4 ns 43.4 ns 16112098 +bitarray::reverse (small) (UU) 95.1 ns 95.1 ns 7387177 +std::reverse (small) 419 ns 419 ns 1677069 +bit::reverse (large) 1245260 ns 1245160 ns 563 +bit::reverse (large) (UU) 1800771 ns 1800680 ns 389 +bitarray::reverse (large) 16899481 ns 16898587 ns 41 +bitarray::reverse (large) (UU) 22719408 ns 22720393 ns 31 +std::reverse (large) 293563397 ns 293542850 ns 2 +bit::transform(UnaryOp) (small) 8.75 ns 8.75 ns 80079214 +bit::transform(UnaryOp) (small) (UU) 16.6 ns 16.6 ns 42254961 +dynamic_bitset::transform(UnaryOp) (small) 4.00 ns 4.00 ns 169219246 +bitarray::transform(UnaryOp) (small) 8.39 ns 8.39 ns 83877004 +std::transform(UnaryOp) (small) 763 ns 763 ns 917975 +bit::transform(UnaryOp) (large) 373982 ns 373950 ns 1853 +bit::transform(UnaryOp) (large) (UU) 2059234 ns 2059268 ns 339 +dynamic_bitset::transform(UnaryOp) (large) 379368 ns 379368 ns 1805 +bitarray::transform(UnaryOp) (large) 739552 ns 739544 ns 881 +std::transform(UnaryOp) (large) 197977698 ns 197969224 ns 4 +bit::transform(BinaryOp) (small) 4.38 ns 4.38 ns 160002060 +bit::transform(BinaryOp) (small) (UU) 42.1 ns 42.1 ns 16549758 +dynamic_bitset::transform(BinaryOp) (small) 4.36 ns 4.36 ns 160692979 +bitarray::transform(BinaryOp) (small) 10.7 ns 10.7 ns 66178974 +std::transform(BinaryOp) (small) 855 ns 855 ns 832115 +bit::transform(BinaryOp) (large) 763642 ns 763574 ns 912 +bit::transform(BinaryOp) (large) (UU) 10966202 ns 10966406 ns 64 +dynamic_bitset::transform(BinaryOp) (large) 758617 ns 758574 ns 906 +bitarray::transform(BinaryOp) (large) 518286 ns 518267 ns 1177 +std::transform(BinaryOp) (large) 802270688 ns 802303941 ns 1 +bit::rotate (small) 131 ns 131 ns 16525922 +std::rotate (small) 1782 ns 1782 ns 417293 +bit::rotate (large) 7333284 ns 7333170 ns 96 +std::rotate (large) 514697313 ns 514718779 ns 1 +bit::count (small) 8.14 ns 8.14 ns 86522765 +dynamic_bitset::count (small) 6.29 ns 6.29 ns 108878018 +bitarray::count (small) 5.47 ns 5.47 ns 133692569 +std::count (small) 234 ns 234 ns 2997782 +bit::count (large) 365194 ns 365159 ns 1919 +dynamic_bitset::count (large) 365279 ns 365269 ns 1919 +bitarray::count (large) 917302 ns 917185 ns 764 +std::count (large) 58934071 ns 58931785 ns 12 +bit::swap_ranges (small) 9.58 ns 9.57 ns 73128377 +bit::swap_ranges (small) (UU) 19.7 ns 19.7 ns 35498474 +std::swap_ranges (small) 756 ns 756 ns 912041 +bit::swap_ranges (large) 852205 ns 852241 ns 821 +bit::swap_ranges (large) (UU) 5691899 ns 5692145 ns 123 +std::swap_ranges (large) 522198664 ns 522161939 ns 1 +bit::copy (small) (UU) 25.0 ns 25.0 ns 28200772 +std::copy (small) 707 ns 707 ns 990757 +bit::copy (large) (UU) 5952278 ns 5951729 ns 116 +std::copy (large) 189551338 ns 189554366 ns 4 +bit::equal (small) (UU) 13.1 ns 13.1 ns 53616228 +std::equal (small) 886 ns 886 ns 790035 +bit::equal (large) (UU) 1960399 ns 1960375 ns 357 +std::equal (large) 234389098 ns 234398907 ns 3 +bit::move (small) (UU) 23.5 ns 23.5 ns 29764745 +std::move (small) 706 ns 706 ns 992054 +bit::move (large) (UU) 5135837 ns 5135619 ns 136 +std::move (large) 188961979 ns 188953500 ns 4 +bit::copy_backward (small) (UU) 39.0 ns 39.0 ns 17977387 +std::copy_backward (small) 527 ns 527 ns 1313265 +bit::copy_backward (large) (UU) 9163333 ns 9163038 ns 76 +std::copy_backward (large) 444362971 ns 444350668 ns 2 +bit::fill (small) (UU) 6.48 ns 6.48 ns 108934237 +dynamic_bitset::fill (small) 4.79 ns 4.79 ns 146205764 +bitarray::fill (small) 14.5 ns 14.5 ns 48030428 +std::fill (small) 9.15 ns 9.15 ns 76612702 +bit::fill (large) (UU) 440400 ns 440396 ns 1590 +dynamic_bitset::fill (large) 429375 ns 429359 ns 1631 +bitarray::fill (large) 369732 ns 369736 ns 1964 +std::fill (large) 356517 ns 356488 ns 1894 +bit::find (small) (UU) 3.10 ns 3.10 ns 228714994 +dynamic_bitset::find (small) 3.05 ns 3.05 ns 229830138 +bitarray::find (small) 7.38 ns 7.38 ns 99039746 +std::find (small) 110 ns 110 ns 6311725 +bit::find (large) (UU) 182002 ns 182006 ns 3850 +dynamic_bitset::find (large) 259896 ns 259908 ns 2696 +bitarray::find (large) 252434 ns 252445 ns 2774 +std::find (large) 28570723 ns 28567762 ns 25 +``` + From ce4c19e6db83e709fced4349c53585b022b759e0 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sat, 5 Jul 2025 22:28:33 -0400 Subject: [PATCH 2/7] Small tweaks/improvements to CMake constraint/requirements --- CMakeLists.txt | 14 +++++++++----- README.md | 35 ++++++++++++++++++----------------- benchmark/CMakeLists.txt | 2 ++ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32f3b4a5..b2616ae2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,14 @@ -# specify the C++ standard -cmake_minimum_required(VERSION 3.14) -cmake_policy(SET CMP0168 NEW) -cmake_policy(SET CMP0167 NEW) +cmake_minimum_required(VERSION 3.20) + +if (POLICY CMP0168) + cmake_policy(SET CMP0168 NEW) +endif() +if (POLICY CMP0167) + cmake_policy(SET CMP0167 NEW) +endif() # set the project name -project(BitLib VERSION 0.3.0) +project(BitLib VERSION 1.0.0) option(BITLIB_HWY "Build with google highway SIMD extensions" OFF) option(BITLIB_BENCHMARK "Build bitlib benchmarks" OFF) diff --git a/README.md b/README.md index 63367f06..fe942661 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,10 @@ This project provides convenient and efficient stl-like containers and algorithm # Requirements -_gcc_ or _clang_ - -`C++23` +- _gcc_ or _clang_ +- `C++23` +- cmake verison 3.20. + * cmake version 3.31 if compiling bitlib's benchmark suite # Example @@ -155,20 +156,20 @@ auto oct_lit = 037'361100; // 31 bit octal literal ## bit_word_pointer_adapter ## bit_word_reference_adapter # Algorithms -accumulate -copy_backward -copy -count -equal -fill -find -move -reverse -rotate -shift -swap_ranges -to_string -transform + - accumulate + - copy_backward + - copy + - count + - equal + - fill + - find + - move + - reverse + - rotate + - shift + - swap_ranges + - to_string + - transform diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 709c3b21..3bcd87e9 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,3 +1,5 @@ +cmake_minimum_required(VERSION 3.31) + set(BENCHMARK_ENABLE_GTEST_TESTS OFF) include(FetchContent) From 1a6d6b4d6b8792d56c1cc1eb78746a8d68fcd3a7 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 6 Jul 2025 15:06:07 -0400 Subject: [PATCH 3/7] Add documentation on bit_array and mdspan --- README.md | 288 ++++++++---------- .../bit-containers/bit_mdspan_accessor.hpp | 4 +- 2 files changed, 134 insertions(+), 158 deletions(-) diff --git a/README.md b/README.md index fe942661..d4397a5d 100644 --- a/README.md +++ b/README.md @@ -13,14 +13,15 @@ This project provides convenient and efficient stl-like containers and algorithm - [Example](#example) - [CMake](#cmake) - [Sized Literal](#literal) -- [Containers](#containers) +- [Slice Operator](#slice-operator) +- [Owning Containers](#owning-containers) - [bit_array](#bit_array) - [bit_vector](#bit_vector) -- [Views](#views) +- [Non-owning Views](#non-owning-views) - [bit_array_ref](#bit_array_ref) - [bit_span](#bit_span) - - [mdspan with bit_default_accessor](#mdspan) -- [Iterators and References](#iterators_and_references) + - [mdspan with bit_default_accessor](#mdspan-with-bit-accessors) +- [Iterators and References](#iterators-and-references) - [bit_iterator](#bit_iterator) - [bit_reference](#bit_reference) - [bit_word_pointer_adapter](#bit_word_pointer_adapter) @@ -56,7 +57,7 @@ option(BITLIB_MDSPAN "Accessor Support for mdspan" ON) ``` Options can be set through command line switches: -``` +```bash cmake -G .. -DBITLIB_MDSPAN=OFF ``` or within cmake files before the bitlib targets have been added @@ -93,17 +94,18 @@ target_link_libraries(example PRIVATE bitlib::bitlib) This provides a sized literal for compile-time bit_array. -There are three components of the literal: +There are four components of the literal: ``` - [base_prefix][size']data - | | | - |---> | <--| -ex: 0xC'7B; + [base_prefix][size']data_b + | | | | + |---> | <--| |--- '_b' suffix +ex: 0xC'7B_b; ``` - base prefix - size * before first apostrophe `'` - data + - `_b` suffix ### Base Similar to standard C++ literals, the base is optionally prefixed: @@ -132,25 +134,134 @@ Numeric literal in the base described > [!CAUTION] > This literal does not support literals above 64 bits +### Suffix + +The literal must be followed by the user defined literal suffix: _b + ### Examples -``` +```c++ #include "bitlib/bit.hpp" -auto dec_lit = 31'123456; // 31 bit base 10 literal -auto hex_lit = 0x1F'1E240; // 31 bit hex literal -auto bin_lit = 0b11111'11110001001000000; //31 bit binary literal -auto oct_lit = 037'361100; // 31 bit octal literal +auto dec_lit = 31'123456_b; // 31 bit base 10 literal +auto hex_lit = 0x1F'1E240_b; // 31 bit hex literal +auto bin_lit = 0b11111'11110001001000000_b; //31 bit binary literal +auto oct_lit = 037'361100_b; // 31 bit octal literal +``` + +# Slice Operator + +All containers and views provide a slice operator which take a half-open range and +return a [mutable view](#bit_array_ref) of the given range. +Example: + +```c++ +auto lit = 0x1F'1E240_b; +auto ref = lit(4, 8); // reference the bits from [4,8) i.e. 4,5,6,7. +assert(ref == 0x4'4_b); +assert(ref == 0x4); +lit(4, 8) = 0xA; +assert(lit == 0x1F'1E2A0_b); +assert(ref(1,4) == 0x5); // array_ref can be sliced further ``` -# Containers +# Owning Containers + ## bit_array + +Provides compile-time or construction time container for an array of bits. + +### Compile-time: +Storage is on the stack. The number of bytes is the nearest power of two integral size. +```c++ +bit_array<11> vec_11(0x123); // Will use a uint16_t to hold the data +bit_array<65> vec_65(); // Will use a uint64_t to hold the data +``` +The storage word type can be specified: +```c++ +bit_array<65, uint8_t> vec_65_bytes(); // 9 bytes on stack +``` + +### Construction-time +A non-resizable construction-time storage is used when the N (aka Extent) +is equal to std::dynamic_extent (similar to std::span). +Since the N template parameter is by default std::dynamic_extent this is the +default template specialization `bit_array<>`. + +```c++ +bit_array<> vec_11(11, 0x123); // 8 bytes on stack for data, 8 bytes for size +bit_array<> vec_64(65); // same stack size as above + 16 bytes in heap +``` +The storage word size is by default uintptr_t. +The container will perform small buffer optimization +when the number of bits is equal or less than `bitsof()` typically 64. + ## bit_vector -# Views +# Non-Owning Views ## bit_array_ref ## bit_span -## mdspan with bit_default_accessor -# Iterators and References +## mdspan with bit accessors + +The std::mdspan container (C++23) can be used with a custom accessors that +use proxy pointers and references. This makes it suitable for accessing multi-dimensional +bit dense data. + +There are three flavours of accessors: + - `bit_default_accessor` which povides individual `bit_value` access which behaves like a typical stl mdspan + - `bit_word_accessor` which provides compile-time bit array value type access + - `bit_word_accessor` which provides construction-time bit array value type access +> [!INFO] +> The dynamic_extent `bit_word_accessor` requires a non-default constructor to the accessor. +> The mdspan must use the mdspan constructor which takes the +> container pointer, extent instance and accessor instance. +bit_value: +```c++ +bit_array<7*8*9> bits(); +std::mdspan< + bit::bit_value, + std::extents, + std::layout_right, + bit::bit_default_accessor +> myspan ( + &bits[0] +); +myspan[6, 7, 8] = bit::bit1; // set last bit to one +assert(bits[7*8*9-1] == bit::bit1); +``` + +Compile-time: +```c++ +bit_array<7*8*9> bits(); +std::mdspan< + bit::bit_word_accessor<7>::element_type, + std::extents, + std::layout_right, + bit::bit_word_accessor<7> +> myspan ( + &bits[0] +); +myspan[7, 8] = 0x7'7F_b; // set last 7 bit word to all ones. +assert(bits(7*8*9-7, 7*8*9) == 0x7F); +``` + +Construction-time: +```c++ +bit_array<> bits(7*8*9); +std::mdspan< + bit::bit_word_accessor<>::element_type, + std::dextents, + std::layout_right, + bit::bit_word_accessor<> +> myspan ( + &bits[0], + std::dextents{8, 9}, + bit::bit_word_accessor<>(7) +); +myspan[7, 8] = 0x7'7F_b; // set last 7 bit word to all ones. +assert(bits(7*8*9-7, 7*8*9) == 0x7F); +``` + +# Iterators and References ## bit_iterator ## bit_reference ## bit_word_pointer_adapter @@ -168,145 +279,8 @@ auto oct_lit = 037'361100; // 31 bit octal literal - rotate - shift - swap_ranges - - to_string + - to_from_string - transform - - - -**This repository acts as an efficient replacement of `std::vector`. It provides implementations of many of the functions in [``](https://en.cppreference.com/w/cpp/algorithm) optimized for containers of bits, in addition to providing a `bit_vector` class which has roughly the same interface as `std::vector`**. - -This project is built on "[bit iterators](https://github.com/vreverdy/bit)" developed by Vincent Reverdy and many of the implementations in `include/bit-algorithms` come from some of my previous work with Vincent [here](https://github.com/vreverdy/bit-algorithms). - -# Example -The code below is from `example/src/example1.cpp`. While the type of word that the bitvector is built off of is templated and you can use any unsigned type, it is likely that you'll want to use `uint64_t` or another 64 bit unsigned type, as that will leverage the most bit-parallelism. -```cpp -#include -#include "bitlib/bitlib.hpp" - -int main() { - bit::bit_vector bv1 ("011111010010"); - std::cout << "Original bitvec: " << bv1.debug_string() << std::endl; - // Original bitvec: 01111101 0010 - - // Same behavior as std::reverse - bit::reverse(bv1.begin(), bv1.end()); - std::cout << "Reversed bitvec: " << bv1.debug_string() << std::endl; - // Reversed bitvec: 01001011 1110 - - // Same behavior as std::rotate - bit::rotate(bv1.begin(), bv1.begin() + 3, bv1.end()); - std::cout << "Rotated bitvec: " << bv1.debug_string() << std::endl; - // Rotated bitvec: 01011111 0010 - - // Same behavior as the corresponding std::vector::push_back and std::vector::insert - bv1.push_back(bit::bit0); - bv1.insert(bv1.end(), 10, bit::bit1); - std::cout << "Extended bitvec: " << bv1.debug_string() << std::endl; - // Extended bitvec: 01011111 00100111 1111111 - - return 0; -} -``` - -# Installation -BitLib is a header-only libarary. Currently, the BitLib library requires at least `-std=c++17`. - - -## CMake -You can automatically fetch the library using Cmake's `FetchContent`. - -```cmake -include(FetchContent) -FetchContent_Declare( - bitlib - GIT_REPOSITORY https://github.com/bkille/bitlib.git - GIT_TAG origin/master -) -FetchContent_MakeAvailable(bitlib) - -add_executable(example example.cpp) -target_link_libraries(example bitlib::bitlib) -``` - -## Manual include -Alternatively, you can copy the `include/bitlib` directory to somewhere in your include path. - -## SIMD support, testing and benchmarking - -SIMD support (enabled via Google's [highway](https://github.com/google/highway) library) can be enabled by defining `BITLIB_HWY`. For example, with `cmake`, you can run `cmake -DBITLIB_HWY=1`. Other options can be found in the `CMakeLists.txt` file: - -```cmake -option(BITLIB_HWY "Build with google highway SIMD extensions" OFF) -option(BITLIB_BENCHMARK "Build bitlib benchmarks" OFF) -option(BITLIB_EXAMPLE "Build bitlib examples" OFF) -option(BITLIB_TEST "Build bitlib tests" OFF) -option(BITLIB_PROFILE "Buid simple example for profiling" OFF) -option(BITLIB_COVERAGE "Compute test coverage" OFF) -``` - -# Usage -The goal of BitLib is to be as similar to the C++ STL as possible. The interface of most functions and classes are the same as they are in the STL. Instead of the values being `bool`, we have `bit::bit_value`, which can take on either `bit::bit0` or `bit::bit1`. - -## Containers - Right now, the only container I have implemented is the bitvector. `bit::bit_vector` is essentially a wrapper around `std::vector`. The interfaces are nearly identical. In addition to the normal `vector` constructors, you can also provide a string to construct your bitvector: -```cpp -using WordType = uint64_t; -bit::bit_vector bvec1 ("011111010010"); -``` - -While the type of word that the bitvector is built off of is templated and you can use any unsigned type, it is likely that you'll want to use `uint64_t` or another 64 bit unsigned type, as that will leverage the most bit-parallelism. - -## Algorithms -The algorithms again work in the same manner as the STL. The functions provided here have the same interface as those in the STL, however under the hood, they take advantage of bit-parallelism. It should be noted that if there is an STL algorithm that is not supported yet by BitLib, you can still use the STL implementation. For example: -```cpp -using WordType = uint64_t; -bit::bit_vector bvec1 ("011111010010"); -bit::bit_vector bvec2 = bvec1; -bit::equal(bvec1.begin(), bvec1.end(), bvec2.begin(), bvec1.end()); -std::equal(bvec1.begin(), bvec1.end(), bvec2.begin(), bvec1.end()); // Also works, but much slower as it works bit-by-bit -``` - -For algorithms which take a function (i.e. `bit::transform`), the function should have `WordType` as the input types as well as the return type. For example, to compute the intersection of two bitvectors: -```cpp -using WordType = uint64_t; -auto binary_op = std::bit_and(); - -// Store the AND of bitvec1 and bitvec2 in bitvec3 -auto bitret = bit::transform( - bitvec1.begin(), - bitvec1.end(), - bitvec2.begin(), - bitvec3.begin() - binary_op); -``` - -## Iterators -The bit-iterators are the foundation of the library. In most cases, users will only need to work w/ the `bit::bit_vector::begin()` and `bit::bit_vector::end()` methods to obtain iterators. However, constructing a bit iterator from any address is also straightforward: -```cpp -using WordType = uint64_t; -std::array wordArr = {1,2,3,4}; -bit::bit_iterator(&(wordArr[0])); // Constructs a bit iterator starting from the first bit from the first word of the vector -bit::bit_iterator(&(wordArr[0]), 1); // Constructs a bit iterator from the second bit (position 1) of the first word of the vector -``` - -In order to grab the underlying word that a bit pointed to by a bit_iterator comes from, you can use the `bit_iterator.base()` function. - -It is worth noting that the "position" of a bit always increases from LSB to MSB. For those looking to create their own algorithms from bit_iterators, this can be a common "gotcha". For example, shifting a word to the right by `k` will eliminate the first `k` bits of the container. This is only important to those implementing their own algorithms. `bit::shift_*` works as described in the documentation i.e. `shift_right` shifts the container towards `end()` and `shift_left` shifts the container towards `begin()`. - -``` - MSB|<-----|LSB -Position: 76543210 -Value: 01010001 --> Sequence: 10001010 - - -// bit::shift_right by 2 - MSB|<-----|LSB -Position: 76543210 -Value: 01000100 --> Sequence: 00100010 -``` - -# Documentation -Given that the majority of the library is focused on having the same interface as the C++ STL iterators, containers, and algorithms, users should use the official [STL documentation website](https://en.cppreference.com/). We do plan on adding our own documentation in the future, however. diff --git a/include/bitlib/bit-containers/bit_mdspan_accessor.hpp b/include/bitlib/bit-containers/bit_mdspan_accessor.hpp index 9b8cd82b..80076231 100644 --- a/include/bitlib/bit-containers/bit_mdspan_accessor.hpp +++ b/include/bitlib/bit-containers/bit_mdspan_accessor.hpp @@ -47,7 +47,9 @@ struct bit_word_accessor : private detail::container_size_storagesize(); } - constexpr bit_word_accessor() : detail::container_size_storage() {} + constexpr bit_word_accessor() + requires(N != std::dynamic_extent) + : detail::container_size_storage() {} constexpr bit_word_accessor(const size_t& size) requires(N == std::dynamic_extent) : detail::container_size_storage(size) {} From deb2443eb68cb2a8e7ed44300a9201f5dad370c1 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 6 Jul 2025 15:33:35 -0400 Subject: [PATCH 4/7] Add a small section about policy --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index d4397a5d..b576234c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This project provides convenient and efficient stl-like containers and algorithm - [CMake](#cmake) - [Sized Literal](#literal) - [Slice Operator](#slice-operator) +- [Policy](#policy) - [Owning Containers](#owning-containers) - [bit_array](#bit_array) - [bit_vector](#bit_vector) @@ -165,6 +166,14 @@ assert(lit == 0x1F'1E2A0_b); assert(ref(1,4) == 0x5); // array_ref can be sliced further ``` +# Policy + +Template class controlling behavior such as expansion (aka sign-extension) and truncation +The containers can be specialized with a custom policy type to +throwing an exception on loss of data or clamping instead of truncation + +The default policy truncates when necessary and sign extends for conversion to/from signed integrals + # Owning Containers ## bit_array From 8f6dc716e5f71ac8020655b192a557fb76c4b217 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 6 Jul 2025 15:39:16 -0400 Subject: [PATCH 5/7] Add a note about licensing --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index b576234c..816efc02 100644 --- a/README.md +++ b/README.md @@ -291,5 +291,9 @@ assert(bits(7*8*9-7, 7*8*9) == 0x7F); - to_from_string - transform +# License +This open source library is license under [BSD 3-Clause License](./LICENSE). +> [!IMPORTANT] +> This library uses libpopcnt which has its own [BSD 2-Clause License](include/bitlib/bit-algorithms/libpopcnt.h) From a9ee5975a4416be8babed0d1c6dbb2aac733c50a Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 6 Jul 2025 15:59:18 -0400 Subject: [PATCH 6/7] Update license file to include libpopcnt license --- LICENSE | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index e66d784a..e0e49caf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -BSD 3-Clause License +BitLib BSD 3-Clause License Copyright (c) 2022, Bryce Kille All rights reserved. @@ -27,3 +27,34 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------THIRD-PARTY LICENSES------------------------------- + +libpopcnt.h - C/C++ library for counting the number of 1 bits (bit +population count) in an array as quickly as possible using +specialized CPU instructions i.e. POPCNT, AVX2, AVX512, NEON. + +Copyright (c) 2016 - 2020, Kim Walisch +Copyright (c) 2016 - 2018, Wojciech Muła +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 1f2efbf4fe6c754b2702c4cb8b29c9b748989d28 Mon Sep 17 00:00:00 2001 From: Peter McLean Date: Sun, 6 Jul 2025 16:16:56 -0400 Subject: [PATCH 7/7] Try harder to remove undesired paths from clang coverage --- .github/actions/coverage_clang/action.yml | 5 +- .github/actions/coverage_epilogue/action.yml | 86 -------------------- .github/actions/coverage_prologue/action.yml | 34 -------- 3 files changed, 3 insertions(+), 122 deletions(-) delete mode 100644 .github/actions/coverage_epilogue/action.yml delete mode 100644 .github/actions/coverage_prologue/action.yml diff --git a/.github/actions/coverage_clang/action.yml b/.github/actions/coverage_clang/action.yml index e75f6698..f3a93909 100644 --- a/.github/actions/coverage_clang/action.yml +++ b/.github/actions/coverage_clang/action.yml @@ -24,17 +24,18 @@ runs: # Show summary coverage report llvm-cov report ${{ inputs.build-output-dir }}/test/bitlib-tests \ -instr-profile=coverage.profdata \ - -ignore-filename-regex='/usr/|_deps/|libpopcnt\.h|test/inc/|test/src/' + -ignore-filename-regex='/usr/.*|.*_deps/.*|.*/libpopcnt\.h|.*test/inc/.*|.*test/src/.*' # Generate HTML report llvm-cov show ${{ inputs.build-output-dir }}/test/bitlib-tests \ -instr-profile=coverage.profdata \ -format=html \ -output-dir=out/coverage_clang \ - -ignore-filename-regex='/usr/|_deps/|libpopcnt\.h|test/inc/|test/src/' + -ignore-filename-regex='/usr/.*|.*_deps/.*|.*/libpopcnt\.h|.*test/inc/.*|.*test/src/.*' llvm-cov export ${{ inputs.build-output-dir }}/test/bitlib-tests \ -instr-profile=coverage.profdata \ + -ignore-filename-regex='/usr/.*|.*_deps/.*|.*/libpopcnt\.h|.*test/inc/.*|.*test/src/.*' \ -format=lcov > coverage_clang.info - name: Upload coverage artifact diff --git a/.github/actions/coverage_epilogue/action.yml b/.github/actions/coverage_epilogue/action.yml deleted file mode 100644 index 9515efc8..00000000 --- a/.github/actions/coverage_epilogue/action.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: "Coverage Epilogue" -description: "Processes coverage information with lcov and uploads it to coveralls/codecov" -inputs: - build-output-dir: - required: true - description: 'Build output directory' - compiler: - required: true - description: 'Compiler in use' - GITHUB_TOKEN: - required: true - -runs: - using: "composite" - steps: - - name: Generate Coverage Report (gcc) - if: ${{ inputs.compiler == 'gcc' }} - shell: bash - run: | - # Capture actual coverage data after tests - lcov --capture \ - --directory "${{ inputs.build-output-dir }}" \ - --output-file coverage.info \ - --ignore-errors mismatch - - # Combine with baseline - lcov --add-tracefile coverage.baseline \ - --add-tracefile coverage.info\ - --output-file coverage.info - - # Clean the coverage report from system and external deps - lcov --remove coverage.info \ - '/usr/*' \ - '*/_deps/*' \ - '*/include/bitlib/bit-algorithms/libpopcnt.h' \ - '*/test/inc/*' \ - '*/test/src/*' \ - --output-file coverage.info - - # Show a summary in the logs - lcov --list coverage.info - - # Generate an HTML report - genhtml coverage.info --output-directory out/coverage - - - name: Generate Coverage Report (clang) - if: ${{ inputs.compiler == 'clang' }} - shell: bash - run: | - # Merge raw coverage into .profdata - llvm-profdata merge -sparse coverage.profraw -o coverage.info - - # Show summary coverage report - llvm-cov report ${{ inputs.build-output-dir }}/test/bitlib-tests \ - -instr-profile=coverage.info \ - -ignore-filename-regex='/usr/|_deps/|libpopcnt\.h|test/inc/|test/src/' - - # Generate HTML report - llvm-cov show ${{ inputs.build-output-dir }}/test/bitlib-tests \ - -instr-profile=coverage.info \ - -format=html \ - -output-dir=out/coverage \ - -ignore-filename-regex='/usr/|_deps/|libpopcnt\.h|test/inc/|test/src/' - - - name: Upload coverage artifact - uses: actions/upload-artifact@v4 - with: - name: coverage-report - path: | - out/coverage - coverage.baseline - coverage.info - - - name: Coveralls - if: ${{ inputs.compiler != 'clang' }} - uses: coverallsapp/github-action@master - with: - github-token: ${{ inputs.GITHUB_TOKEN }} - path-to-lcov: coverage.info - - - name: Upload to Codecov - uses: codecov/codecov-action@v5 - with: - files: coverage.info - flags: unittests - name: codecov-coverage-report diff --git a/.github/actions/coverage_prologue/action.yml b/.github/actions/coverage_prologue/action.yml deleted file mode 100644 index 883b77c6..00000000 --- a/.github/actions/coverage_prologue/action.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: "Coverage Prologue" -description: "Installs lcov and generates the baseline coverage" -inputs: - build-output-dir: - required: true - description: 'Build output directory' - compiler: - required: true - description: 'Compiler in use' - -runs: - using: "composite" - steps: - - name: "Install lcov" - if: ${{ inputs.compiler == 'gcc' }} - shell: bash - run: | - sudo apt-get update - sudo apt-get install -y lcov - - - name: "Initialize 0% coverage baseline" - if: ${{ inputs.compiler == 'gcc' }} - shell: bash - run: | - lcov --capture --initial \ - --base-directory "$GITHUB_WORKSPACE" \ - --directory "${{ inputs.build-output-dir }}" \ - --output-file coverage.baseline \ - --ignore-errors mismatch - - - name: "LLVM profile env var" - if: ${{ inputs.compiler == 'clang' }} - shell: bash - run: echo "LLVM_PROFILE_FILE=${GITHUB_WORKSPACE}/coverage.profraw" >> $GITHUB_ENV \ No newline at end of file