Topic: [Flags] attribute for enum class bitfields?


Author: "'snk_kid' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 27 Jun 2016 06:19:49 -0700 (PDT)
Raw View
------=_Part_4335_1108085134.1467033589524
Content-Type: multipart/alternative;
 boundary="----=_Part_4336_1974542681.1467033589524"

------=_Part_4336_1974542681.1467033589524
Content-Type: text/plain; charset=UTF-8

Hi, it would be nice to have a [Flags] attribute for enum classes like .NET
which would either allow using bit-wise operators without casting to
underlying type or generates bit-wise operator overloads.



--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/cc181644-b304-4084-95eb-7deeab86795d%40isocpp.org.

------=_Part_4336_1974542681.1467033589524
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi, it would be nice to have a [Flags] attribute for enum =
classes like .NET which would either allow using bit-wise operators without=
 casting to underlying type or generates bit-wise operator overloads.<div><=
br><div><br><div><br></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/cc181644-b304-4084-95eb-7deeab86795d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cc181644-b304-4084-95eb-7deeab86795d=
%40isocpp.org</a>.<br />

------=_Part_4336_1974542681.1467033589524--

------=_Part_4335_1108085134.1467033589524--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 27 Jun 2016 10:20:05 -0400
Raw View
On 2016-06-27 09:19, snk_kid wrote:
> Hi, it would be nice to have a [Flags] attribute for enum classes like .NET
> which would either allow using bit-wise operators without casting to
> underlying type or generates bit-wise operator overloads.

Somewhere on my "TO DO" list is to propose a std::flags modeled after
QFlags. This would be a library solution rather than a language
solution, which is usually preferred, and also allows keeping separate
types for "a set of flags" and "exactly one flag".

The main problem is how to provide the operators for the enum type
itself. Usual solutions involve using a macro, to which some folks take
a very strong disliking.

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nkrcml%24so9%241%40ger.gmane.org.

.


Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Mon, 27 Jun 2016 15:23:43 +0100
Raw View
On 27/06/16 15:20, Matthew Woehlke wrote:
> On 2016-06-27 09:19, snk_kid wrote:
>> Hi, it would be nice to have a [Flags] attribute for enum classes like .NET
>> which would either allow using bit-wise operators without casting to
>> underlying type or generates bit-wise operator overloads.
>
> Somewhere on my "TO DO" list is to propose a std::flags modeled after
> QFlags. This would be a library solution rather than a language
> solution, which is usually preferred, and also allows keeping separate
> types for "a set of flags" and "exactly one flag".
>
> The main problem is how to provide the operators for the enum type
> itself. Usual solutions involve using a macro, to which some folks take
> a very strong disliking.
>

You don't need to use macros for that. You can specialize a traits
class, or use a constexpr function. I wrote about this last year:

https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html

Anthony
--
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++11 thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/577136EF.7010901%40gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 27 Jun 2016 10:36:59 -0400
Raw View
On 2016-06-27 10:23, Anthony Williams wrote:
> On 27/06/16 15:20, Matthew Woehlke wrote:
>> On 2016-06-27 09:19, snk_kid wrote:
>>> Hi, it would be nice to have a [Flags] attribute for enum classes like .NET
>>> which would either allow using bit-wise operators without casting to
>>> underlying type or generates bit-wise operator overloads.
>>
>> Somewhere on my "TO DO" list is to propose a std::flags modeled after
>> QFlags. This would be a library solution rather than a language
>> solution, which is usually preferred, and also allows keeping separate
>> types for "a set of flags" and "exactly one flag".
>>
>> The main problem is how to provide the operators for the enum type
>> itself. Usual solutions involve using a macro, to which some folks take
>> a very strong disliking.
>
> You don't need to use macros for that. You can specialize a traits
> class, or use a constexpr function. I wrote about this last year:
>
> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html

That's hardly an improvement. Unless I am missing something, your
example involves writing *more* code vs. using a macro, and also loses
the feature of single-flag and flag-set being separate types.

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nkrdmq%24ffu%241%40ger.gmane.org.

.


Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Mon, 27 Jun 2016 16:37:13 +0100
Raw View
On 27/06/16 15:36, Matthew Woehlke wrote:
> On 2016-06-27 10:23, Anthony Williams wrote:
>> On 27/06/16 15:20, Matthew Woehlke wrote:
>>> On 2016-06-27 09:19, snk_kid wrote:
>>>> Hi, it would be nice to have a [Flags] attribute for enum classes like .NET
>>>> which would either allow using bit-wise operators without casting to
>>>> underlying type or generates bit-wise operator overloads.
>>>
>>> Somewhere on my "TO DO" list is to propose a std::flags modeled after
>>> QFlags. This would be a library solution rather than a language
>>> solution, which is usually preferred, and also allows keeping separate
>>> types for "a set of flags" and "exactly one flag".
>>>
>>> The main problem is how to provide the operators for the enum type
>>> itself. Usual solutions involve using a macro, to which some folks take
>>> a very strong disliking.
>>
>> You don't need to use macros for that. You can specialize a traits
>> class, or use a constexpr function. I wrote about this last year:
>>
>> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
>
> That's hardly an improvement. Unless I am missing something, your
> example involves writing *more* code vs. using a macro, and also loses
> the feature of single-flag and flag-set being separate types.

enum class SingleFlag{ flag1,flag2};

SingleFlag x=SingleFlag::flag1;
//SingleFlag x2=SingleFlag::flag1|SingleFlag::flag2; // fails to compile

enum class FlagSet{ option1=1,option2=2,option3=4};

template<>
struct enable_bitmask_operators<FlagSet>{
    static constexpr bool enable=true;
};
FlagSet y=FlagSet::option1|FlagSet::option2;


It's marginally more than a macro, but not much.

With a bit more work in the generic code, you can make it use a
constexpr function instead of a traits specialization, which is then
even less work for the user:

constexpr bool is_bitmask_enum(FlagSet){return true;}

Anthony
--
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++11 thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/57714829.7090909%40gmail.com.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 27 Jun 2016 12:10:07 -0400
Raw View
On 2016-06-27 11:37, Anthony Williams wrote:
> On 27/06/16 15:36, Matthew Woehlke wrote:
>> On 2016-06-27 10:23, Anthony Williams wrote:
>>> You don't need to use macros for that. You can specialize a traits
>>> class, or use a constexpr function. I wrote about this last year:
>>>
>>> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
>>
>> That's hardly an improvement. Unless I am missing something, your
>> example involves writing *more* code vs. using a macro, and also loses
>> the feature of single-flag and flag-set being separate types.
>
> enum class SingleFlag{ flag1,flag2};
>
> SingleFlag x=SingleFlag::flag1;
> //SingleFlag x2=SingleFlag::flag1|SingleFlag::flag2; // fails to compile
>
> enum class FlagSet{ option1=1,option2=2,option3=4};
>
> template<>
> struct enable_bitmask_operators<FlagSet>{
>     static constexpr bool enable=true;
> };
> FlagSet y=FlagSet::option1|FlagSet::option2;

That's... lovely. And completely misses the issue.

Given an enum (call it `F`) of flags, how do I write one function that
takes exactly one flag of `F`, and one function that takes a collection
of one or more flags of `F`?

QFlags can do this. The std::flags implementation I derived from QFlags
can do it. I don't see how your implementation can. You would have to write:

  enum Flag { ... }; // same for any implementation

  using Flags = std::flags<flag>; // Reasonable enough

  template<>
  struct enable_bitmask_operators<Flags>{
      static constexpr bool enable=true;
  }; // Ugh, long and repetitive (read: error-prone)

Honestly, I would strongly prefer a macro over that four-line mess. One
benefit of a macro is that it is an *error* if I typo it, *at* the site
where I make the typo... not a hair-pulling-out why-is-this-happening
error at some far removed location where I'm trying to use it.

Better would be if declaring a type-alias of std::flags somehow did this
"magically". But I have not come up with any reasonable way for that to
happen. (SFINAE + attribute introspection might make it possible, but I
can hear people screaming about that already...)

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nkrj4v%24at8%241%40ger.gmane.org.

.


Author: =?UTF-8?Q?Jonathan_M=C3=BCller?= <jonathanmueller.dev@gmail.com>
Date: Mon, 27 Jun 2016 19:39:29 +0200
Raw View
--94eb2c043898a7fe6a05364600d5
Content-Type: text/plain; charset=UTF-8

On Mon, Jun 27, 2016 at 6:10 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> That's... lovely. And completely misses the issue.
>
> Given an enum (call it `F`) of flags, how do I write one function that
> takes exactly one flag of `F`, and one function that takes a collection
> of one or more flags of `F`?
>

Why do you need two different types for that?


> QFlags can do this. The std::flags implementation I derived from QFlags
> can do it. I don't see how your implementation can. You would have to
> write:
>
>   enum Flag { ... }; // same for any implementation
>
>   using Flags = std::flags<flag>; // Reasonable enough
>
>   template<>
>   struct enable_bitmask_operators<Flags>{
>       static constexpr bool enable=true;
>   }; // Ugh, long and repetitive (read: error-prone)
>
> Honestly, I would strongly prefer a macro over that four-line mess. One
> benefit of a macro is that it is an *error* if I typo it, *at* the site
> where I make the typo... not a hair-pulling-out why-is-this-happening
> error at some far removed location where I'm trying to use it.
>
> Better would be if declaring a type-alias of std::flags somehow did this
> "magically". But I have not come up with any reasonable way for that to
> happen. (SFINAE + attribute introspection might make it possible, but I
> can hear people screaming about that already...)
>

What about:

  enum FlagImpl { ... };

  using Flag = std::flag<FlagImpl>;

  using Flags = std::flags<FlagImpl>;

Or am I missing something?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEddoJaRqCpf-_OpPcCpAbQsjiLbV8AYK0xXHFuqs61DX7Ozmw%40mail.gmail.com.

--94eb2c043898a7fe6a05364600d5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jun 27, 2016 at 6:10 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That&#39;s... =
lovely. And completely misses the issue.<br>
<br>
Given an enum (call it `F`) of flags, how do I write one function that<br>
takes exactly one flag of `F`, and one function that takes a collection<br>
of one or more flags of `F`?<br></blockquote><div><br></div><div>Why do you=
 need two different types for that?<br></div><div>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">

QFlags can do this. The std::flags implementation I derived from QFlags<br>
can do it. I don&#39;t see how your implementation can. You would have to w=
rite:<br>
<br>
=C2=A0 enum Flag { ... }; // same for any implementation<br>
<br>
=C2=A0 using Flags =3D std::flags&lt;flag&gt;; // Reasonable enough<br>
<br>
=C2=A0 template&lt;&gt;<br>
=C2=A0 struct enable_bitmask_operators&lt;Flags&gt;{<br>
=C2=A0 =C2=A0 =C2=A0 static constexpr bool enable=3Dtrue;<br>
=C2=A0 }; // Ugh, long and repetitive (read: error-prone)<br>
<br>
Honestly, I would strongly prefer a macro over that four-line mess. One<br>
benefit of a macro is that it is an *error* if I typo it, *at* the site<br>
where I make the typo... not a hair-pulling-out why-is-this-happening<br>
error at some far removed location where I&#39;m trying to use it.<br>
<br>
Better would be if declaring a type-alias of std::flags somehow did this<br=
>
&quot;magically&quot;. But I have not come up with any reasonable way for t=
hat to<br>
happen. (SFINAE + attribute introspection might make it possible, but I<br>
can hear people screaming about that already...)<br></blockquote><div><br><=
/div><div>What about:<br><br></div><div>=C2=A0 enum FlagImpl { ... };<br><b=
r></div><div>=C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;<br><br></div>=
<div>=C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;<br><br></div><div>O=
r am I missing something?=C2=A0 <br></div></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAEddoJaRqCpf-_OpPcCpAbQsjiLbV8AYK0xX=
HFuqs61DX7Ozmw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEddoJaRqCpf-_Op=
PcCpAbQsjiLbV8AYK0xXHFuqs61DX7Ozmw%40mail.gmail.com</a>.<br />

--94eb2c043898a7fe6a05364600d5--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 27 Jun 2016 10:43:07 -0700 (PDT)
Raw View
------=_Part_1110_1032653091.1467049387916
Content-Type: multipart/alternative;
 boundary="----=_Part_1111_1237810429.1467049387916"

------=_Part_1111_1237810429.1467049387916
Content-Type: text/plain; charset=UTF-8



On Monday, June 27, 2016 at 12:10:15 PM UTC-4, Matthew Woehlke wrote:
>
> On 2016-06-27 11:37, Anthony Williams wrote:
> > On 27/06/16 15:36, Matthew Woehlke wrote:
> >> On 2016-06-27 10:23, Anthony Williams wrote:
> >>> You don't need to use macros for that. You can specialize a traits
> >>> class, or use a constexpr function. I wrote about this last year:
> >>>
> >>>
> https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
> >>
> >> That's hardly an improvement. Unless I am missing something, your
> >> example involves writing *more* code vs. using a macro, and also loses
> >> the feature of single-flag and flag-set being separate types.
> >
> > enum class SingleFlag{ flag1,flag2};
> >
> > SingleFlag x=SingleFlag::flag1;
> > //SingleFlag x2=SingleFlag::flag1|SingleFlag::flag2; // fails to compile
> >
> > enum class FlagSet{ option1=1,option2=2,option3=4};
> >
> > template<>
> > struct enable_bitmask_operators<FlagSet>{
> >     static constexpr bool enable=true;
> > };
> > FlagSet y=FlagSet::option1|FlagSet::option2;
>
> That's... lovely. And completely misses the issue.
>
> Given an enum (call it `F`) of flags, how do I write one function that
> takes exactly one flag of `F`, and one function that takes a collection
> of one or more flags of `F`?
>
> QFlags can do this. The std::flags implementation I derived from QFlags
> can do it. I don't see how your implementation can. You would have to
> write:
>
>   enum Flag { ... }; // same for any implementation
>
>   using Flags = std::flags<flag>; // Reasonable enough
>
>   template<>
>   struct enable_bitmask_operators<Flags>{
>       static constexpr bool enable=true;
>   }; // Ugh, long and repetitive (read: error-prone)
>
> Honestly, I would strongly prefer a macro over that four-line mess.


Is there some reason not to put "that four-line mess" in a macro:

ENABLE_FLAGS(flag_type, enum_type) \
using flag_type = std::flags<enum_type>;\
template<>\
struct enable_bitmask_operators<flag_type>{ static constexpr bool enable=
true; };

That way, the heavy lifting work is being done by genuine C++ code, and
someone can reasonably easily read and understand what the macro is doing.

My point is that you ship the C++ code; you *package* it in a macro as you
see fit.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d59a8139-1c1a-4553-965c-02b2ddf59e15%40isocpp.org.

------=_Part_1111_1237810429.1467049387916
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, June 27, 2016 at 12:10:15 PM UTC-4, Mat=
thew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-06-=
27 11:37, Anthony Williams wrote:
<br>&gt; On 27/06/16 15:36, Matthew Woehlke wrote:
<br>&gt;&gt; On 2016-06-27 10:23, Anthony Williams wrote:
<br>&gt;&gt;&gt; You don&#39;t need to use macros for that. You can special=
ize a traits
<br>&gt;&gt;&gt; class, or use a constexpr function. I wrote about this las=
t year:
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; <a href=3D"https://www.justsoftwaresolutions.co.uk/cpluspl=
us/using-enum-classes-as-bitfields.html" target=3D"_blank" rel=3D"nofollow"=
 onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2=
F%2Fwww.justsoftwaresolutions.co.uk%2Fcplusplus%2Fusing-enum-classes-as-bit=
fields.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH6oHYrqAbunJJPz4b2MMWCS=
43-Aw&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com=
/url?q\x3dhttps%3A%2F%2Fwww.justsoftwaresolutions.co.uk%2Fcplusplus%2Fusing=
-enum-classes-as-bitfields.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNH6o=
HYrqAbunJJPz4b2MMWCS43-Aw&#39;;return true;">https://www.<wbr>justsoftwares=
olutions.co.uk/<wbr>cplusplus/using-enum-classes-<wbr>as-bitfields.html</a>
<br>&gt;&gt;
<br>&gt;&gt; That&#39;s hardly an improvement. Unless I am missing somethin=
g, your
<br>&gt;&gt; example involves writing *more* code vs. using a macro, and al=
so loses
<br>&gt;&gt; the feature of single-flag and flag-set being separate types.
<br>&gt;=20
<br>&gt; enum class SingleFlag{ flag1,flag2};
<br>&gt;=20
<br>&gt; SingleFlag x=3DSingleFlag::flag1;
<br>&gt; //SingleFlag x2=3DSingleFlag::flag1|<wbr>SingleFlag::flag2; // fai=
ls to compile
<br>&gt;=20
<br>&gt; enum class FlagSet{ option1=3D1,option2=3D2,option3=3D4}<wbr>;
<br>&gt;=20
<br>&gt; template&lt;&gt;
<br>&gt; struct enable_bitmask_operators&lt;<wbr>FlagSet&gt;{
<br>&gt; =C2=A0 =C2=A0 static constexpr bool enable=3Dtrue;
<br>&gt; };
<br>&gt; FlagSet y=3DFlagSet::option1|FlagSet::<wbr>option2;
<br>
<br>That&#39;s... lovely. And completely misses the issue.
<br>
<br>Given an enum (call it `F`) of flags, how do I write one function that
<br>takes exactly one flag of `F`, and one function that takes a collection
<br>of one or more flags of `F`?
<br>
<br>QFlags can do this. The std::flags implementation I derived from QFlags
<br>can do it. I don&#39;t see how your implementation can. You would have =
to write:
<br>
<br>=C2=A0 enum Flag { ... }; // same for any implementation
<br>
<br>=C2=A0 using Flags =3D std::flags&lt;flag&gt;; // Reasonable enough
<br>
<br>=C2=A0 template&lt;&gt;
<br>=C2=A0 struct enable_bitmask_operators&lt;<wbr>Flags&gt;{
<br>=C2=A0 =C2=A0 =C2=A0 static constexpr bool enable=3Dtrue;
<br>=C2=A0 }; // Ugh, long and repetitive (read: error-prone)
<br>
<br>Honestly, I would strongly prefer a macro over that four-line mess.</bl=
ockquote><div><br>Is there some reason not to put &quot;that four-line mess=
&quot; in a macro:<br><br><div class=3D"prettyprint" style=3D"background-co=
lor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: so=
lid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled=
-by-prettify">ENABLE_FLAGS</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">flag_type</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> en=
um_type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">using</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> flag_type </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">flags</span><span style=3D"color: #080;" class=3D"styled-by=
-prettify">&lt;enum_type&gt;</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;\</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;&gt;\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struc=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> enable_b=
itmask_operators</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&lt;flag_type&gt;</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">stati=
c</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> enable</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">};</span></div></code></div><br>That way, the heavy lifting work is =
being done by genuine C++ code, and someone can reasonably easily read and =
understand what the macro is doing.<br><br>My point is that you ship the C+=
+ code; you <i>package</i> it in a macro as you see fit.</div><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/d59a8139-1c1a-4553-965c-02b2ddf59e15%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d59a8139-1c1a-4553-965c-02b2ddf59e15=
%40isocpp.org</a>.<br />

------=_Part_1111_1237810429.1467049387916--

------=_Part_1110_1032653091.1467049387916--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 27 Jun 2016 10:46:49 -0700 (PDT)
Raw View
------=_Part_4866_410720444.1467049609367
Content-Type: multipart/alternative;
 boundary="----=_Part_4867_609169838.1467049609367"

------=_Part_4867_609169838.1467049609367
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, June 27, 2016 at 1:39:31 PM UTC-4, Jonathan M=C3=BCller wrote:
>
> On Mon, Jun 27, 2016 at 6:10 PM, Matthew Woehlke <mwoehlk...@gmail.com=20
> <javascript:>> wrote:
>
>> That's... lovely. And completely misses the issue.
>>
>> Given an enum (call it `F`) of flags, how do I write one function that
>> takes exactly one flag of `F`, and one function that takes a collection
>> of one or more flags of `F`?
>>
>
> Why do you need two different types for that?
>

Because they are two different use cases of flag enumerations, and you want=
=20
compiler support to help minimize the chance of someone doing the wrong=20
thing. If you have a function that asks if a specific flag is set, you want=
=20
the compiler to fail if they try to do an `or` between two different flags.=
=20
The function asks if a specific flag is set, not if a group of flags is set=
..

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/84d38593-e696-4bc4-b0cc-8cb8f5a343c4%40isocpp.or=
g.

------=_Part_4867_609169838.1467049609367
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, June 27, 2016 at 1:39:31 PM UTC-4, Jonathan M=
=C3=BCller wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div class=3D"gmail_quote">On Mon, Jun 27, 2016 at 6:10 PM, Matthe=
w Woehlke <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" g=
df-obfuscated-mailto=3D"qjz2N2IbBgAJ" rel=3D"nofollow" onmousedown=3D"this.=
href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;java=
script:&#39;;return true;">mwoehlk...@gmail.com</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">That&#39;s... lovely. And completely misses th=
e issue.<br>
<br>
Given an enum (call it `F`) of flags, how do I write one function that<br>
takes exactly one flag of `F`, and one function that takes a collection<br>
of one or more flags of `F`?<br></blockquote><div><br></div><div>Why do you=
 need two different types for that?<br></div></div></div></div></blockquote=
><div><br>Because they are two different use cases of flag enumerations, an=
d you want compiler support to help minimize the chance of someone doing th=
e wrong thing. If you have a function that asks if a specific flag is set, =
you want the compiler to fail if they try to do an `or` between two differe=
nt flags. The function asks if a specific flag is set, not if a group of fl=
ags is set.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/84d38593-e696-4bc4-b0cc-8cb8f5a343c4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/84d38593-e696-4bc4-b0cc-8cb8f5a343c4=
%40isocpp.org</a>.<br />

------=_Part_4867_609169838.1467049609367--

------=_Part_4866_410720444.1467049609367--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 27 Jun 2016 15:24:36 -0400
Raw View
On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:
> On Mon, Jun 27, 2016 at 6:10 PM, Matthew Woehlke <mwoehlke.floss@gmail.co=
m>
> wrote:
>=20
>> That's... lovely. And completely misses the issue.
>>
>> Given an enum (call it `F`) of flags, how do I write one function that
>> takes exactly one flag of `F`, and one function that takes a collection
>> of one or more flags of `F`?
>=20
> Why do you need two different types for that?

....because I might have a function that needs to take exactly one flag?

For example, a QDockWidget has supported areas (flags) and current area
(flag). It can't concurrently be in multiple areas, so a method to set
the current area taking more than one flag would be an error, and one
returning the current area is better API if it encodes that the result
will be one flag, not a collection of flags.

>> Better would be if declaring a type-alias of std::flags somehow did this
>> "magically". But I have not come up with any reasonable way for that to
>> happen. (SFINAE + attribute introspection might make it possible, but I
>> can hear people screaming about that already...)
>=20
> What about:
>=20
>   enum FlagImpl { ... };
>=20
>   using Flag =3D std::flag<FlagImpl>;
>=20
>   using Flags =3D std::flags<FlagImpl>;
>=20
> Or am I missing something?

How does that enable Boolean operators?

  operator|(FlagImpl, FlagImpl) -> Flags
  operator|(Flags, FlagImpl) -> Flags
  operator|(FlagImpl, Flags) -> Flags

....etc.?

--=20
Matthew

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/nkruhk%24utv%241%40ger.gmane.org.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 27 Jun 2016 15:30:17 -0400
Raw View
On 2016-06-27 13:43, Nicol Bolas wrote:
> On Monday, June 27, 2016 at 12:10:15 PM UTC-4, Matthew Woehlke wrote:
>>   template<>
>>   struct enable_bitmask_operators<Flags>{
>>       static constexpr bool enable=true;
>>   }; // Ugh, long and repetitive (read: error-prone)
>>
>> Honestly, I would strongly prefer a macro over that four-line mess.
>
> Is there some reason not to put "that four-line mess" in a macro:

....certain people absolutely loathe macros? ;-)

MHO is that any flags implementation requiring more than two additional
lines of code (the flag type alias, and one to enable flags) is
suboptimal and grounds to keep looking for a better way. Ideally,
declaring the type alias would be sufficient to enable operators, but
that's probably not possible without a very special (read: very limited
use case) language rule or abuse such as SFINAE on attribute introspection.

Note that I'm counting lines that the library author has to write. Those
still have to be reimplemented if multiple independent projects want to
use the feature.

That said, maybe folks would be less opposed to a (standard) macro that
just specializes a type trait than one that actually declares operators
(a la Q_DECLARE_OPERATORS_FOR_FLAGS).

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nkrusa%2485q%241%40ger.gmane.org.

.


Author: =?UTF-8?Q?Jonathan_M=c3=bcller?= <jonathanmueller.dev@gmail.com>
Date: Mon, 27 Jun 2016 22:35:13 +0200
Raw View
On 27.06.2016 21:24, Matthew Woehlke wrote:
> On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:
>> Why do you need two different types for that?
>
> ...because I might have a function that needs to take exactly one flag?
>
> For example, a QDockWidget has supported areas (flags) and current area
> (flag). It can't concurrently be in multiple areas, so a method to set
> the current area taking more than one flag would be an error, and one
> returning the current area is better API if it encodes that the result
> will be one flag, not a collection of flags.

Okay, I'll get that.

>> What about:
>>
>>   enum FlagImpl { ... };
>>
>>   using Flag =3D std::flag<FlagImpl>;
>>
>>   using Flags =3D std::flags<FlagImpl>;
>>
>> Or am I missing something?
>
> How does that enable Boolean operators?
>
>   operator|(FlagImpl, FlagImpl) -> Flags
>   operator|(Flags, FlagImpl) -> Flags
>   operator|(FlagImpl, Flags) -> Flags
>
> ...etc.?
>

Yes, I thought about something like that.
You still need to cast one argument though.

So overall there are the following options:

* manual overload bitwise operators

* manual overload through macro

* automatic generation via traits or similar

* semi-automatic generation by casting one argument

* language feature

Or am I missing something?

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/812db1bf-3d99-a00b-28a9-16b71e47f2bc%40gmail.com=
..

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 28 Jun 2016 03:27:53 -0700 (PDT)
Raw View
------=_Part_381_1125382141.1467109673766
Content-Type: multipart/alternative;
 boundary="----=_Part_382_127407045.1467109673767"

------=_Part_382_127407045.1467109673767
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
> > On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
> >> Why do you need two different types for that?=20
> >=20
> > ...because I might have a function that needs to take exactly one flag?=
=20
> >=20
> > For example, a QDockWidget has supported areas (flags) and current area=
=20
> > (flag). It can't concurrently be in multiple areas, so a method to set=
=20
> > the current area taking more than one flag would be an error, and one=
=20
> > returning the current area is better API if it encodes that the result=
=20
> > will be one flag, not a collection of flags.=20
>
> Okay, I'll get that.=20
>
> >> What about:=20
> >>=20
> >>   enum FlagImpl { ... };=20
> >>=20
> >>   using Flag =3D std::flag<FlagImpl>;=20
> >>=20
> >>   using Flags =3D std::flags<FlagImpl>;=20
> >>=20
> >> Or am I missing something?=20
> >=20
> > How does that enable Boolean operators?=20
> >=20
> >   operator|(FlagImpl, FlagImpl) -> Flags=20
> >   operator|(Flags, FlagImpl) -> Flags=20
> >   operator|(FlagImpl, Flags) -> Flags=20
> >=20
> > ...etc.?=20
> >=20
>
> Yes, I thought about something like that.=20
> You still need to cast one argument though.=20
>
> So overall there are the following options:=20
>
> * manual overload bitwise operators=20
>
> * manual overload through macro=20
>
> * automatic generation via traits or similar=20
>
> * semi-automatic generation by casting one argument=20
>
> * language feature=20
>
> Or am I missing something?=20
>

Take a look on implementation here: =20
http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article is in=
=20
russian but the code is self documented). The only thing which one have to=
=20
do manually is operator|(FlagImpl, FlagImpl) which can be written once with=
=20
trait enabled template suggested by Anthony Williams. One more issue here=
=20
is inverse operation can't be implemented in order the following code work=
=20
without triggering assertion:

enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
using Days =3D BitMask<Day>;

const Days workdays =3D ~(Day::Sat | Day::Sun);
assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day::Fry)=
;

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b592e3e8-91ed-49ec-9625-3ca5d405045d%40isocpp.or=
g.

------=_Part_382_127407045.1467109673767
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller =D0=
=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">On 27.06.2016 21:24, Matthew Woehlke wrote:
<br>&gt; On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:
<br>&gt;&gt; Why do you need two different types for that?
<br>&gt;
<br>&gt; ...because I might have a function that needs to take exactly one =
flag?
<br>&gt;
<br>&gt; For example, a QDockWidget has supported areas (flags) and current=
 area
<br>&gt; (flag). It can&#39;t concurrently be in multiple areas, so a metho=
d to set
<br>&gt; the current area taking more than one flag would be an error, and =
one
<br>&gt; returning the current area is better API if it encodes that the re=
sult
<br>&gt; will be one flag, not a collection of flags.
<br>
<br>Okay, I&#39;ll get that.
<br>
<br>&gt;&gt; What about:
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 enum FlagImpl { ... };
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;
<br>&gt;&gt;
<br>&gt;&gt; Or am I missing something?
<br>&gt;
<br>&gt; How does that enable Boolean operators?
<br>&gt;
<br>&gt; =C2=A0 operator|(FlagImpl, FlagImpl) -&gt; Flags
<br>&gt; =C2=A0 operator|(Flags, FlagImpl) -&gt; Flags
<br>&gt; =C2=A0 operator|(FlagImpl, Flags) -&gt; Flags
<br>&gt;
<br>&gt; ...etc.?
<br>&gt;
<br>
<br>Yes, I thought about something like that.
<br>You still need to cast one argument though.
<br>
<br>So overall there are the following options:
<br>
<br>* manual overload bitwise operators
<br>
<br>* manual overload through macro
<br>
<br>* automatic generation via traits or similar
<br>
<br>* semi-automatic generation by casting one argument
<br>
<br>* language feature
<br>
<br>Or am I missing something?
<br></blockquote><div><br>Take a look on implementation here:=C2=A0 http://=
my-it-experiments.blogspot.ru/2015/11/blog-post.html (article is in russian=
 but the code is self documented). The only thing which one have to do manu=
ally is operator|(FlagImpl, FlagImpl) which can be written once with trait =
enabled template suggested by Anthony Williams<span class=3D"_username"><sp=
an data-name=3D"Anthony Williams" data-userid=3D"116081441770153189228" sty=
le=3D"color: rgb(34, 34, 34);" class=3D"IVILX2C-D-a g-hovercard"></span></s=
pan>. One more issue here is inverse operation can&#39;t be implemented in =
order the following code work without triggering assertion:<br><br><div cla=
ss=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap:=
 break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">enum</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Day</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">{</span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Mon</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Tue</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Wed</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Thu</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Fri</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Sat</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Sun</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">using</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Days</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">BitMask</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Day</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Days</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> workdays </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">~(</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Day</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Sat</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">|</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #606;" class=3D"styled-by-prettify">Day</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Sun</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><co=
de class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">workdays</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day</span></code>:=
:Fry);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span></div></code></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b592e3e8-91ed-49ec-9625-3ca5d405045d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b592e3e8-91ed-49ec-9625-3ca5d405045d=
%40isocpp.org</a>.<br />

------=_Part_382_127407045.1467109673767--

------=_Part_381_1125382141.1467109673766--

.


Author: "'snk_kid' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 28 Jun 2016 04:32:50 -0700 (PDT)
Raw View
------=_Part_561_1509681471.1467113571057
Content-Type: multipart/alternative;
 boundary="----=_Part_562_571470003.1467113571058"

------=_Part_562_571470003.1467113571058
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Are those enum members suppose to represent bit positions because they=20
don't look like bit-masks as you're not setting the values for them. I=20
don't like the fact that you have 2 types instead of just one.

None of the library solutions look ideal too me, why are people against=20
having a standardized attribute? it seems like it should be a trivial thing=
=20
for compiler vendors to implement. I don't believe in this mantra that=20
every new feature should (preferably) be or start off as a library solution=
..

On Tuesday, June 28, 2016 at 11:27:54 AM UTC+1, Sergey Vidyuk wrote:
>
>
>
> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
>> > On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
>> >> Why do you need two different types for that?=20
>> >=20
>> > ...because I might have a function that needs to take exactly one flag=
?=20
>> >=20
>> > For example, a QDockWidget has supported areas (flags) and current are=
a=20
>> > (flag). It can't concurrently be in multiple areas, so a method to set=
=20
>> > the current area taking more than one flag would be an error, and one=
=20
>> > returning the current area is better API if it encodes that the result=
=20
>> > will be one flag, not a collection of flags.=20
>>
>> Okay, I'll get that.=20
>>
>> >> What about:=20
>> >>=20
>> >>   enum FlagImpl { ... };=20
>> >>=20
>> >>   using Flag =3D std::flag<FlagImpl>;=20
>> >>=20
>> >>   using Flags =3D std::flags<FlagImpl>;=20
>> >>=20
>> >> Or am I missing something?=20
>> >=20
>> > How does that enable Boolean operators?=20
>> >=20
>> >   operator|(FlagImpl, FlagImpl) -> Flags=20
>> >   operator|(Flags, FlagImpl) -> Flags=20
>> >   operator|(FlagImpl, Flags) -> Flags=20
>> >=20
>> > ...etc.?=20
>> >=20
>>
>> Yes, I thought about something like that.=20
>> You still need to cast one argument though.=20
>>
>> So overall there are the following options:=20
>>
>> * manual overload bitwise operators=20
>>
>> * manual overload through macro=20
>>
>> * automatic generation via traits or similar=20
>>
>> * semi-automatic generation by casting one argument=20
>>
>> * language feature=20
>>
>> Or am I missing something?=20
>>
>
> Take a look on implementation here: =20
> http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article is=
=20
> in russian but the code is self documented). The only thing which one hav=
e=20
> to do manually is operator|(FlagImpl, FlagImpl) which can be written once=
=20
> with trait enabled template suggested by Anthony Williams. One more issue=
=20
> here is inverse operation can't be implemented in order the following cod=
e=20
> work without triggering assertion:
>
> enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
> using Days =3D BitMask<Day>;
>
> const Days workdays =3D ~(Day::Sat | Day::Sun);
> assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day::Fr=
y);
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9956d306-ca2a-4429-8439-52b640f5ea8d%40isocpp.or=
g.

------=_Part_562_571470003.1467113571058
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Are those enum members suppose to represent bit positions =
because they don&#39;t look like bit-masks as you&#39;re not setting the va=
lues for them. I don&#39;t like the fact that you have 2 types instead of j=
ust one.<div><br></div><div>None of the library solutions look ideal too me=
, why are people against having a standardized attribute? it seems like it =
should be a trivial thing for compiler vendors to implement. I don&#39;t be=
lieve in this mantra that every new feature should (preferably) be or start=
 off as a library solution.<div><div><br>On Tuesday, June 28, 2016 at 11:27=
:54 AM UTC+1, Sergey Vidyuk wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, =
28 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=
=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=
 =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">On 27.06.2016 21:24, Matthew Woehlke wrote:
<br>&gt; On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:
<br>&gt;&gt; Why do you need two different types for that?
<br>&gt;
<br>&gt; ...because I might have a function that needs to take exactly one =
flag?
<br>&gt;
<br>&gt; For example, a QDockWidget has supported areas (flags) and current=
 area
<br>&gt; (flag). It can&#39;t concurrently be in multiple areas, so a metho=
d to set
<br>&gt; the current area taking more than one flag would be an error, and =
one
<br>&gt; returning the current area is better API if it encodes that the re=
sult
<br>&gt; will be one flag, not a collection of flags.
<br>
<br>Okay, I&#39;ll get that.
<br>
<br>&gt;&gt; What about:
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 enum FlagImpl { ... };
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;
<br>&gt;&gt;
<br>&gt;&gt; Or am I missing something?
<br>&gt;
<br>&gt; How does that enable Boolean operators?
<br>&gt;
<br>&gt; =C2=A0 operator|(FlagImpl, FlagImpl) -&gt; Flags
<br>&gt; =C2=A0 operator|(Flags, FlagImpl) -&gt; Flags
<br>&gt; =C2=A0 operator|(FlagImpl, Flags) -&gt; Flags
<br>&gt;
<br>&gt; ...etc.?
<br>&gt;
<br>
<br>Yes, I thought about something like that.
<br>You still need to cast one argument though.
<br>
<br>So overall there are the following options:
<br>
<br>* manual overload bitwise operators
<br>
<br>* manual overload through macro
<br>
<br>* automatic generation via traits or similar
<br>
<br>* semi-automatic generation by casting one argument
<br>
<br>* language feature
<br>
<br>Or am I missing something?
<br></blockquote><div><br>Take a look on implementation here:=C2=A0 <a href=
=3D"http://my-it-experiments.blogspot.ru/2015/11/blog-post.html" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://my-it-exper=
iments.blogspot.ru/2015/11/blog-post.html&#39;;return true;" onclick=3D"thi=
s.href=3D&#39;http://my-it-experiments.blogspot.ru/2015/11/blog-post.html&#=
39;;return true;">http://my-it-experiments.<wbr>blogspot.ru/2015/11/blog-po=
st.<wbr>html</a> (article is in russian but the code is self documented). T=
he only thing which one have to do manually is operator|(FlagImpl, FlagImpl=
) which can be written once with trait enabled template suggested by Anthon=
y Williams<span><span style=3D"color:rgb(34,34,34)"></span></span>. One mor=
e issue here is inverse operation can&#39;t be implemented in order the fol=
lowing code work without triggering assertion:<br><br><div style=3D"backgro=
und-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid=
;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#00=
8">enum</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>class</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Day</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</=
span><span style=3D"color:#606">Mon</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#606">Tue</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span =
style=3D"color:#606">Wed</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#606">Thu</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#606">Fri</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#606">Sat</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Sun</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><b=
r></span><span style=3D"color:#008">using</span><span style=3D"color:#000">=
 </span><span style=3D"color:#606">Days</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#606">BitMask</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#606">Day</span><span style=3D"color:#660">&gt;=
;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">const</span><span style=3D"color:#000"> </span><span style=3D"color:#606"=
>Days</span><span style=3D"color:#000"> workdays </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">~(</span><span style=3D"color:#606">Day</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#606">Sat</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">|</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Day</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#606">Sun</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">assert</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#660"><code><spa=
n style=3D"color:#000">workdays</span><span style=3D"color:#000"> =3D=3D Da=
y::Mon | Day::Tue | Day::Wed | Day:Thu | Day</span></code>::Fry);</span><sp=
an style=3D"color:#000"><br></span></div></code></div></div></div></blockqu=
ote></div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9956d306-ca2a-4429-8439-52b640f5ea8d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9956d306-ca2a-4429-8439-52b640f5ea8d=
%40isocpp.org</a>.<br />

------=_Part_562_571470003.1467113571058--

------=_Part_561_1509681471.1467113571057--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 28 Jun 2016 04:51:02 -0700 (PDT)
Raw View
------=_Part_5351_1537791798.1467114663066
Content-Type: multipart/alternative;
 boundary="----=_Part_5352_1508617307.1467114663067"

------=_Part_5352_1508617307.1467114663067
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 17:32:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C snk_kid =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=
:
>
> Are those enum members suppose to represent bit positions because they=20
> don't look like bit-masks as you're not setting the values for them. I=20
> don't like the fact that you have 2 types instead of just one.
>

I agree with Matthew Woehlke that 2 types are needed here. In most of the=
=20
cases I need to use enum as combinable flags I also have special cases when=
=20
I need to work with a single flag. Having 2 types allows one to solve both=
=20
kind of tasks. If you never need to distinguish single flag and set of=20
flags you are using Flags type and don't care about Flag type at all but=20
when you need to distinguish them "1 type"-solution just don't fit you task=
=20
at all.
=20

>
> None of the library solutions look ideal too me, why are people against=
=20
> having a standardized attribute? it seems like it should be a trivial thi=
ng=20
> for compiler vendors to implement. I don't believe in this mantra that=20
> every new feature should (preferably) be or start off as a library soluti=
on.
>
>
Because attributes are intendend to be hint's for a compiler which do not=
=20
change code semantic and can be ignored if compiler do not support this=20
particular attribute without breaking aplication behaviour. In your=20
proposal adding attribute to enum adds extra operations to this enum which=
=20
are not supported otherwise.

One more strong objection: adding attributes to majically solve one=20
particular task, then adding one more attribute to solve another task and=
=20
so on and so on is the worst way to evolve the language. Instead of=20
standartising one simple attribute to solve one simple task one have to=20
standartize some syntax extention which will allow to add user defined=20
attribute and use them to solve huge set of task including the task=20
discussed here.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/92fd556c-b73f-4978-989f-069cd6a5e8e2%40isocpp.or=
g.

------=_Part_5352_1508617307.1467114663067
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 17:32:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C snk_kid =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr">Are those enum members suppose to represent bit positions becau=
se they don&#39;t look like bit-masks as you&#39;re not setting the values =
for them. I don&#39;t like the fact that you have 2 types instead of just o=
ne.</div></blockquote><div><br>I agree with Matthew Woehlke that 2 types ar=
e needed here. In most of the cases I need to use enum as combinable flags =
I also have special cases when I need to work with a single flag. Having 2 =
types allows one to solve both kind of tasks. If you never need to distingu=
ish single flag and set of flags you are using Flags type and don&#39;t car=
e about Flag type at all but when you need to distinguish them &quot;1 type=
&quot;-solution just don&#39;t fit you task at all.<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>N=
one of the library solutions look ideal too me, why are people against havi=
ng a standardized attribute? it seems like it should be a trivial thing for=
 compiler vendors to implement. I don&#39;t believe in this mantra that eve=
ry new feature should (preferably) be or start off as a library solution.<d=
iv><div><br></div></div></div></div></blockquote><br>Because attributes are=
 intendend to be hint&#39;s for a compiler which do not change code semanti=
c and can be ignored if compiler do not support this particular attribute w=
ithout breaking aplication behaviour. In your proposal adding attribute to =
enum adds extra operations to this enum which are not supported otherwise.<=
br><br>One more strong objection: adding attributes to majically solve one =
particular task, then adding one more attribute to solve another task and s=
o on and so on is the worst way to evolve the language. Instead of standart=
ising one simple attribute to solve one simple task one have to standartize=
 some syntax extention which will allow to add user defined attribute and u=
se them to solve huge set of task including the task discussed here.<br><br=
></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/92fd556c-b73f-4978-989f-069cd6a5e8e2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/92fd556c-b73f-4978-989f-069cd6a5e8e2=
%40isocpp.org</a>.<br />

------=_Part_5352_1508617307.1467114663067--

------=_Part_5351_1537791798.1467114663066--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 28 Jun 2016 10:45:26 -0400
Raw View
On 2016-06-28 06:27, Sergey Vidyuk wrote:
> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
>>> On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
>>>> What about:=20
>>>>
>>>>   enum FlagImpl { ... };=20
>>>>
>>>>   using Flag =3D std::flag<FlagImpl>;=20
>>>>
>>>>   using Flags =3D std::flags<FlagImpl>;=20
>>>>
>>>> Or am I missing something?=20
>>>
>>> How does that enable Boolean operators?=20
>>>
>>>   operator|(FlagImpl, FlagImpl) -> Flags=20
>>>   operator|(Flags, FlagImpl) -> Flags=20
>>>   operator|(FlagImpl, Flags) -> Flags=20
>>>
>>> ...etc.?=20
>>
>> Yes, I thought about something like that.=20
>> You still need to cast one argument though.=20
>>
>> So overall there are the following options:=20
>>
>> * manual overload bitwise operators=20
>>
>> * manual overload through macro=20
>>
>> * automatic generation via traits or similar=20
>>
>> * semi-automatic generation by casting one argument=20
>>
>> * language feature=20
>>
>> Or am I missing something?=20

Sounds right.

> Take a look on implementation here: =20
> http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article is i=
n=20
> russian but the code is self documented). The only thing which one have t=
o=20
> do manually is operator|(FlagImpl, FlagImpl) which can be written once wi=
th=20
> trait enabled template suggested by Anthony Williams.

That doesn't seem to add anything that hasn't already been discussed.

> One more issue here is inverse operation can't be implemented in
> order the following code work without triggering assertion:
>=20
> enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
> using Days =3D BitMask<Day>;
>=20
> const Days workdays =3D ~(Day::Sat | Day::Sun);
> assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day::Fr=
y);

That's... hard to get right. QFlags deals with this by promoting the
result of operator~ to int=C2=B9, and allowing int as one of the types to
operator&. Trying to comprehend the set of all actual flags is...
hard(er). Maybe with introspection it will be possible... but I'm
honestly not entirely convinced it wouldn't have corner cases...

(=C2=B9 A std implementation should use underlying_type, obviously.)

--=20
Matthew

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/nku2i6%248lc%241%40ger.gmane.org.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 28 Jun 2016 10:48:28 -0400
Raw View
On 2016-06-28 07:32, snk_kid wrote:
> None of the library solutions look ideal too me, why are people against
> having a standardized attribute? it seems like it should be a trivial thing
> for compiler vendors to implement. I don't believe in this mantra that
> every new feature should (preferably) be or start off as a library solution.

As Sergey notes, an attribute is pretty much a non-starter. As any form
of language feature, well, the bar for language features is higher, and
this is a fairly esoteric (i.e. limited) use case. We generally like
language features to be widely useful. That's less important for library
features.

A language feature that enabled this *and* a bunch of other awesome
things would be much more palatable.

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nku2o1%24eo6%241%40ger.gmane.org.

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Tue, 28 Jun 2016 21:30:44 -0700 (PDT)
Raw View
------=_Part_4389_1767458850.1467174644652
Content-Type: multipart/alternative;
 boundary="----=_Part_4390_1068493103.1467174644653"

------=_Part_4390_1068493103.1467174644653
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 201=
6 =D0=B3., 20:45:37 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=
=D1=82=D0=B5=D0=BB=D1=8C Matthew Woehlke=20
=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On 2016-06-28 06:27, Sergey Vidyuk wrote:=20
> > =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F=
 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=
=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
> > =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=20
> >> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
> >>> On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
> >>>> What about:=20
> >>>>=20
> >>>>   enum FlagImpl { ... };=20
> >>>>=20
> >>>>   using Flag =3D std::flag<FlagImpl>;=20
> >>>>=20
> >>>>   using Flags =3D std::flags<FlagImpl>;=20
> >>>>=20
> >>>> Or am I missing something?=20
> >>>=20
> >>> How does that enable Boolean operators?=20
> >>>=20
> >>>   operator|(FlagImpl, FlagImpl) -> Flags=20
> >>>   operator|(Flags, FlagImpl) -> Flags=20
> >>>   operator|(FlagImpl, Flags) -> Flags=20
> >>>=20
> >>> ...etc.?=20
> >>=20
> >> Yes, I thought about something like that.=20
> >> You still need to cast one argument though.=20
> >>=20
> >> So overall there are the following options:=20
> >>=20
> >> * manual overload bitwise operators=20
> >>=20
> >> * manual overload through macro=20
> >>=20
> >> * automatic generation via traits or similar=20
> >>=20
> >> * semi-automatic generation by casting one argument=20
> >>=20
> >> * language feature=20
> >>=20
> >> Or am I missing something?=20
>
> Sounds right.=20
>
> > Take a look on implementation here:  =20
> > http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article is=
=20
> in=20
> > russian but the code is self documented). The only thing which one have=
=20
> to=20
> > do manually is operator|(FlagImpl, FlagImpl) which can be written once=
=20
> with=20
> > trait enabled template suggested by Anthony Williams.=20
>
> That doesn't seem to add anything that hasn't already been discussed.=20
>

Yes it's just implementation example which I use when need to mix enum into=
=20
bitmasks.
=20

>
> > One more issue here is inverse operation can't be implemented in=20
> > order the following code work without triggering assertion:=20
> >=20
> > enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};=20
> > using Days =3D BitMask<Day>;=20
> >=20
> > const Days workdays =3D ~(Day::Sat | Day::Sun);=20
> > assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day::=
Fry);=20
>
> That's... hard to get right. QFlags deals with this by promoting the=20
> result of operator~ to int=C2=B9, and allowing int as one of the types to=
=20
> operator&. Trying to comprehend the set of all actual flags is...=20
> hard(er). Maybe with introspection it will be possible... but I'm=20
> honestly not entirely convinced it wouldn't have corner cases...=20
>
>
There is a huge issue with inverse operator. The following example works as=
=20
expected:

bool contains_weekend(Days days) {
  return (days & (Day::Sat | Day::Sun));
}

while the next one breaks if inversion was used during function parameter=
=20
calculation:

bool contains_workday(Days days) {
  return (days & ~(Day::Sat | Day::Sun));
}

With static reflection propsal it's possible to calculate additional=20
numeric template parameter which will contain only bits related to the enum=
=20
items and perform bitwise and  with it in the operator~ implementation.=20
Promoting to bitmask representation type (int in case of QFlags or extra=20
template parameter in my ButMask) do not really solve's this issue. It have=
=20
to be solved in a user code:

bool contains_workday(Days days) {
  // TODO: Do not forget to update line bellow when adding new item to Day=
=20
enum
  days =3D days & (Day::Mon | Day::Tue | Day::Wed | Day::Thu | Day::Fry |=
=20
Day::Sat | Day::Sun);
  return (days & ~(Day::Sat | Day::Sun));
}

And this solution is not reliable since it requires to search for all todo=
=20
comments when extending the enum.
=20

> (=C2=B9 A std implementation should use underlying_type, obviously.)=20
>
>
underlying_type do not fit here. If MyEnum underlying type uint8_t and it=
=20
contains 10 items then BitMask<MyEnum> has 2^10 possible values while=20
underlying_type can cover only 2^8. That's why I have additional template=
=20
parameter T in my implementation. With static reflection it's possible co=
=20
choose better default type then just uint64_t. From my personal point of=20
view static reflection is the only blocker to implement this class properly=
=20
but it will be great to have it as std::flags someday.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/956ab1ec-14a2-4f22-af9f-423b5c920ecc%40isocpp.or=
g.

------=_Part_4390_1068493103.1467174644653
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=
=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 20:45:37 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=
=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Matthew Woehlke =D0=BD=D0=
=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">On 2016-06-28 06:27, Sergey Vidyuk wrote:
<br>&gt; =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=
=D1=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=
=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
<br>&gt; =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
<br>&gt;&gt; On 27.06.2016 21:24, Matthew Woehlke wrote:=20
<br>&gt;&gt;&gt; On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
<br>&gt;&gt;&gt;&gt; What about:=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 enum FlagImpl { ... };=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; Or am I missing something?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; How does that enable Boolean operators?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(Flags, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, Flags) -&gt; Flags=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; ...etc.?=20
<br>&gt;&gt;
<br>&gt;&gt; Yes, I thought about something like that.=20
<br>&gt;&gt; You still need to cast one argument though.=20
<br>&gt;&gt;
<br>&gt;&gt; So overall there are the following options:=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload bitwise operators=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload through macro=20
<br>&gt;&gt;
<br>&gt;&gt; * automatic generation via traits or similar=20
<br>&gt;&gt;
<br>&gt;&gt; * semi-automatic generation by casting one argument=20
<br>&gt;&gt;
<br>&gt;&gt; * language feature=20
<br>&gt;&gt;
<br>&gt;&gt; Or am I missing something?=20
<br>
<br>Sounds right.
<br>
<br>&gt; Take a look on implementation here: =C2=A0
<br>&gt; <a href=3D"http://my-it-experiments.blogspot.ru/2015/11/blog-post.=
html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;ht=
tp://my-it-experiments.blogspot.ru/2015/11/blog-post.html&#39;;return true;=
" onclick=3D"this.href=3D&#39;http://my-it-experiments.blogspot.ru/2015/11/=
blog-post.html&#39;;return true;">http://my-it-experiments.<wbr>blogspot.ru=
/2015/11/blog-post.<wbr>html</a> (article is in=20
<br>&gt; russian but the code is self documented). The only thing which one=
 have to=20
<br>&gt; do manually is operator|(FlagImpl, FlagImpl) which can be written =
once with=20
<br>&gt; trait enabled template suggested by Anthony Williams.
<br>
<br>That doesn&#39;t seem to add anything that hasn&#39;t already been disc=
ussed.
<br></blockquote><div><br>Yes it&#39;s just implementation example which I =
use when need to mix enum into bitmasks.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
<br>&gt; One more issue here is inverse operation can&#39;t be implemented =
in
<br>&gt; order the following code work without triggering assertion:
<br>&gt;=20
<br>&gt; enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
<br>&gt; using Days =3D BitMask&lt;Day&gt;;
<br>&gt;=20
<br>&gt; const Days workdays =3D ~(Day::Sat | Day::Sun);
<br>&gt; assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | =
Day::Fry);
<br>
<br>That&#39;s... hard to get right. QFlags deals with this by promoting th=
e
<br>result of operator~ to int=C2=B9, and allowing int as one of the types =
to
<br>operator&amp;. Trying to comprehend the set of all actual flags is...
<br>hard(er). Maybe with introspection it will be possible... but I&#39;m
<br>honestly not entirely convinced it wouldn&#39;t have corner cases...
<br>
<br></blockquote><div><br>There is a huge issue with inverse operator. The =
following example works as expected:<br><br><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; word-wrap: break-word;"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> contains_weekend</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Days</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> days</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">days </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Day</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Sat=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">|</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Day</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Sun</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span></div></code></div><br>while the next one breaks if inversion was use=
d during function parameter calculation:<br><br><div class=3D"prettyprint" =
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, =
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><code=
 class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">bool contains_workday</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Days</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> days</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">days </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">~(</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify"><code class=3D"prettyprint"><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Day</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Sat</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">|</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Day</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Sun</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify"></span></code>));</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>With s=
tatic reflection propsal it&#39;s possible to calculate additional numeric =
template parameter which will contain only bits related to the enum items a=
nd perform bitwise and=C2=A0 with it in the operator~ implementation. Promo=
ting to bitmask representation type (int in case of QFlags or extra templat=
e parameter in my ButMask) do not really solve&#39;s this issue. It have to=
 be solved in a user code:<br><br><code class=3D"prettyprint"><div class=3D=
"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: brea=
k-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">bool contains_workday</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">Days</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> days</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 // TODO: Do not forget to update line bellow when=
 adding new item to Day enum<br>=C2=A0 days =3D days &amp; (Day::Mon | Day:=
:Tue | Day::Wed | Day::Thu | Day::Fry | Day::Sat | Day::Sun);<br>=C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">days </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">~(</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><code class=3D"prettyprint"><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Day</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Sat</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">|</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Day</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Sun</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify"></span></code>));</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span></div></code></div></code><br>And this solut=
ion is not reliable since it requires to search for all todo comments when =
extending the enum.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">(=C2=B9 A std implementation should use underlying_type, obviously.)
<br>
<br></blockquote><div><br>underlying_type do not fit here. If MyEnum underl=
ying type uint8_t and it contains 10 items then BitMask&lt;MyEnum&gt; has 2=
^10 possible values while underlying_type can cover only 2^8. That&#39;s wh=
y I have additional template parameter T in my implementation. With static =
reflection it&#39;s possible co choose better default type then just uint64=
_t. From my personal point of view static reflection is the only blocker to=
 implement this class properly but it will be great to have it as std::flag=
s someday.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/956ab1ec-14a2-4f22-af9f-423b5c920ecc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/956ab1ec-14a2-4f22-af9f-423b5c920ecc=
%40isocpp.org</a>.<br />

------=_Part_4390_1068493103.1467174644653--

------=_Part_4389_1767458850.1467174644652--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Wed, 29 Jun 2016 04:19:50 -0700 (PDT)
Raw View
------=_Part_6540_70281721.1467199190640
Content-Type: multipart/alternative;
 boundary="----=_Part_6541_1211607838.1467199190647"

------=_Part_6541_1211607838.1467199190647
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, 29 June 2016 05:30:45 UTC+1, Sergey Vidyuk wrote:
>
> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 2=
016 =D0=B3., 20:45:37 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=
=B0=D1=82=D0=B5=D0=BB=D1=8C Matthew Woehlke=20
> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>
>> On 2016-06-28 06:27, Sergey Vidyuk wrote:=20
>> > =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=
=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=
=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
>> > =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=20
>> >> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
>> >>> On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
>> >>>> What about:=20
>> >>>>=20
>> >>>>   enum FlagImpl { ... };=20
>> >>>>=20
>> >>>>   using Flag =3D std::flag<FlagImpl>;=20
>> >>>>=20
>> >>>>   using Flags =3D std::flags<FlagImpl>;=20
>> >>>>=20
>> >>>> Or am I missing something?=20
>> >>>=20
>> >>> How does that enable Boolean operators?=20
>> >>>=20
>> >>>   operator|(FlagImpl, FlagImpl) -> Flags=20
>> >>>   operator|(Flags, FlagImpl) -> Flags=20
>> >>>   operator|(FlagImpl, Flags) -> Flags=20
>> >>>=20
>> >>> ...etc.?=20
>> >>=20
>> >> Yes, I thought about something like that.=20
>> >> You still need to cast one argument though.=20
>> >>=20
>> >> So overall there are the following options:=20
>> >>=20
>> >> * manual overload bitwise operators=20
>> >>=20
>> >> * manual overload through macro=20
>> >>=20
>> >> * automatic generation via traits or similar=20
>> >>=20
>> >> * semi-automatic generation by casting one argument=20
>> >>=20
>> >> * language feature=20
>> >>=20
>> >> Or am I missing something?=20
>>
>> Sounds right.=20
>>
>> > Take a look on implementation here:  =20
>> > http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article=
=20
>> is in=20
>> > russian but the code is self documented). The only thing which one hav=
e=20
>> to=20
>> > do manually is operator|(FlagImpl, FlagImpl) which can be written once=
=20
>> with=20
>> > trait enabled template suggested by Anthony Williams.=20
>>
>> That doesn't seem to add anything that hasn't already been discussed.=20
>>
>
> Yes it's just implementation example which I use when need to mix enum=20
> into bitmasks.
> =20
>
>>
>> > One more issue here is inverse operation can't be implemented in=20
>> > order the following code work without triggering assertion:=20
>> >=20
>> > enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};=20
>> > using Days =3D BitMask<Day>;=20
>> >=20
>> > const Days workdays =3D ~(Day::Sat | Day::Sun);=20
>> > assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu |=20
>> Day::Fry);=20
>>
>> That's... hard to get right. QFlags deals with this by promoting the=20
>> result of operator~ to int=C2=B9, and allowing int as one of the types t=
o=20
>> operator&. Trying to comprehend the set of all actual flags is...=20
>> hard(er). Maybe with introspection it will be possible... but I'm=20
>> honestly not entirely convinced it wouldn't have corner cases...=20
>>
>>
> There is a huge issue with inverse operator. The following example works=
=20
> as expected:
>
> bool contains_weekend(Days days) {
>   return (days & (Day::Sat | Day::Sun));
> }
>
> while the next one breaks if inversion was used during function parameter=
=20
> calculation:
>
> bool contains_workday(Days days) {
>   return (days & ~(Day::Sat | Day::Sun));
> }
>
> With static reflection propsal it's possible to calculate additional=20
> numeric template parameter which will contain only bits related to the en=
um=20
> items and perform bitwise and  with it in the operator~ implementation.=
=20
> Promoting to bitmask representation type (int in case of QFlags or extra=
=20
> template parameter in my ButMask) do not really solve's this issue. It ha=
ve=20
> to be solved in a user code:
>
> bool contains_workday(Days days) {
>   // TODO: Do not forget to update line bellow when adding new item to Da=
y=20
> enum
>   days =3D days & (Day::Mon | Day::Tue | Day::Wed | Day::Thu | Day::Fry |=
=20
> Day::Sat | Day::Sun);
>   return (days & ~(Day::Sat | Day::Sun));
> }
>
> And this solution is not reliable since it requires to search for all tod=
o=20
> comments when extending the enum.=20
>

For an enumeration without fixed underlying type, it should be possible to=
=20
infer its value range ([dcl.enum]/8) by exploiting [class.bit]/4 and=20
[expr.const]/2, since an equality operation on an enumeration bitmask has=
=20
unspecified result if the bitmask is too small to cover all the values of=
=20
the enumeration, and so a conditional-expression containing that equality=
=20
operation is not core constant.=20

Unfortunately I haven't found any compiler that gets this correct. It would=
=20
be reasonable IMO to request a type trait giving the value range of an=20
enumeration, if we don't get static reflection first.
=20

> (=C2=B9 A std implementation should use underlying_type, obviously.)=20
>>
>>
> underlying_type do not fit here. If MyEnum underlying type uint8_t and it=
=20
> contains 10 items then BitMask<MyEnum> has 2^10 possible values while=20
> underlying_type can cover only 2^8. That's why I have additional template=
=20
> parameter T in my implementation. With static reflection it's possible co=
=20
> choose better default type then just uint64_t. From my personal point of=
=20
> view static reflection is the only blocker to implement this class proper=
ly=20
> but it will be great to have it as std::flags someday.
>

Under the assumption that the enumerators of MyEnum have values 1, 2, 4,=20
etc. then MyEnum's underlying type would have to have at least 10 bits.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/3e12239a-5ea2-453b-9b58-3436f39919fe%40isocpp.or=
g.

------=_Part_6541_1211607838.1467199190647
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, 29 June 2016 05:30:45 UTC+1, Sergey Vidyuk  =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=D0=B2=
=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=
=B3., 20:45:37 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=
=D0=B5=D0=BB=D1=8C Matthew Woehlke =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=
=BB:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex">On 2016-06-28 06:27, Sergey Vid=
yuk wrote:
<br>&gt; =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=
=D1=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=
=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
<br>&gt; =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
<br>&gt;&gt; On 27.06.2016 21:24, Matthew Woehlke wrote:=20
<br>&gt;&gt;&gt; On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
<br>&gt;&gt;&gt;&gt; What about:=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 enum FlagImpl { ... };=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; Or am I missing something?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; How does that enable Boolean operators?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(Flags, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, Flags) -&gt; Flags=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; ...etc.?=20
<br>&gt;&gt;
<br>&gt;&gt; Yes, I thought about something like that.=20
<br>&gt;&gt; You still need to cast one argument though.=20
<br>&gt;&gt;
<br>&gt;&gt; So overall there are the following options:=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload bitwise operators=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload through macro=20
<br>&gt;&gt;
<br>&gt;&gt; * automatic generation via traits or similar=20
<br>&gt;&gt;
<br>&gt;&gt; * semi-automatic generation by casting one argument=20
<br>&gt;&gt;
<br>&gt;&gt; * language feature=20
<br>&gt;&gt;
<br>&gt;&gt; Or am I missing something?=20
<br>
<br>Sounds right.
<br>
<br>&gt; Take a look on implementation here: =C2=A0
<br>&gt; <a href=3D"http://my-it-experiments.blogspot.ru/2015/11/blog-post.=
html" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;ht=
tp://my-it-experiments.blogspot.ru/2015/11/blog-post.html&#39;;return true;=
" onclick=3D"this.href=3D&#39;http://my-it-experiments.blogspot.ru/2015/11/=
blog-post.html&#39;;return true;">http://my-it-experiments.<wbr>blogspot.ru=
/2015/11/blog-post.<wbr>html</a> (article is in=20
<br>&gt; russian but the code is self documented). The only thing which one=
 have to=20
<br>&gt; do manually is operator|(FlagImpl, FlagImpl) which can be written =
once with=20
<br>&gt; trait enabled template suggested by Anthony Williams.
<br>
<br>That doesn&#39;t seem to add anything that hasn&#39;t already been disc=
ussed.
<br></blockquote><div><br>Yes it&#39;s just implementation example which I =
use when need to mix enum into bitmasks.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">
<br>&gt; One more issue here is inverse operation can&#39;t be implemented =
in
<br>&gt; order the following code work without triggering assertion:
<br>&gt;=20
<br>&gt; enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
<br>&gt; using Days =3D BitMask&lt;Day&gt;;
<br>&gt;=20
<br>&gt; const Days workdays =3D ~(Day::Sat | Day::Sun);
<br>&gt; assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | =
Day::Fry);
<br>
<br>That&#39;s... hard to get right. QFlags deals with this by promoting th=
e
<br>result of operator~ to int=C2=B9, and allowing int as one of the types =
to
<br>operator&amp;. Trying to comprehend the set of all actual flags is...
<br>hard(er). Maybe with introspection it will be possible... but I&#39;m
<br>honestly not entirely convinced it wouldn&#39;t have corner cases...
<br>
<br></blockquote><div><br>There is a huge issue with inverse operator. The =
following example works as expected:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">bool</s=
pan><span style=3D"color:#000"> contains_weekend</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Days</span><span style=3D"color:#=
000"> days</span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><=
br>=C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">days </span><span style=3D"color:#660">&amp;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#606=
">Day</span><span style=3D"color:#660">::</span><span style=3D"color:#606">=
Sat</span><span style=3D"color:#000"> </span><span style=3D"color:#660">|</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Day</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#606">Sun</span>=
<span style=3D"color:#660">));</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></=
div></code></div><br>while the next one breaks if inversion was used during=
 function parameter calculation:<br><br><div style=3D"background-color:rgb(=
250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:=
1px;word-wrap:break-word"><code><div><span style=3D"color:#000">bool contai=
ns_workday</span><span style=3D"color:#660">(</span><span style=3D"color:#6=
06">Days</span><span style=3D"color:#000"> days</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">days </span><span style=3D"color:#=
660">&amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">~(</span><span style=3D"color:#660"><code><span style=3D"color:#606">Da=
y</span><span style=3D"color:#660">::</span><span style=3D"color:#606">Sat<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">|</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Day</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#606">Sun</span><spa=
n style=3D"color:#660"></span></code>));</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br=
></span></div></code></div><br>With static reflection propsal it&#39;s poss=
ible to calculate additional numeric template parameter which will contain =
only bits related to the enum items and perform bitwise and=C2=A0 with it i=
n the operator~ implementation. Promoting to bitmask representation type (i=
nt in case of QFlags or extra template parameter in my ButMask) do not real=
ly solve&#39;s this issue. It have to be solved in a user code:<br><br><cod=
e><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,=
187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><=
span style=3D"color:#000">bool contains_workday</span><span style=3D"color:=
#660">(</span><span style=3D"color:#606">Days</span><span style=3D"color:#0=
00"> days</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 // TODO: Do not forget to update line bellow when adding new item =
to Day enum<br>=C2=A0 days =3D days &amp; (Day::Mon | Day::Tue | Day::Wed |=
 Day::Thu | Day::Fry | Day::Sat | Day::Sun);<br>=C2=A0 </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">days </span><span style=
=3D"color:#660">&amp;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">~(</span><span style=3D"color:#660"><code><span style=3D"co=
lor:#606">Day</span><span style=3D"color:#660">::</span><span style=3D"colo=
r:#606">Sat</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">|</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Day</span><span style=3D"color:#660">::</span><span style=3D"color:#606">Su=
n</span><span style=3D"color:#660"></span></code>));</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"col=
or:#000"><br></span></div></code></div></code><br>And this solution is not =
reliable since it requires to search for all todo comments when extending t=
he enum.=C2=A0</div></div></blockquote><div><br></div><div>For an enumerati=
on without fixed underlying type, it should be possible to infer its value =
range ([dcl.enum]/8) by exploiting [class.bit]/4 and [expr.const]/2, since =
an equality operation on an enumeration bitmask has unspecified result if t=
he bitmask is too small to cover all the values of the enumeration, and so =
a conditional-expression containing that equality operation is not core con=
stant.=C2=A0</div><div><br></div><div>Unfortunately I haven&#39;t found any=
 compiler that gets this correct. It would be reasonable IMO to request a t=
ype trait giving the value range of an enumeration, if we don&#39;t get sta=
tic reflection first.</div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">(=C2=
=B9 A std implementation should use underlying_type, obviously.)
<br>
<br></blockquote><div><br>underlying_type do not fit here. If MyEnum underl=
ying type uint8_t and it contains 10 items then BitMask&lt;MyEnum&gt; has 2=
^10 possible values while underlying_type can cover only 2^8. That&#39;s wh=
y I have additional template parameter T in my implementation. With static =
reflection it&#39;s possible co choose better default type then just uint64=
_t. From my personal point of view static reflection is the only blocker to=
 implement this class properly but it will be great to have it as std::flag=
s someday.<br></div></div></blockquote><div><br></div><div>Under the assump=
tion that the enumerators of MyEnum have values 1, 2, 4, etc. then MyEnum&#=
39;s underlying type would have to have at least 10 bits.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3e12239a-5ea2-453b-9b58-3436f39919fe%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3e12239a-5ea2-453b-9b58-3436f39919fe=
%40isocpp.org</a>.<br />

------=_Part_6541_1211607838.1467199190647--

------=_Part_6540_70281721.1467199190640--

.


Author: Sergey Vidyuk <sir.vestnik@gmail.com>
Date: Wed, 29 Jun 2016 06:05:44 -0700 (PDT)
Raw View
------=_Part_77_1199755787.1467205544966
Content-Type: multipart/alternative;
 boundary="----=_Part_78_2132836390.1467205544967"

------=_Part_78_2132836390.1467205544967
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



=D1=81=D1=80=D0=B5=D0=B4=D0=B0, 29 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 1=
7:19:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=
=D0=BB=D1=8C Edward Catmur =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>
> On Wednesday, 29 June 2016 05:30:45 UTC+1, Sergey Vidyuk wrote:
>>
>> =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F =
2016 =D0=B3., 20:45:37 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=
=B0=D1=82=D0=B5=D0=BB=D1=8C Matthew Woehlke=20
>> =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
>>>
>>> On 2016-06-28 06:27, Sergey Vidyuk wrote:=20
>>> > =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=
=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=
=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
>>> > =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:=20
>>> >> On 27.06.2016 21:24, Matthew Woehlke wrote:=20
>>> >>> On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
>>> >>>> What about:=20
>>> >>>>=20
>>> >>>>   enum FlagImpl { ... };=20
>>> >>>>=20
>>> >>>>   using Flag =3D std::flag<FlagImpl>;=20
>>> >>>>=20
>>> >>>>   using Flags =3D std::flags<FlagImpl>;=20
>>> >>>>=20
>>> >>>> Or am I missing something?=20
>>> >>>=20
>>> >>> How does that enable Boolean operators?=20
>>> >>>=20
>>> >>>   operator|(FlagImpl, FlagImpl) -> Flags=20
>>> >>>   operator|(Flags, FlagImpl) -> Flags=20
>>> >>>   operator|(FlagImpl, Flags) -> Flags=20
>>> >>>=20
>>> >>> ...etc.?=20
>>> >>=20
>>> >> Yes, I thought about something like that.=20
>>> >> You still need to cast one argument though.=20
>>> >>=20
>>> >> So overall there are the following options:=20
>>> >>=20
>>> >> * manual overload bitwise operators=20
>>> >>=20
>>> >> * manual overload through macro=20
>>> >>=20
>>> >> * automatic generation via traits or similar=20
>>> >>=20
>>> >> * semi-automatic generation by casting one argument=20
>>> >>=20
>>> >> * language feature=20
>>> >>=20
>>> >> Or am I missing something?=20
>>>
>>> Sounds right.=20
>>>
>>> > Take a look on implementation here:  =20
>>> > http://my-it-experiments.blogspot.ru/2015/11/blog-post.html (article=
=20
>>> is in=20
>>> > russian but the code is self documented). The only thing which one=20
>>> have to=20
>>> > do manually is operator|(FlagImpl, FlagImpl) which can be written onc=
e=20
>>> with=20
>>> > trait enabled template suggested by Anthony Williams.=20
>>>
>>> That doesn't seem to add anything that hasn't already been discussed.=
=20
>>>
>>
>> Yes it's just implementation example which I use when need to mix enum=
=20
>> into bitmasks.
>> =20
>>
>>>
>>> > One more issue here is inverse operation can't be implemented in=20
>>> > order the following code work without triggering assertion:=20
>>> >=20
>>> > enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};=20
>>> > using Days =3D BitMask<Day>;=20
>>> >=20
>>> > const Days workdays =3D ~(Day::Sat | Day::Sun);=20
>>> > assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu |=20
>>> Day::Fry);=20
>>>
>>> That's... hard to get right. QFlags deals with this by promoting the=20
>>> result of operator~ to int=C2=B9, and allowing int as one of the types =
to=20
>>> operator&. Trying to comprehend the set of all actual flags is...=20
>>> hard(er). Maybe with introspection it will be possible... but I'm=20
>>> honestly not entirely convinced it wouldn't have corner cases...=20
>>>
>>>
>> There is a huge issue with inverse operator. The following example works=
=20
>> as expected:
>>
>> bool contains_weekend(Days days) {
>>   return (days & (Day::Sat | Day::Sun));
>> }
>>
>> while the next one breaks if inversion was used during function paramete=
r=20
>> calculation:
>>
>> bool contains_workday(Days days) {
>>   return (days & ~(Day::Sat | Day::Sun));
>> }
>>
>> With static reflection propsal it's possible to calculate additional=20
>> numeric template parameter which will contain only bits related to the e=
num=20
>> items and perform bitwise and  with it in the operator~ implementation.=
=20
>> Promoting to bitmask representation type (int in case of QFlags or extra=
=20
>> template parameter in my ButMask) do not really solve's this issue. It h=
ave=20
>> to be solved in a user code:
>>
>> bool contains_workday(Days days) {
>>   // TODO: Do not forget to update line bellow when adding new item to=
=20
>> Day enum
>>   days =3D days & (Day::Mon | Day::Tue | Day::Wed | Day::Thu | Day::Fry =
|=20
>> Day::Sat | Day::Sun);
>>   return (days & ~(Day::Sat | Day::Sun));
>> }
>>
>> And this solution is not reliable since it requires to search for all=20
>> todo comments when extending the enum.=20
>>
>
> For an enumeration without fixed underlying type, it should be possible t=
o=20
> infer its value range ([dcl.enum]/8) by exploiting [class.bit]/4 and=20
> [expr.const]/2, since an equality operation on an enumeration bitmask has=
=20
> unspecified result if the bitmask is too small to cover all the values of=
=20
> the enumeration, and so a conditional-expression containing that equality=
=20
> operation is not core constant.=20
>
> Unfortunately I haven't found any compiler that gets this correct. It=20
> would be reasonable IMO to request a type trait giving the value range of=
=20
> an enumeration, if we don't get static reflection first.
> =20
>
>> (=C2=B9 A std implementation should use underlying_type, obviously.)=20
>>>
>>>
>> underlying_type do not fit here. If MyEnum underlying type uint8_t and i=
t=20
>> contains 10 items then BitMask<MyEnum> has 2^10 possible values while=20
>> underlying_type can cover only 2^8. That's why I have additional templat=
e=20
>> parameter T in my implementation. With static reflection it's possible c=
o=20
>> choose better default type then just uint64_t. From my personal point of=
=20
>> view static reflection is the only blocker to implement this class prope=
rly=20
>> but it will be great to have it as std::flags someday.
>>
>
> Under the assumption that the enumerators of MyEnum have values 1, 2, 4,=
=20
> etc. then MyEnum's underlying type would have to have at least 10 bits.
>
=20
My BitMask implementation uses enum with default values (0,1,2..N) and=20
perform 'RepresentationIntType(1) <<=20
stutic_cast<RepresentationIntType>(enum_item);' internaly so one can write

enum class Perm {Read, Write, Exec};
using Perms =3D BitMask<Perm>;

instead of

enum class Perm {Read =3D 1, Write =3D 2, Exec =3D 4};
using Perms =3D BitMask<Perm>;

So I need max enum item value to find unsigned integer type which has at=20
least MaxVal bits length.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/450e06f6-bfad-4750-9a60-b384a95abe7e%40isocpp.or=
g.

------=_Part_78_2132836390.1467205544967
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>=D1=81=D1=80=D0=B5=D0=B4=D0=B0, 29 =D0=B8=D1=8E=D0=
=BD=D1=8F 2016 =D0=B3., 17:19:51 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=
=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Edward Catmur =D0=BD=D0=B0=D0=BF=D0=B8=
=D1=81=D0=B0=D0=BB:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">On Wednesday, 29 June 2016 05:30:45 UTC+1, Sergey Vidyuk  wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=D0=B2=D1=82=D0=BE=D1=
=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=D1=8F 2016 =D0=B3., 20:45:37 U=
TC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=
=8C Matthew Woehlke =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:<blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex">On 2016-06-28 06:27, Sergey Vidyuk wrote:
<br>&gt; =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 28 =D0=B8=D1=8E=D0=BD=
=D1=8F 2016 =D0=B3., 2:35:18 UTC+6 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=
=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jonathan M=C3=BCller=20
<br>&gt; =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
<br>&gt;&gt; On 27.06.2016 21:24, Matthew Woehlke wrote:=20
<br>&gt;&gt;&gt; On 2016-06-27 13:39, Jonathan M=C3=BCller wrote:=20
<br>&gt;&gt;&gt;&gt; What about:=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 enum FlagImpl { ... };=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flag =3D std::flag&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; =C2=A0 using Flags =3D std::flags&lt;FlagImpl&gt;;=20
<br>&gt;&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt; Or am I missing something?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; How does that enable Boolean operators?=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(Flags, FlagImpl) -&gt; Flags=20
<br>&gt;&gt;&gt; =C2=A0 operator|(FlagImpl, Flags) -&gt; Flags=20
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; ...etc.?=20
<br>&gt;&gt;
<br>&gt;&gt; Yes, I thought about something like that.=20
<br>&gt;&gt; You still need to cast one argument though.=20
<br>&gt;&gt;
<br>&gt;&gt; So overall there are the following options:=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload bitwise operators=20
<br>&gt;&gt;
<br>&gt;&gt; * manual overload through macro=20
<br>&gt;&gt;
<br>&gt;&gt; * automatic generation via traits or similar=20
<br>&gt;&gt;
<br>&gt;&gt; * semi-automatic generation by casting one argument=20
<br>&gt;&gt;
<br>&gt;&gt; * language feature=20
<br>&gt;&gt;
<br>&gt;&gt; Or am I missing something?=20
<br>
<br>Sounds right.
<br>
<br>&gt; Take a look on implementation here: =C2=A0
<br>&gt; <a href=3D"http://my-it-experiments.blogspot.ru/2015/11/blog-post.=
html" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;ht=
tp://my-it-experiments.blogspot.ru/2015/11/blog-post.html&#39;;return true;=
" onclick=3D"this.href=3D&#39;http://my-it-experiments.blogspot.ru/2015/11/=
blog-post.html&#39;;return true;">http://my-it-experiments.<wbr>blogspot.ru=
/2015/11/blog-post.<wbr>html</a> (article is in=20
<br>&gt; russian but the code is self documented). The only thing which one=
 have to=20
<br>&gt; do manually is operator|(FlagImpl, FlagImpl) which can be written =
once with=20
<br>&gt; trait enabled template suggested by Anthony Williams.
<br>
<br>That doesn&#39;t seem to add anything that hasn&#39;t already been disc=
ussed.
<br></blockquote><div><br>Yes it&#39;s just implementation example which I =
use when need to mix enum into bitmasks.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex">
<br>&gt; One more issue here is inverse operation can&#39;t be implemented =
in
<br>&gt; order the following code work without triggering assertion:
<br>&gt;=20
<br>&gt; enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
<br>&gt; using Days =3D BitMask&lt;Day&gt;;
<br>&gt;=20
<br>&gt; const Days workdays =3D ~(Day::Sat | Day::Sun);
<br>&gt; assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | =
Day::Fry);
<br>
<br>That&#39;s... hard to get right. QFlags deals with this by promoting th=
e
<br>result of operator~ to int=C2=B9, and allowing int as one of the types =
to
<br>operator&amp;. Trying to comprehend the set of all actual flags is...
<br>hard(er). Maybe with introspection it will be possible... but I&#39;m
<br>honestly not entirely convinced it wouldn&#39;t have corner cases...
<br>
<br></blockquote><div><br>There is a huge issue with inverse operator. The =
following example works as expected:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">bool</s=
pan><span style=3D"color:#000"> contains_weekend</span><span style=3D"color=
:#660">(</span><span style=3D"color:#606">Days</span><span style=3D"color:#=
000"> days</span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><=
br>=C2=A0 </span><span style=3D"color:#008">return</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">days </span><span style=3D"color:#660">&amp;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#606=
">Day</span><span style=3D"color:#660">::</span><span style=3D"color:#606">=
Sat</span><span style=3D"color:#000"> </span><span style=3D"color:#660">|</=
span><span style=3D"color:#000"> </span><span style=3D"color:#606">Day</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#606">Sun</span>=
<span style=3D"color:#660">));</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></=
div></code></div><br>while the next one breaks if inversion was used during=
 function parameter calculation:<br><br><div style=3D"background-color:rgb(=
250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:=
1px;word-wrap:break-word"><code><div><span style=3D"color:#000">bool contai=
ns_workday</span><span style=3D"color:#660">(</span><span style=3D"color:#6=
06">Days</span><span style=3D"color:#000"> days</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">days </span><span style=3D"color:#=
660">&amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">~(</span><span style=3D"color:#660"><code><span style=3D"color:#606">Da=
y</span><span style=3D"color:#660">::</span><span style=3D"color:#606">Sat<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">|</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Day</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#606">Sun</span><spa=
n style=3D"color:#660"></span></code>));</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br=
></span></div></code></div><br>With static reflection propsal it&#39;s poss=
ible to calculate additional numeric template parameter which will contain =
only bits related to the enum items and perform bitwise and=C2=A0 with it i=
n the operator~ implementation. Promoting to bitmask representation type (i=
nt in case of QFlags or extra template parameter in my ButMask) do not real=
ly solve&#39;s this issue. It have to be solved in a user code:<br><br><cod=
e><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,=
187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><=
span style=3D"color:#000">bool contains_workday</span><span style=3D"color:=
#660">(</span><span style=3D"color:#606">Days</span><span style=3D"color:#0=
00"> days</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><b=
r>=C2=A0 // TODO: Do not forget to update line bellow when adding new item =
to Day enum<br>=C2=A0 days =3D days &amp; (Day::Mon | Day::Tue | Day::Wed |=
 Day::Thu | Day::Fry | Day::Sat | Day::Sun);<br>=C2=A0 </span><span style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">days </span><span style=
=3D"color:#660">&amp;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">~(</span><span style=3D"color:#660"><code><span style=3D"co=
lor:#606">Day</span><span style=3D"color:#660">::</span><span style=3D"colo=
r:#606">Sat</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">|</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Day</span><span style=3D"color:#660">::</span><span style=3D"color:#606">Su=
n</span><span style=3D"color:#660"></span></code>));</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"col=
or:#000"><br></span></div></code></div></code><br>And this solution is not =
reliable since it requires to search for all todo comments when extending t=
he enum.=C2=A0</div></div></blockquote><div><br></div><div>For an enumerati=
on without fixed underlying type, it should be possible to infer its value =
range ([dcl.enum]/8) by exploiting [class.bit]/4 and [expr.const]/2, since =
an equality operation on an enumeration bitmask has unspecified result if t=
he bitmask is too small to cover all the values of the enumeration, and so =
a conditional-expression containing that equality operation is not core con=
stant.=C2=A0</div><div><br></div><div>Unfortunately I haven&#39;t found any=
 compiler that gets this correct. It would be reasonable IMO to request a t=
ype trait giving the value range of an enumeration, if we don&#39;t get sta=
tic reflection first.</div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">(=C2=B9 A=
 std implementation should use underlying_type, obviously.)
<br>
<br></blockquote><div><br>underlying_type do not fit here. If MyEnum underl=
ying type uint8_t and it contains 10 items then BitMask&lt;MyEnum&gt; has 2=
^10 possible values while underlying_type can cover only 2^8. That&#39;s wh=
y I have additional template parameter T in my implementation. With static =
reflection it&#39;s possible co choose better default type then just uint64=
_t. From my personal point of view static reflection is the only blocker to=
 implement this class properly but it will be great to have it as std::flag=
s someday.<br></div></div></blockquote><div><br></div><div>Under the assump=
tion that the enumerators of MyEnum have values 1, 2, 4, etc. then MyEnum&#=
39;s underlying type would have to have at least 10 bits.</div></div></bloc=
kquote><div>=C2=A0<br>My BitMask implementation uses enum with default valu=
es (0,1,2..N) and perform &#39;RepresentationIntType(1) &lt;&lt; stutic_cas=
t&lt;RepresentationIntType&gt;(enum_item);&#39; internaly so one can write<=
br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">enum<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Perm</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Read</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Write</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Exec</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">using</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Perms</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">BitMask</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Perm</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br=
>instead of<br><br><div class=3D"prettyprint" style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">enum</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Perm</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Read</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">1=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Write</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Exec</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">4</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">using</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Per=
ms</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">BitMask</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Perm</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div><br>So I need max enu=
m item value to find unsigned integer type which has at least MaxVal bits l=
ength.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/450e06f6-bfad-4750-9a60-b384a95abe7e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/450e06f6-bfad-4750-9a60-b384a95abe7e=
%40isocpp.org</a>.<br />

------=_Part_78_2132836390.1467205544967--

------=_Part_77_1199755787.1467205544966--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Wed, 29 Jun 2016 06:07:17 -0700 (PDT)
Raw View
------=_Part_524_1050854710.1467205637127
Content-Type: multipart/alternative;
 boundary="----=_Part_525_491132970.1467205637128"

------=_Part_525_491132970.1467205637128
Content-Type: text/plain; charset=UTF-8

On Tuesday, 28 June 2016 15:50:07 UTC+1, Matthew Woehlke wrote:
>
> On 2016-06-28 07:32, snk_kid wrote:
> > None of the library solutions look ideal too me, why are people against
> > having a standardized attribute? it seems like it should be a trivial
> thing
> > for compiler vendors to implement. I don't believe in this mantra that
> > every new feature should (preferably) be or start off as a library
> solution.
>
> As Sergey notes, an attribute is pretty much a non-starter. As any form
> of language feature, well, the bar for language features is higher, and
> this is a fairly esoteric (i.e. limited) use case. We generally like
> language features to be widely useful. That's less important for library
> features.
>
> A language feature that enabled this *and* a bunch of other awesome
> things would be much more palatable.
>
>
Perhaps allowing enumerations to have base type another enumeration (with
enumerators declared at at most one level) could work here? That way the
operators could be picked up via ADL on the base type (with CRTP where
appropriate).

Use cases:

1. Creating a set type from an existing enumeration, without interfering
with the original enum's operators:
template<class E> enum enum_set : E {};
template<class E> enum_set<E> operator|(enum_set<E>, enum_set<E>);
enum E { x = 1, y = 2, z = 4 };
using S = enum_set<E>;
auto s = S::x | S::y; // decltype(s) == S

2. Creating interoperable flag and set enumerations:
template<class E> enum enum_bitwise_operations {};
template<class E> enum_set<E> operator|(enum_bitwise_operations<E>,
enum_bitwise_operations<E>);
enum E : enum_bitwise_operations<E> { x = 1, y = 2, z = 4 };
auto s = E::x | E::y; // decltype(s) == enum_set<E>

3. Creating a combined flag and set enumeration:
template<class E> enum enum_combined_set {};
template<class E> enum_combined_set<E> operator|(enum_combined_set<E>,
enum_combined_set<E>);
enum E : enum_combined_set<E> { x = 1, y = 2, z = 4 };
auto e = E::x | E::y; // decltype(e) == E


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/86e312d1-140c-40fb-865d-5df63a084677%40isocpp.org.

------=_Part_525_491132970.1467205637128
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, 28 June 2016 15:50:07 UTC+1, Matthew Woehlke  =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-06-28 07:32, snk=
_kid wrote:
<br>&gt; None of the library solutions look ideal too me, why are people ag=
ainst=20
<br>&gt; having a standardized attribute? it seems like it should be a triv=
ial thing=20
<br>&gt; for compiler vendors to implement. I don&#39;t believe in this man=
tra that=20
<br>&gt; every new feature should (preferably) be or start off as a library=
 solution.
<br>
<br>As Sergey notes, an attribute is pretty much a non-starter. As any form
<br>of language feature, well, the bar for language features is higher, and
<br>this is a fairly esoteric (i.e. limited) use case. We generally like
<br>language features to be widely useful. That&#39;s less important for li=
brary
<br>features.
<br>
<br>A language feature that enabled this *and* a bunch of other awesome
<br>things would be much more palatable.
<br><br></blockquote><div><br></div><div>Perhaps allowing enumerations to h=
ave base type another enumeration (with enumerators declared at at most one=
 level) could work here? That way the operators could be picked up via ADL =
on the base type (with CRTP where appropriate).</div><div><br></div><div>Us=
e cases:</div><div><br></div><div>1. Creating a set type from an existing e=
numeration, without interfering with the original enum&#39;s operators:</di=
v><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187);=
 word-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> E</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">enum=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> enum_set =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> E </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> E</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> enum_set</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">E</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">|(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">enum_set</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">E</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> enum_set</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">E</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">e=
num</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> E </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> y </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> z </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">4</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> S </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> enum_set</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">E</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> S</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">|</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> S</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">y</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">// decltype(s) =3D=3D S</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></div></code></div><div><br></div><div>2. Cre=
ating interoperable flag and set enumerations:</div><div class=3D"prettypri=
nt" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">clas=
s</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> E</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> enum_bitwise_operations </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> E</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> enum_set</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">E</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">|(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">enum_bitwise_operations</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">E</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> enum_bitwise_operations</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">E</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&gt;);</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">enum</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> E </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> enum_bitwise_operations</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">E</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> y </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> z </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;=
" class=3D"styled-by-prettify">4</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> E</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">x </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">|</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> E</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">// decltype(s) =3D=
=3D enum_set&lt;E&gt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><div><br></div><div>3. Creating a =
combined flag and set enumeration:</div><div class=3D"prettyprint" style=3D=
"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-co=
lor: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><span style=3D"color: #008;" class=3D"styled-by-prettify">template=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> E</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">enum</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> enum_combined_set </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> E</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
enum_combined_set</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>E</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">|(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">enum_combined_set</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">E</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> enum_combined_set</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">E</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">enum</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> E </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> enum_co=
mbined_set</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">E</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> z </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">4</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> e </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> E</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">x </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">|</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 E</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">y</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// decltype(e) =3D=3D E </span></div></code=
></div><div><br></div><div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/86e312d1-140c-40fb-865d-5df63a084677%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/86e312d1-140c-40fb-865d-5df63a084677=
%40isocpp.org</a>.<br />

------=_Part_525_491132970.1467205637128--

------=_Part_524_1050854710.1467205637127--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Wed, 29 Jun 2016 06:15:41 -0700 (PDT)
Raw View
------=_Part_6556_1276236169.1467206141729
Content-Type: multipart/alternative;
 boundary="----=_Part_6557_833574607.1467206141729"

------=_Part_6557_833574607.1467206141729
Content-Type: text/plain; charset=UTF-8

On Wednesday, 29 June 2016 14:05:45 UTC+1, Sergey Vidyuk wrote:
>
> underlying_type do not fit here. If MyEnum underlying type uint8_t and it
>>> contains 10 items then BitMask<MyEnum> has 2^10 possible values while
>>> underlying_type can cover only 2^8. That's why I have additional template
>>> parameter T in my implementation. With static reflection it's possible co
>>> choose better default type then just uint64_t. From my personal point of
>>> view static reflection is the only blocker to implement this class properly
>>> but it will be great to have it as std::flags someday.
>>>
>>
>> Under the assumption that the enumerators of MyEnum have values 1, 2, 4,
>> etc. then MyEnum's underlying type would have to have at least 10 bits.
>>
>
> My BitMask implementation uses enum with default values (0,1,2..N) and
> perform 'RepresentationIntType(1) <<
> stutic_cast<RepresentationIntType>(enum_item);' internaly so one can write
>
> enum class Perm {Read, Write, Exec};
> using Perms = BitMask<Perm>;
>
> instead of
>
> enum class Perm {Read = 1, Write = 2, Exec = 4};
> using Perms = BitMask<Perm>;
>
> So I need max enum item value to find unsigned integer type which has at
> least MaxVal bits length.
>

Knowing the value range would just about be sufficient for your use case,
on the (realistic) assumption that bit lengths of integral types are powers
of two.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bcb39a22-fff6-4cda-8b10-da638ee368ca%40isocpp.org.

------=_Part_6557_833574607.1467206141729
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, 29 June 2016 14:05:45 UTC+1, Sergey Vidyuk  =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>underlying_type do not fit here. If My=
Enum underlying type uint8_t and it contains 10 items then BitMask&lt;MyEnu=
m&gt; has 2^10 possible values while underlying_type can cover only 2^8. Th=
at&#39;s why I have additional template parameter T in my implementation. W=
ith static reflection it&#39;s possible co choose better default type then =
just uint64_t. From my personal point of view static reflection is the only=
 blocker to implement this class properly but it will be great to have it a=
s std::flags someday.<br></div></div></blockquote><div><br></div><div>Under=
 the assumption that the enumerators of MyEnum have values 1, 2, 4, etc. th=
en MyEnum&#39;s underlying type would have to have at least 10 bits.</div><=
/div></blockquote><div>=C2=A0<br>My BitMask implementation uses enum with d=
efault values (0,1,2..N) and perform &#39;RepresentationIntType(1) &lt;&lt;=
 stutic_cast&lt;<wbr>RepresentationIntType&gt;(enum_<wbr>item);&#39; intern=
aly so one can write<br><br><div style=3D"background-color:rgb(250,250,250)=
;border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wra=
p:break-word"><code><div><span style=3D"color:#008">enum</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Perm</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#606">Read</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#606">Write</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Exec</span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"><br></span><span style=3D"color:#008">using</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Perms</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
 </span><span style=3D"color:#606">BitMask</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#606">Perm</span><span style=3D"color:#660=
">&gt;;</span><span style=3D"color:#000"><br></span></div></code></div><br>=
instead of<br><br><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wo=
rd"><code><div><span style=3D"color:#008">enum</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">class</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Perm</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#606">Rea=
d</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#066">1</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#606">Write</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#066">2</span><span style=3D"color:#660">,</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Exec</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#066">4</span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">using</span><span style=3D"color:#000"> </span><span style=3D"color:#606"=
>Perms</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Bit=
Mask</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#606"=
>Perm</span><span style=3D"color:#660">&gt;;</span><span style=3D"color:#00=
0"><br></span></div></code></div><br>So I need max enum item value to find =
unsigned integer type which has at least MaxVal bits length.<br></div></div=
></blockquote><div><br></div><div>Knowing the value range would just about =
be sufficient for your use case, on the (realistic) assumption that bit len=
gths of integral types are powers of two.</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bcb39a22-fff6-4cda-8b10-da638ee368ca%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bcb39a22-fff6-4cda-8b10-da638ee368ca=
%40isocpp.org</a>.<br />

------=_Part_6557_833574607.1467206141729--

------=_Part_6556_1276236169.1467206141729--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 29 Jun 2016 10:42:07 -0400
Raw View
On 2016-06-29 09:07, Edward Catmur wrote:
> On Tuesday, 28 June 2016 15:50:07 UTC+1, Matthew Woehlke wrote:
>> On 2016-06-28 07:32, snk_kid wrote:
>>> None of the library solutions look ideal too me, why are people against
>>> having a standardized attribute?
>>
>> As any form of language feature, well, the bar for language
>> features is higher, and this is a fairly esoteric (i.e. limited)
>> use case. We generally like language features to be widely useful.
>>
>> A language feature that enabled this *and* a bunch of other awesome
>> things would be much more palatable.
>
> Perhaps allowing enumerations to have base type another enumeration (with
> enumerators declared at at most one level) could work here? That way the
> operators could be picked up via ADL on the base type (with CRTP where
> appropriate).

Hmm...

> 2. Creating interoperable flag and set enumerations:
> template<class E> enum enum_bitwise_operations {};
> template<class E> enum_set<E> operator|(enum_bitwise_operations<E>,
> enum_bitwise_operations<E>);
> enum E : enum_bitwise_operations<E> { x = 1, y = 2, z = 4 };
> auto s = E::x | E::y; // decltype(s) == enum_set<E>

....yes, I think that would work! And I've wanted enum inheritance for
ages anyway.

Even better, that implementation only needs one operator|, not the three
pairs (Flag, Flags), (Flags, Flag) and (Flags, Flags), because the Flags
type is-a Flag.

A related reason why I want inheritance:

  enum class Flag : std::flag_enum<Flag>
  {
    Flag1 = 1<<0,
    Flag2 = 1<<1,
    Flag3 = 1<<2,
  };
  enum class FlagExt : Flag
  {
    LowFlags = Flag1 | Flag2,
  };
  using Flags = std::flags<FlagExt>;

That is, the ability to have one enum that has literally just the flags,
but also a second enum inheriting from the first that also has useful
combinations of flags that I can use anywhere a Flags is accepted.

--
Matthew

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/nl0mnv%24s4q%241%40ger.gmane.org.

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 29 Jun 2016 10:48:24 -0400
Raw View
On 2016-06-29 00:30, Sergey Vidyuk wrote:
> On 2016-06-28 10:45, Matthew Woehlke wrote:
>> On 2016-06-28 06:27, Sergey Vidyuk wrote:=20
>>> One more issue here is inverse operation can't be implemented in=20
>>> order the following code work without triggering assertion:=20
>>>
>>> enum class Day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};=20
>>> using Days =3D BitMask<Day>;=20
>>>
>>> const Days workdays =3D ~(Day::Sat | Day::Sun);=20
>>> assert(workdays =3D=3D Day::Mon | Day::Tue | Day::Wed | Day:Thu | Day::=
Fry);=20
>>
>> That's... hard to get right. QFlags deals with this by promoting the=20
>> result of operator~ to int=C2=B9, and allowing int as one of the types t=
o=20
>> operator&. Trying to comprehend the set of all actual flags is...=20
>> hard(er). Maybe with introspection it will be possible... but I'm=20
>> honestly not entirely convinced it wouldn't have corner cases...=20
>
> There is a huge issue with inverse operator. The following example works =
as=20
> expected:
>=20
> bool contains_weekend(Days days) {
>   return (days & (Day::Sat | Day::Sun));
> }
>=20
> while the next one breaks if inversion was used during function parameter=
=20
> calculation:
>=20
> bool contains_workday(Days days) {
>   return (days & ~(Day::Sat | Day::Sun));
> }

Not... quite. Inversion doesn't give you the flags type, it gives you
the integer type (call it a 'mask' type). So you have to bend over
backwards to coerce the result of an inversion back into the flags type.
At that point, you deserve to get bitten :-).

You could build the parameter something like:

  auto days =3D Days::EveryDay & ~(Day::Sun);

....because applying a mask to a Flags still gives a Flags. But you
couldn't do this (without a static_cast):

  auto w =3D contains_workday(~Day::Sun);

In fact, I think there is another reason for things to work like this...
ABI compatibility. Doing it this way, the result of operator~ is wholly
dependent on its inputs, which means it doesn't change if I add a flag,
which means applications compiled against an old library version (the
flags being defined in said library) are fine. If implemented with
reflection, adding a flag becomes a BIC and I now have to recompile the
application after such a change. That doesn't seem to me like a good
thing :-).

> With static reflection propsal it's possible to calculate additional=20
> numeric template parameter which will contain only bits related to the en=
um=20
> items and perform bitwise and  with it in the operator~ implementation.=
=20
> Promoting to bitmask representation type (int in case of QFlags or extra=
=20
> template parameter in my ButMask) do not really solve's this issue. It ha=
ve=20
> to be solved in a user code:
>=20
> bool contains_workday(Days days) {
>   // TODO: Do not forget to update line bellow when adding new item to Da=
y=20
> enum
>   days =3D days & (Day::Mon | Day::Tue | Day::Wed | Day::Thu | Day::Fry |=
=20
> Day::Sat | Day::Sun);
>   return (days & ~(Day::Sat | Day::Sun));
> }

Two reasons this isn't a problem. One, as above, it is an error to pass
a value of days that has bits not in Day. Two, most people writing code
like this are going to write a mask constant near where the Day enum is
defined so that only one place needs to be changed when adding a flag.

>> (=C2=B9 A std implementation should use underlying_type, obviously.)=20
>
> underlying_type do not fit here. If MyEnum underlying type uint8_t and it=
=20
> contains 10 items then BitMask<MyEnum> has 2^10 possible values while=20
> underlying_type can cover only 2^8.

No. If the enum has underlying type uint8_t and has 10 items, some of
those must either be duplicates or combinations, as there are only 8
bits available!

The flags helper class (at least, not QFlags, and not any version I
would be okay with) uses the underlying values as operands in binary
arithmetic. It is NOT a fancy std::[unordered_]set as you seem to be
thinking.

--=20
Matthew

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/nl0n3o%24b0%241%40ger.gmane.org.

.