1

I'm attempting to do the following:

Say I have a class, A, and I have a static member variable, static_bit_id, that is a bitset<128>. At compile time, I want to create an ID that is a one hot bit of my choosing using bitset. I have a function that does this for me onehotbits(int n). for example:

bitset<128> b = onehotbits(4) // 0....01000

At compile time I want to assign to a static member of class A in such a way:

//in A.h
class A{
public:
    const static bitset<128> bits;
};

// in A.cpp
const bitset<128> A::bits = onehotbits(1);

Previously this pattern worked with a constexpr function that instead of bitset, took uint64_t's and shifted them. Now doing the same with bitsets violates constexpr rules since operator << for bitset< T > is not a constexpr.

I can't think of a way to accomplish this using constexpr, or in a namespace safe way in general. I can initialize bitset<128> with a string, but that violates constexpr.

I'm currently getting around this problem via:

const bitset<128> A::bits = bitset<128>(1) >> n;

which seems to violate DRIP, the only way to get rid of this problem appears to use a MACRO, which wouldn't be necessary if I could just use >> operator for bitset.

Note I want to avoid using other libraries for this, especially not boost, that is overkill.

Note, while my question is similar to Initializing c++ std::bitset at compile time it is not the same, since the solution there does not work for my problem (since I'm not simply using a literal, but a literal that would have to be created at compile time via some input)

Community
  • 1
  • 1
Krupip
  • 4,404
  • 2
  • 32
  • 54

1 Answers1

-1

Does this solve your problem?

constexpr auto onehotbits(int i)
{
    return 1<<(i-1);
}

class A{
public:
    constexpr static std::bitset<128> bits{onehotbits(4)};
};

constexpr std::bitset<128> A::bits;

Calling it via

int main()
{
    for(int i=0;i<128;++i)
    {
        std::cout<<A::bits[i]<<" ";   
    }
}

yields

0 0 0 1 0 0 0 0 ...

DEMO


With regard to the question whether the shift-operator is constexpr, see here. Didn't get that so far ... if not, the same behavior can attained via a template class.

Community
  • 1
  • 1
davidhigh
  • 14,652
  • 2
  • 44
  • 75
  • 1
    um, `auto` there is just `int`? – Yakk - Adam Nevraumont Mar 25 '17 at 02:30
  • @Yakk crap, you are right, good thing I didn't mark this as solved, for some reason I thought it would actually resolve to bitset due to how the demo was created. I can't give onehotbits a value greater than the precision of int here, I need something that works on with bitset. – Krupip Mar 25 '17 at 02:35
  • @snb: there's no resolution to bitset, the code is just using the plain bitset constructor taking an integral. This approach naturally fails for large numbers (however, 127 could be in the valid region of long long int) ... so I knew that this does not solve your problem in general -- and I should have mentioned it. – davidhigh Mar 25 '17 at 23:40
  • @davidhigh, it doesn't solve my problem at all, I already had the the solution for 64bits, you just don't even need auto to do it. its just static_cast(1) << n. I need something that works with N sized bitsets. Right now the macro does it for compile time, though it isn't ideal. – Krupip Mar 26 '17 at 01:00