$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Is there any interest in type-safe container of bool flags with noexcept guarantees?
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2017-03-22 17:14:08
I agree that bitfields are not the way to go. They suffer from a number of
deficiencies - not least that each bit is *not a separate object* so they
are problematic i multithreaded environments. They also of course carry no
type information.
However, I am struggling to see how the proposed class is any more useful
than a std::tuple classes that support a bool conversion operator.
Can you demonstrate a use case where a tuple is inadequate?
On 22 March 2017 at 17:02, Roman Orlov via Boost <boost_at_[hidden]>
wrote:
> On 21.03.2017 21:23, Steven Watanabe via Boost wrote:
>
>>
>> what's wrong with
>> struct animal {
>>   bool eats_meat : 1;
>>   bool eats_grass : 1;
>>   bool has_tail : 1;
>> };
>>
>>
> There are several reasons I don't like that approach
>
> While declaring a variable of type 'animal' you should always keep in
> mind to initialize it with empty initializer
>   animal a1; // bit fields are not initialized
>   animal a2{}; // now it's ok, bits are set to zeros
>
> When you want to initialize some fields (eats_grass, has_tail) you have
> to write several lines of code
>   animal a1{};
>   a1.eats_grass = 1;
>   a1.has_tail = 1;
>
> Of course, it can be done in one line with initializer list
>   animal a1{0, 1, 1};
>
> But we don't write a code ones, we are about to support it for a long
> time. One day we decided to add a new bit field to structure
>   struct animal {
>     bool can_fly : 1; // yeah, somebody puts it on the first position
>     bool eats_meat : 1;
>     bool eats_grass : 1;
>     bool has_tail : 1;
>   };
>
> What will happen with all of list initializers? There will be bugs we
> can't detect at compile time.
>   animal a1{0, 1, 1}; // now it doesn't work properly
>
> We have to find all of such initializers and rewrite them
>   animal a1{0, 0, 1, 1};
>
> To prevent this I propose to abstract from strict ordering and use
> typed entities
>   animal a1{flag<eats_grass>{1}, flag<has_tail>{1}};
>
> And what about bitwise operations on plain structures? While working
> with bool properties conjunction and disjunction are needed fairly
> often. For each structure you'll have to implement them manually.
> Of course it's better to have it out of the box
>   auto a1 = animal{flag<eats_gass>{1}} | animal{flag<eats_meat>{1}};
>
> Sometimes it's needed to test that all flags are set or at least one.
> And again for each structure you'll have to implement it manually.
> It's better to have these functions in container
>   auto a1 = animal{flag<eats_gass>{1}};
>   assert( (!a1.all()) );
>   assert( (!a1.any<eats_meat, has_tail>()) ); // with some syntax sugar
>
> Managing typed entities allows you to test common properties of
> semantically different entities. For example:
>   class p1;
>   class p2;
>   class p3;
>   class p4;
>
>   typedef typed_flags<p1, p2, p3> a; // has p3 property
>   typedef typed_flags<p3, p4> b; // has p3 property too
>
>   template<typename T, typename... Args>
>   bool test_p(Args&&... args) {
>     return (... && args.template test<T>());
>   }
>   // test p3 property from a and b
>   test_p<p3>(a{flag<p3>{1}}, b{flag<p3>{1}});
>
>
> _______________________________________________
> Unsubscribe & other changes: http://listarchives.boost.org/mailman
> /listinfo.cgi/boost
>