Create compile-time constants with first N bits set - c++

In C++17, is there are way to generate at compile-time a constant with the first N bits set?
In pseudocode, I am looking for something like:
constexpr uint32_t MY_CONSTANT = setBits<2>();
Would be equivalent to:
constexpr uint32_t MY_CONSTANT = 0b11;
In other words, given a compile-time constant N, return a compile-time constant M where bits 0 to (N-1) are 1 (set).

I don't think there's a ready made function for it in the standard library (although std::bitset::set is constexpr since C++23). You could make your own though:
template<class T, std::size_t N>
constexpr T setBits() {
if constexpr (N == sizeof(unsigned long long) * CHAR_BIT) return ~T{};
else return static_cast<T>((1ull << N) - 1);
}
constexpr auto MY_CONSTANT = setBits<std::uint32_t, 2>();
Example for setBits<std::uint8_t, 2>():
0b00000001
<< 2
-------------
= 0b00000100
0b00000100
- 1
-------------
= 0b00000011
Or negate 0 to get all bits set and right shift away all but N bits:
template<class T, std::size_t N>
constexpr T setBits() {
if constexpr (N == 0) return 0;
else return ~T{} >> (sizeof(T) * CHAR_BIT - N);
}

Related

Generating prime numbers at compile time

I am interested in how you can generate an array of prime numbers at compile time (I believe that the only way is using metaprogramming (in C++, not sure how this works in other languages)).
Quick note, I don't want to just say int primes[x] = {2, 3, 5, 7, 11, ...};, since I want to use this method in competitive programming, where source files cannot be larger than 10KB. So this rules out any pregenerated arrays of more than a few thousand elements.
I know that you can generate the fibonacci sequence at compile time for example, but that is rather easy, since you just add the 2 last elements. For prime numbers, I don't really know how to do this without loops (I believe it is possible, but I don't know how, using recursion I guess), and I don't know how loops could be evaluated at compile-time.
So I'm looking for an idea (at least) on how to approach this problem, maybe even a short example
We can do a compile time pre calculation of some prime numbers and put them in a compile time generated array. And then use a simple look up mechanism to get the value. This will work only to a small count of prime numbers. But it should show you the basic mechanism.
We will first define some default approach for the calculation a prime number as a constexpr function:
constexpr bool isPrime(size_t n) noexcept {
if (n <= 1) return false;
for (size_t i = 2; i*i < n; i++) if (n % i == 0) return false;
return true;
}
constexpr unsigned int primeAtIndex(size_t i) noexcept {
size_t k{3};
for (size_t counter{}; counter < i; ++k)
if (isPrime(k)) ++counter;
return k-1;
}
With that, prime numbers can easily be calculated at compile time. Then, we fill a std::array with all prime numbers. We use also a constexpr function and make it a template with a variadic parameter pack.
We use std::index_sequence to create a prime number for indices 0,1,2,3,4,5, ....
That is straigtforward and not complicated:
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
This function will be fed with an index sequence 0,1,2,3,4,... and a generator function and return a std::array<return type of generator function, ...> with the corresponding numbers, calculated by the generator.
We make a next function, that will call the above with the index sequence 1,2,3,4,...Max, like so:
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
And now, finally,
constexpr auto Primes = generateArray<100>(primeAtIndex);
will give us a compile-time std::array<unsigned int, 100> with the name Primes containing all 100 prime numbers. And if we need the i'th prime number, then we can simply write Primes [i]. There will be no calculation at runtime.
I do not think that there is a faster way to calculate the n'th prime number.
Please see the complete program below:
#include <iostream>
#include <utility>
#include <array>
// All done during compile time -------------------------------------------------------------------
constexpr bool isPrime(size_t n) noexcept {
if (n <= 1) return false;
for (size_t i = 2; i*i < n; i++) if (n % i == 0) return false;
return true;
}
constexpr unsigned int primeAtIndex(size_t i) noexcept {
size_t k{3};
for (size_t counter{}; counter < i; ++k)
if (isPrime(k)) ++counter;
return k-1;
}
// Some helper to create a constexpr std::array initilized by a generator function
template <typename Generator, size_t ... Indices>
constexpr auto generateArrayHelper(Generator generator, std::index_sequence<Indices...>) {
return std::array<decltype(std::declval<Generator>()(size_t{})), sizeof...(Indices) > { generator(Indices)... };
}
template <size_t Size, typename Generator>
constexpr auto generateArray(Generator generator) {
return generateArrayHelper(generator, std::make_index_sequence<Size>());
}
// This is the definition of a std::array<unsigned int, 100> with prime numbers in it
constexpr auto Primes = generateArray<100>(primeAtIndex);
// End of: All done during compile time -----------------------------------------------------------
// Some debug test driver code
int main() {
for (const auto p : Primes) std::cout << p << ' '; std::cout << '\n';
return 0;
}
By the way. The generateArray fucntionality will of course also work with other generator functions.
If you need for example triangle numbers, then you could use:
constexpr size_t getTriangleNumber(size_t row) noexcept {
size_t sum{};
for (size_t i{ 1u }; i <= row; i++) sum += i;
return sum;
}
and
constexpr auto TriangleNumber = generateArray<100>(getTriangleNumber);
would give you a compile time calculated constexpr std::array<size_t, 100> with triangle numbers.
For fibonacci numbers your could use
constexpr unsigned long long getFibonacciNumber(size_t index) noexcept {
unsigned long long f1{ 0ull }, f2{ 1ull }, f3{};
while (index--) { f3 = f2 + f1; f1 = f2; f2 = f3; }
return f2;
}
and
constexpr auto FibonacciNumber = generateArray<93>(getFibonacciNumber);
to get ALL Fibonacci numbers that fit in a 64 bit value.
So, a rather flexible helper.
Caveat
Big array sizes will create a compiler out of heap error.
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2.
Additionally compiled and tested with clang11.0 and gcc10.2
Language: C++17
The following is just to give you something to start with. It heavily relies on recursively instantiating types, which isn't quite efficient and I would not want to see in the next iteration of the implementation.
div is a divisor of x iff x%div == false:
template <int div,int x>
struct is_divisor_of : std::conditional< x%div, std::false_type, std::true_type>::type {};
A number x is not prime, if there is a p < x that is a divisor of x:
template <int x,int p=x-2>
struct has_divisor : std::conditional< is_divisor_of<p,x>::value, std::true_type, has_divisor<x,p-1>>::type {};
If no 1 < p < x divides x then x has no divisor (and thus is prime):
template <int x>
struct has_divisor<x,1> : std::false_type {};
A main to test it:
int main()
{
std::cout << is_divisor_of<3,12>::value;
std::cout << is_divisor_of<5,12>::value;
std::cout << has_divisor<12>::value;
std::cout << has_divisor<13>::value;
}
Output:
1010
Live Demo.
PS: You probably better take the constexpr function route, as suggested in a comment. The above is just as useful as recursive templates to calculate the fibonacci numbers (ie not really useful other than for demonstration ;).
With "simple" constexpr, you might do:
template <std::size_t N>
constexpr void fill_next_primes(std::array<std::size_t, N>& a, std::size_t n)
{
std::size_t i = (a[n - 1] & ~0x1) + 1;
while (!std::all_of(a.begin(), a.begin() + n, [&i](int e){ return i % e != 0; })) {
i += 2;
}
a[n] = i;
}
template <std::size_t N>
constexpr std::array<std::size_t, N> make_primes_array()
{
// use constexpr result
// to ensure to compute at compile time,
// even if `make_primes_array` is not called in constexpr context
constexpr auto res = [](){
std::array<std::size_t, N> res{2};
for (std::size_t i = 1; i != N; ++i) {
fill_next_primes(res, i);
}
return res;
}();
return res;
}
Demo

Is it possible to use array of bit fields?

I am curious to know, Is it possible to use array of bit fields? Like:
struct st
{
unsigned int i[5]: 4;
};
No, you can't. Bit field can only be used with integral type variables.
C11-§6.7.2.1/5
A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type.
Alternatively you can do this
struct st
{
unsigned int i: 4;
} arr_st[5];
but its size will be 5 times the size of a struct (as mentioned in comment by #Jonathan Leffler) having 5 members each with bit field 4. So, it doesn't make much sense here.
More closely you can do this
struct st
{
uint8_t i: 4; // Will take only a byte
} arr_st[5];
C does not support arrays of bit-fields, so the short answer is no.
For very large arrays, it might be worthwhile to pack values, 2 per byte, this way:
#define ARRAY_SIZE 1000000
unsigned char arr[(ARRAY_SIZE + 1) / 2];
int get_4bits(const unsigned char *arr, size_t index) {
return arr[index >> 1] >> ((index & 1) << 2);
}
int set_4bits(unsigned char *arr, size_t index, int value) {
arr[index >> 1] &= ~ 0x0F << ((index & 1) << 2);
arr[index >> 1] |= (value & 0x0F) << ((index & 1) << 2);
}
You can write your own class for this case. For example:
template <typename T, size_t ITEM_BIT_SIZE>
class BitArrayView {
private:
static const size_t ARRAY_ENTRY_BITS = sizeof(T) * 8;
static const T ITEM_MASK = (~((T) 0)) >> (ARRAY_ENTRY_BITS - ITEM_BIT_SIZE);
T* arr;
public:
struct ItemMutator {
BitArrayView* owner;
size_t index;
T operator=(T value) {
return owner->set(index, value);
}
operator T() {
return owner->get(index);
}
};
const size_t bitSize;
BitArrayView(T* arr, size_t length) : arr(arr), bitSize((length * ARRAY_ENTRY_BITS) / ITEM_BIT_SIZE) {}
T get(size_t index) const {
size_t bitPos = index * ITEM_BIT_SIZE;
size_t arrIndex = bitPos / ARRAY_ENTRY_BITS;
size_t shiftCount = bitPos % ARRAY_ENTRY_BITS;
return (arr[arrIndex] >> shiftCount) & ITEM_MASK;
}
T set(size_t index, T value) {
size_t bitPos = index * ITEM_BIT_SIZE;
size_t arrIndex = bitPos / ARRAY_ENTRY_BITS;
size_t shiftCount = bitPos % ARRAY_ENTRY_BITS;
value &= ITEM_MASK; // trim
arr[arrIndex] &= ~(ITEM_MASK << shiftCount); // clear target bits
arr[arrIndex] |= value << shiftCount; // insert new bits
return value;
}
ItemMutator operator[](size_t index) {
return { this, index };
}
};
And then you may access it like a "bit field" array:
// create array of some uints
unsigned int arr[5] = { 0, 0, 0, 0, 0 };
// set BitArrayView of 3-bit entries on some part of the array
// (two indexes starting at 1)
BitArrayView<unsigned int, 3> arrView(arr + 1, 2);
// should equal 21 now => (2 * 32) / 3
arrView.bitSize == 21;
for (unsigned int i = 0; i < arrView.bitSize; i++) {
arrView[i] = 7; // eg.: 0b111;
}
// now arr[1] should have all bits set
// and arr[2] should have all bits set but last one unset => (2 * 32) % 3 = 1
// the remaining arr items should stay untouched
This is simple implementation which should work with unsigned backing arrays only.
Notice "the mutator trick" in operator[] ;).
Of course some other operators could be implemented, too.
No, bitfields only support integral types. But for very small arrays, you can store each element as a property individually, for example:
struct st
{
unsigned int i0: 1;
unsigned int i1: 1;
unsigned int i2: 1;
unsigned int i3: 1;
unsigned int i4: 1;
};
The disadvantage of this approach is obviously that you can no longer use array-based operations or methods, such as run-time indexing, but it works well enough for basic applications like mathematical vectors.

Signed int from bitset<n>

How can I convert given bitset of a length N (where 0 < N < 64) to signed int. For instance, given:
std::bitset<13> b("1111111101100");
I would like to get back the value -20, not 8172.
My approach:
int t = (static_cast<int>(b.to_ullong()));
if(t > pow(2, 13)/2)
t -= pow(2, 13);
Is there a more generic way to approach this?
Edit: Also the bitset is actually std::bitset<64> and the N can be run-time known value passed by other means.
We can write a function template to do this for us:
template <size_t N, class = std::enable_if_t<(N > 0 && N < 64)>
int64_t as_signed(const std::bitset<N>& b)
{
int64_t v = b.to_ullong(); // safe since we know N < 64
return b[N-1] ? ((1LL << N) - v) : v;
}
Perhaps best is to let compiler to sign-extend it itself:
struct S { int64_t x:N; } s;
int64_t result = s.x = b.to_ullong();
Compiler likely optimizes that s out.
It must be is safe since the int64_t (where available) is required to be two's complement.
Edit: When the actual bit count to extend is only known run-time then most portable algorithm is with mask:
// Do this if bits above position N in b may be are not zero to clear those.
int64_t x = b.to_ullong() & ((1ULL << N) - 1);
// Otherwise just
int64_t x = b.to_ullong();
int64_t const mask = 1ULL << (N - 1);
int64_t result = (x ^ mask) - mask;
A slightly faster but less portable method with dynamic bit counts is with bit shifts (works when architecture has signed arithmetic right shift):
int const shift = 64 - N;
int64_t result = ((int64_t)b.to_ullong() << shift) >> shift;

Problems using template meta-programming to count number of set bits in integer

As an experiment, I'm trying to write template code to count the number of set bits in an integer at compile-time. Here is my first attempt:
template<unsigned long long x>
struct BitCount
{
static const int result = (x == 0) ? 0 : ((x & 1) + BitCount<(x >> 1)>::result);
};
This gives errors.
Visual Studio 2013
error C2065: 'result' : undeclared identifier
ideone.com
error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating ‘BitCount<0ull>::result’
How can I fix this error properly?
Ok so I changed it to
#include <iostream>
using namespace std;
template<unsigned long long x>
struct BitCount
{
static const int result;
};
template<unsigned long long x>
const int BitCount<x>::result = (x == 0) ? 0 : ((x & 1) + BitCount<(x >> 1)>::result);
template<unsigned long long x>
int bitcount()
{
return BitCount<x>::result;
}
int main()
{
cout << bitcount<5>() << endl;
cout << bitcount<1>() << endl;
cout << bitcount<3>() << endl;
cout << bitcount<0>() << endl;
return 0;
}
ideone.com correctly outputs: 2 1 2 0
Visual Studio 2013 incorrectly outputs: 1 1 2 0
Is this a bug in VS or is something in my code incorrect?
Thanks!
You need a specialization for the terminating case of zero:
template<>
struct BitCount<0>
{
static const int result = 0;
};
Otherwise, you simply rely on the primary template so that BitCount<0>::result is defined as true ? 0 : BitCount<0>::result which is an endlessly recursive template instantiation. It still needs to instantiate the else-clause even if it isn't evaluated.
You need to specialize for the base-case, or you get infinite compile-time recursion there (the definition of the base-case is dependent on the definition of the base-case).
Also, it looks better if you inline the initialization:
template<unsigned long long x>
struct PopCount
{
static const int result = (x&1)+BitCount<(x>>1)>::result;
};
template<>
struct PopCount<0ULL>
{
static const int result = 0;
}
BTW: Using constexpr for the result member instead of const static is better, even better a function instead (C++11):
constexpr int popCount(unsigned long long x) {
return x ? int(x&1) + popCount(x>>1) : 0;
}
As a last step, make the function iterative for better performance when executing it at runtime (C++14).
constexpr int popCount(unsigned long long x) {
int r = 0;
for(; x; x &= x-1)
++r;
return r;
}
This assignment x &= x-1; clears the lowest-order set bit, so fewer iterations neccessary.
You may use the following:
template<unsigned long long x>
struct BitCount
{
static constexpr const int result = (x & 1) + BitCount<(x >> 1)>::result;
};
template<>
struct BitCount<0>
{
static constexpr const int result = 0;
};
Live example
or simply a constexpr function
constexpr int bitCount(unsigned long long x)
{
return (x == 0) ? 0 : int(x & 1ULL) + bitCount(x >> 1);
}
BTW, you may use the bit trick x & (x-1) to mask off the lowest set bit instead of doing x >> 1 as follow:
constexpr int bitCount(unsigned long long x)
{
return (x == 0) ? 0 : 1 + bitCount(x & (x - 1));
}

Initializing double at compile-time

I'm writting a compile-time implementation of floating-point arithmetic through template metaprogramming. My implementation has the following characteristics:
16 bit signed integer exponent.
32 bit unsigned integer mantissa, with no implicit most significant 1 (Thats done to simplify debugging).
The type is as follows:
template<bool S , std::int16_t E , std::uint32_t M>
struct number
{
static constexpr const bool sign = S;
static constexpr const std::int16_t exponent = E;
static constexpr const std::uint32_t mantissa = M;
};
The operations work well, but now I need a method to extract those values at compile-time and get the corresponding double values. Since the goal of compile-time arithmetic is to speed up computation injecting the solutions directly on the executable, I need a way to effectively initialize a double constant at compile-time.
So simple solutions involving std::pow( 2.0 , E ) are not allowed.
As far I know double-precission IEE754 floats have a 10 bit signed exponent and a 53 bit wide unsigned integer mantissa. My attemped solution was to use type punning via an union:
template<bool S , std::int16_t E , std::uint32_t M>
struct to_runtime<tml::floating::number<S,E,M>>
{
static constexpr const long unsigned int mantissa = M << (53 - 32);
static constexpr const int exponent = E + (53 - 32);
struct double_parts
{
unsigned int sign : 1;
int exponent : 10;
long unsigned int mantissa : 53;
};
union double_rep
{
double d;
double_parts parts;
};
static constexpr const double_parts parts = { .sign = ((bool)S) ? 0 : 1 , .exponent = exponent , .mantissa = mantissa };
static constexpr const double_rep rep = { .parts = parts };
static constexpr double execute()
{
return rep.d;
}
};
But this solution is not portable, invokes undefined behaviour (Since when doing type punning we read the member of the union which has not been written), and also I have some issues when realizing the conversion (This solution doesn't return the correct number).
Is there any other way to initialize a double at compile-time given my data (sign, exponent, mantissa)?
You may implement a constexpr pow2(std::int16_t), something like:
constexpr double pow2(std::int16_t e)
{
return e == 0 ? 1. :
e > 0 ? 2. * pow2(std::int16_t(e - 1)) :
0.5 * pow2(std::int16_t(e + 1));
}
or
constexpr double pow2(std::int16_t e)
{
return e == 0 ? 1. :
((e & 1) ? (e > 0 ? 2. : 0.5) : 1.)
* pow2(std::int16_t(e / 2))
* pow2(std::int16_t(e / 2));
}
And then
template<bool S , std::int16_t E , std::uint32_t M>
struct number
{
static constexpr const double value = (sign ? -1. : 1.) * M * pow2(E);
};
Live example