This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: allowing compound assignment operators with designated initializers


* Jonathan Wakely:

> On Sun, 14 Oct 2018 at 20:46, Florian Weimer <fw@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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]