All Projects → ClaasBontus → bitset2

ClaasBontus / bitset2

Licence: BSL-1.0 License
std::bitset with constexpr implementations plus additional features.

Programming Languages

C++
36643 projects - #6 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to bitset2

enumset
A library for compact bit sets containing enums.
Stars: ✭ 60 (-21.05%)
Mutual labels:  bitset
inqlude
Command line client for independent Qt library archive
Stars: ✭ 30 (-60.53%)
Mutual labels:  libraries
bitmap-elixir
Bitmap implementation in Elixir using binaries and integers. Fast space efficient data structure for lookups
Stars: ✭ 30 (-60.53%)
Mutual labels:  bitset
BitLens
🔎 Have your bits and eat them too! A C++17 bit lens container for vector types.
Stars: ✭ 20 (-73.68%)
Mutual labels:  bitset
constexpr-java
build-time code-execution for java, a bit like constexpr in C++11
Stars: ✭ 58 (-23.68%)
Mutual labels:  constexpr
lisp-project-of-the-day
Here I'll post notes about Quicklisp projects. Also I publish them on Twitter account svetlyak40wt.
Stars: ✭ 47 (-38.16%)
Mutual labels:  libraries
zig-gamedev
Building game development ecosystem for @ziglang!
Stars: ✭ 1,059 (+1293.42%)
Mutual labels:  libraries
awesome-libraries-resources
Awesome js and css libraries for web development.
Stars: ✭ 32 (-57.89%)
Mutual labels:  libraries
KGySoft.Drawing
KGy SOFT Drawing is a library for advanced image, icon and graphics handling.
Stars: ✭ 27 (-64.47%)
Mutual labels:  libraries
literal ipaddr
C++17 constexpr implementation of inet_addr / inet_aton / inet_pton
Stars: ✭ 19 (-75%)
Mutual labels:  constexpr
ignition
Gemini Protocol Client for Python Developers
Stars: ✭ 22 (-71.05%)
Mutual labels:  libraries
flags17
A comparison of different options to implement binary flags in C++17
Stars: ✭ 16 (-78.95%)
Mutual labels:  constexpr
sketch-library-unlinker
A Sketch plugin that can unlink symbols linked to a specific library, or unlink symbols that have been deleted in their libraries.
Stars: ✭ 21 (-72.37%)
Mutual labels:  libraries
jimhttp
A library collection and web microframework
Stars: ✭ 25 (-67.11%)
Mutual labels:  libraries
here-we-go
Contains hundreds of samples for learning Go.
Stars: ✭ 93 (+22.37%)
Mutual labels:  libraries
SwiftBitset
A fast Bitset class in Swift
Stars: ✭ 33 (-56.58%)
Mutual labels:  bitset
flutter web import js library
Import & use javascript libraries in your flutter web projects
Stars: ✭ 28 (-63.16%)
Mutual labels:  libraries
prjxray-db
Project X-Ray Database: XC7 Series
Stars: ✭ 52 (-31.58%)
Mutual labels:  bitset
kmm-awesome
An awesome list that curates the best KMM libraries, tools and more.
Stars: ✭ 598 (+686.84%)
Mutual labels:  libraries
android-charts
A curated list of Android Chart libraries.
Stars: ✭ 69 (-9.21%)
Mutual labels:  libraries

bitset2: bitset improved

Note
This version of bitset2 is for C++17. For C++14 checkout the corresponding branch.

Bitset2::bitset2 is a header only library. It provides the same functionality as std::bitset with the following extentions/changes.

Focus was set on having as many functions implemented as constexpr as possible. Moreover a second template parameter (with appropriate default) allows control of the underlying data structure (see below).

  • Copy and move constructors are specified constexpr.
  • Additional constexpr constructor bitset2( std::array<T,N> const & ), where T needs not necessarily be equal to base_t. T has to be an unsigned integral type.
  • Conversion from and to std::bitset.
  • Operators implemented as constexpr are ~, ==, !=, |, &, ^, << (shift left), >> (shift right), [] (bit access).
  • Non-const operators implemented as constexpr are <<=, >>=, |=, &=, ^=
  • Functions implemented as constexpr are test, none, any, all, count, to_ulong, to_ullong.
  • Non-const functions implemented as constexpr are set, reset, flip.
  • Additional constexpr operator + for adding two bitset2 objects.
  • Additional constexpr operators ++, --, +=.
  • Additional constexpr operators <, >, <=, >=.
  • Additional constexpr functions rotate_left and rotate_right for binary rotations.
  • Additional constexpr member functions rotate_left and rotate_right.
  • Additional member function to_hex_string() (see below).
  • Additional constexpr member function test_set( size_t bit, bool value= true ), which sets or clears the specified bit and returns its previous state. Throws out_of_range if bit >= N.
  • Additional constexpr function difference, which computes the set difference (bs1 & ~bs2) of two bitset2 objects.
  • Additional constexpr member function difference.
  • Additional constexpr member functions find_first() and find_next(size_t) returning the index of the first (next) bit set. Returning npos if all (remaining) bits are false.
  • Additional constexpr function complement2(bs) computing the two's complement (~bs +1).
  • Additional constexpr member function complement2.
  • Additional constexpr function reverse, which returns argument with bits reversed.
  • Additional constexpr member function reverse.
  • Additional constexpr function convert_to<n> for converting an m-bit bitset2 into an n-bit bitset2.
  • Additional constexpr function convert_to<n,T> for converting an m-bit bitset2 into an n-bit bitset2 with base_t=T.
  • Constexpr member function data() gives read access to the underlying array<base_t,N>. Here element with index zero is the least significant word.
  • Additional constexpr functions zip_fold_and and zip_fold_or. See below for details.

Examples

#include <iostream>
#include <array>
#include <cassert>
#include "bitset2.hpp"

template<size_t n_bits>
using BS2=      Bitset2::bitset2<n_bits>;

int main()
{
  using bs_128= BS2<128>;
  using base_t_128= bs_128::base_t;
  constexpr std::array<base_t_128,2>
            ar1{{ ~(base_t_128(0)), base_t_128(0xFEDCBA) }};
  constexpr bs_128                  b1{ ar1 };
  constexpr auto                    b1_add=  b1 + b1;
  constexpr auto                    b1_shft= b1 << 1; // binary shift
  static_assert( b1_add == b1_shft, "" );

  std::cout << b1.to_hex_string()       // 0000000000fedcbaffffffffffffffff
            << "\n"
            << b1_add.to_hex_string()   // 0000000001fdb975fffffffffffffffe
            << "\n";

  BS2<12>   b2;
  for( size_t c= 0; c < 12; c += 2 ) b2[c]= true;
  auto      b3= ~b2;
  std::cout << b2 << "\n";         // 010101010101
  std::cout << b2.flip() << "\n";  // 101010101010
  assert( b2 == b3 );

  BS2<7> const   b4{ "1110000" };
  auto const     b5= Bitset2::rotate_left( b4, 3 );
  std::cout << b4 << "\n"     // 1110000
            << b5 << "\n";    // 0000111

  BS2<7>        b6{ "1010010" };
  b6.reverse();
  std::cout << b6 << "\n";    // 0100101
}

The following example illustrates how non-const constexpr operators and functions are useful for writing constexpr functions. It converts between gray and binary coding.

template<size_t N,class T>
constexpr
Bitset2::bitset2<N,T>
binary_to_gray( Bitset2::bitset2<N,T> const &bs )
{ return bs ^ (bs >> 1); }

template<size_t N,class T>
constexpr
Bitset2::bitset2<N,T>
gray_to_binary( Bitset2::bitset2<N,T> bs )
{
  Bitset2::bitset2<N,T>   mask= bs >> 1;
  for( ; !mask.none(); mask >>= 1 )  bs ^= mask;
  return bs;
} // gray_to_binary

int main()
{
  using ULLONG= unsigned long long;
  constexpr std::array<ULLONG,2>  arr_01a{{ 0xFEFDFCFBFAF9F8F7ull, 1ull }};
  constexpr Bitset2::bitset2<129> bs_01a{ arr_01a };
  constexpr auto                  gray_01a= binary_to_gray( bs_01a );
  constexpr auto                  bin_01a=  gray_to_binary( gray_01a );

  static_assert( bs_01a == bin_01a, "" );
}

Template parameters and underlying data type

bitset2 is declared as

template< size_t N, class T >
class bitset2;

N is the number of bits and T has to be an unsigned integral type. Data represented by bitset2 objects are stored in elements of type std::array<T,n_array>.

T defaults to uint8_t, uint16_t, or uint32_t if N bits fit into these integers (and the type is supported by the system). T defaults to unsigned long long otherwise. The following aliases and constants are public within bitset2:

  • using base_t= T;
  • size_t n_array; Number of words in underlying array
  • using array_t= std::array<T,n_array>; Underlying data type

to_hex_string

Function to_hex_string takes - as an optional argument - an element of type hex_params, which is defined as

template< class CharT = char,
          class Traits = std::char_traits<CharT>,
          class Allocator = std::allocator<CharT> >
struct hex_params
{
  using str_t= std::basic_string<CharT,Traits,Allocator>;

  CharT        zeroCh=         CharT( '0' );
  CharT        aCh=            CharT( 'a' );
  bool         leadingZeroes=  true;
  bool         nonEmpty=       true;
  str_t        prefix;
};

It allows fine tuning the outcome of the function. In the following examples the output is shown in the comments.

bitset2<16>  b16_a( "0000101000011111" );
bitset2<16>  b16_b;
std::cout
  << b16_a.to_hex_string() << '\n'                                    // 0a1f
  << b16_a.to_hex_string( hex_params<>{'0', 'A', false, true, "0x"})  // 0xA1F
  << '\n'
  << b16_b.to_hex_string() << '\n'                                    // 0000
  << b16_b.to_hex_string( hex_params<>{'0', 'a', false, false, "0X"}) // 0X
  << '\n';

zip_fold_*

Functions zip_fold_and(bs1,bs2,f) and zip_fold_or(bs1,bs2,f) expect two variables of type bitset2 and a functional object f. The latter must accept two variables of type base_t and return a bool. zip_fold_* are mapped over the underlying std::array<base_t,n>s. They will short-circuit if possible, which can result in performance advantages. zip_fold_and returns true if f returns true for each pair of base_ts, while zip_fold_or returns true if f returns true for at least one pair of base_ts. In other words zip_fold_and and zip_fold_or are similar to std::inner_product(...,BinOp1 op1,BinOp2 op2) with op1 set to && and ||, resp.

For instance is_subset_of as proposed in p0125r0 can be implemented as follows.

template<size_t N,class T>
constexpr
bool
is_subset_of( Bitset2::bitset2<N,T> const &bs1,
              Bitset2::bitset2<N,T> const &bs2 ) noexcept
{
  using base_t= T;
  return Bitset2::zip_fold_and( bs1, bs2,
                                []( base_t v1, base_t v2 ) noexcept
                                  // Any bit unset in v2 must not be set in v1
                                  { return (v1 & ~v2) == 0; } );
}

constexpr Bitset2::bitset2<7>    b7_a( 0b1000101ull );
constexpr Bitset2::bitset2<7>    b7_b( 0b1010101ull );
static_assert( is_subset_of( b7_a, b7_b), "" );

Similarly an unequal function can be defined as

template<size_t N,class T>
bool
unequal( Bitset2::bitset2<N,T> const &bs1, Bitset2::bitset2<N,T> const &bs2 )
{
  using base_t= T;
  return Bitset2::zip_fold_or( bs1, bs2,
                               []( base_t v1, base_t v2 ) noexcept
                                 { return v1 != v2; } );
}

Trivia

The following code shows a counter based on a 128-bit integer. If the counter gets incremented once at each nanosecond, you have to wait for overflow for only 1.078 * 1022 years.

Bitset2::bitset2<128> c;
for( ;; ++c ) {}

Caveats

  • bitset2 requires a C++17 compliant compiler.
  • Tested with gcc 7 and clang 5.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].