* Jonathan Wakely: > On Sun, 14 Oct 2018 at 20:46, Florian Weimer <f...@deneb.enyo.de> wrote: >> >> * Rasmus Villemoes: >> >> > This is something I've sometimes found myself wishing was supported. The >> > idea being that one can say >> > >> > unsigned a[] = { [0] = 1, [1] = 3, [0] |= 4, ...} >> > >> > which would end up initializing a[0] to 5. As a somewhat realistic >> > example, suppose one is trying to build a bitmap at compile time, but >> > the bits to set are not really known in the sense that one can group >> > those belonging to each index in a usual | expression. Something like >> > >> > #define _(e) [e / 8] |= 1 << (e % 8) >> > const u8 error_bitmap[] = { _(EINVAL), _(ENAMETOOLONG), _(EBUSY), ... } >> >> I think it wouldn't be too hard to extend std::bitset with more >> compile-time operations to support this, if that's what you need. > > It's already doable using C++17:
I didn't doubt that, it's just that I'd expect to be able to use std::bitset for this. > template<int... N> > constexpr auto > make_error_bitmap() > { > using std::uint8_t; > using std::array; > constexpr auto max_index = std::max_element({N...}) / 8; > array<uint8_t, max_index+1> a; > [[maybe_unused]] uint8_t sink[] = { a[N/8] |= (1 << (N%8)), ... }; > return a; > } > > constexpr uint8_t error_bitmap = make_error_bitmap<EINVAL, > ENAMETOOLONG, EBUSY>(); > > (This won't compile in C++14 because std::array can't be modified in a > constant expression until C++17). You wrote that without testing it? I'm impressed. It's really close. template<int... N> constexpr auto make_error_bitmap() { using std::uint8_t; using std::array; constexpr auto max_index = std::max({ N... }); array<uint8_t, max_index+1> a{}; [[maybe_unused]] uint8_t sink[] = { a[N/8] |= (1 << (N%8)) ... }; return a; } constexpr auto error_bitmap = make_error_bitmap<EINVAL, ENAMETOOLONG, EBUSY>(); It seems to produce the intended bit pattern. > Of course the response will be "but I don't want to use C++" ... Indeed.