Topic: Proposal for two new traits: `std::greedy_conjunction`


Author: mateusz.janek6@gmail.com
Date: Wed, 9 Aug 2017 05:31:54 -0700 (PDT)
Raw View
------=_Part_5175_1112885924.1502281914947
Content-Type: multipart/alternative;
 boundary="----=_Part_5176_1211584219.1502281914949"

------=_Part_5176_1211584219.1502281914949
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

*Introduction*

C++17 introduced besides the others two new structures in `<type_traits>`=
=20
header: `std::conjuction` and `std::disjunction`. They are very useful in=
=20
metaprogramming, but standard has in some way forced their implementation.=
=20
In p0013r1=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html> we=
=20
can read:
The BaseCharacteristic of a specialization conjunction<B1, ..., BN> is the=
=20
first type Bi in the list true_type, B1, ..., BN for which Bi::value =3D=3D=
=20
false, or if every Bi::value !=3D false the BaseCharacteristic is BN. [*Not=
e:* This=20
means a specialization of conjunction does not necessarily have a=20
BaseCharacteristic of either true_type or false_type. =E2=80=94 *end note*]

Similar in the disjunction:=20
The BaseCharacteristic of a specialization disjunction<B1, ..., BN> is the=
=20
first type Bi in the list false_type, B1, ..., BN for which Bi::value !=3D=
=20
false, or if every Bi::value =3D=3D false the BaseCharacteristic is BN. [*N=
ote:* This=20
means a specialization of disjunction does not necessarily have a=20
BaseCharacteristic of either true_type or false_type. =E2=80=94 *end note*]

I'd like to propose a two new structures in `<type_traits>`:=20
`std::greedy_conjunction` and `std::greedy_disjunction`. Their results=20
would very similar to the ones from `std::conjunciton` and=20
`std::disjunction`, but their specification would give more flexibility to=
=20
the standard library creators.


*Motivation and Scope*

With `std::conjuction` and `std::disjunction` restrictions in the standard,=
=20
library creators are forced to make them in such (or similar) way:
template<class...> struct conjunction : std::true_type { };
template<class B1> struct conjunction<B1> : B1 { };
template<class B1, class... Bn>
struct conjunction<B1, Bn...>=20
    : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
   =20
template<class...> struct disjunction : std::false_type { };
template<class B1> struct disjunction<B1> : B1 { };
template<class B1, class... Bn>
struct disjunction<B1, Bn...>=20
    : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  { };


   =20
There are strong grounds to keep these implementations, e.g.=20
short-circuiting, getting information on what type, recursion stopped etc.=
=20
Although, because of these restrictions compilation time suffers in some=20
cases.

*Why new, very similar traits?*
*Abstract*
During my pull request to folly (https://github.com/facebook/folly/pull/643=
)=20
Jay Feldblum posted there a small benchmark script:=20
https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (big=20
credits for poking my brain with the idea). I was surprised that, let's=20
say, the naive implementation compiles faster that the standard one.=20

I decided to benchmark this idea deeper:
-problem was to find in a types sequence if there is a type which T::value=
=20
is equal to 0
-for every benchmark sequence has 1024 types inside
-tested sequences with two kinds of types: light and heavy to instantiate
-tested best and worse cases
-tested two new implementations: fold expression and bool-pack
-core benchmark was to measure the compilation time with given compiler=20
(clang++-4.0/g++-6), case (best/worse), type (light/heavy), implementation=
=20
(proposed/standard). Every compilation case was ran 500 times and average=
=20
result was calculated.

Whole benchmarks code you can find in the gh repo:=20
https://github.com/stryku/boolpack_vs_recursion

And here are the results (sorry for not posting it here, but table was too=
=20
big and it was formatted in unreadable way):
https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/outpu=
t

As you can see, standard implementation is way better when we deal with the=
=20
best case. It can compile 80x(!) faster than the proposed ones. Problem=20
starts when the worse cases occurs.=20
Standard library creators would be able to implement `greedy_conjunction`=
=20
and `greedy_disjunction` in a way that they compiles up to around 6x faster=
=20
than the standard one. Users would be able choose implementation which will=
=20
suit best, based on what cases they are mostly expecting.

*Specification*
Since it's a pre-proposal I don't want to post fully described=20
specification. I'm thinking about it in this way:

`std::greedy_conjunction` would be an alias or would derive from a type,=20
which has a constexpr member `value` which can be converted to bool and is=
=20
equal to:
-false if any bool(Tn::value0 =3D=3D false
-true otherwise

`std::greedy_disjunction` would be an alias or would derive from a type,=20
which has a constexpr member `value` which can be converted to bool and is=
=20
equal to:
-false if all bool(Tn::value) =3D=3D false
-true otherwise

*Example implementations*
bool-pack (this one seems to compile faster than fold expression):
template <bool... Bn>
struct __bools {};

template <typename... Tn>=20
struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn::valu=
e
)...>, __bools<(Tn::value && false)...>>> {};

template <typename... Tn>=20
struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>, __bool=
s
<(Tn::value || true)...>> {};


fold expression:
template <typename... Tn>=20
struct greedy_disjunction : std::bool_constant<(false || ... || bool(Tn::
value))> {};

template <typename... Tn>=20
struct greedy_conjunction : std::bool_constant<(true && ... && bool(Tn::
value))> {};


*Wordings:*
*There is couple of questions*
I asked them to myself a lot, during this pre-proposal.
-Is it in the C++ standard scope to care about how things will be=20
implemented in standard library, even if the implementations will be not=20
efficient on compile-time level?
-Should the standard be changed because of standard library compilation=20
time?

And here's my conclusion (and reason why I'm writing this post).
C++ standard purpose is not to specify a theoretical language. It's created=
=20
to be used by a lot of people in the real world. Giving a choice to user=20
between implementations which differs in a compile-time efficiency is same=
=20
thing as to give a choice between containers e.g. `std::vector` and=20
`std::list`. In some cases one implementation is better, in others the=20
other one.

*And of course the name*
I thought about `strict_*` (like it's in Facebook/folly lib) instead of=20
`greedy_*`, but I'm sure that if this proposal is a thing community will=20
propose better names.


What do you think?

Mateusz (stryku) Janek

--=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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.or=
g.

------=_Part_5176_1211584219.1502281914949
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><b><font size=3D"4">Introduction</font></b></div><div=
><br></div><div>C++17 introduced besides the others two new structures in `=
&lt;type_traits&gt;` header: `std::conjuction` and `std::disjunction`. They=
 are very useful in metaprogramming, but standard has in some way forced th=
eir implementation.=C2=A0</div><div>In <a href=3D"http://www.open-std.org/j=
tc1/sc22/wg21/docs/papers/2015/p0013r1.html">p0013r1</a>=C2=A0we can read:<=
/div><div><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Times Ne=
w Roman&quot;; font-size: medium; text-align: justify;">The BaseCharacteris=
tic of a specialization=C2=A0</span><code style=3D"color: rgb(0, 160, 0); t=
ext-align: justify;">conjunction&lt;B1, ..., BN&gt;</code><span style=3D"co=
lor: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: m=
edium; text-align: justify;">=C2=A0is the first type=C2=A0</span><code styl=
e=3D"color: rgb(0, 160, 0); text-align: justify;">Bi</code><span style=3D"c=
olor: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: =
medium; text-align: justify;">=C2=A0in the list=C2=A0</span><code style=3D"=
color: rgb(0, 160, 0); text-align: justify;">true_type, B1, ..., BN</code><=
span style=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quo=
t;; font-size: medium; text-align: justify;">=C2=A0for which=C2=A0</span><c=
ode style=3D"color: rgb(0, 160, 0); text-align: justify;">Bi::value =3D=3D =
false</code><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Times =
New Roman&quot;; font-size: medium; text-align: justify;">, or if every=C2=
=A0</span><code style=3D"color: rgb(0, 160, 0); text-align: justify;">Bi::v=
alue !=3D false</code><span style=3D"color: rgb(0, 160, 0); font-family: &q=
uot;Times New Roman&quot;; font-size: medium; text-align: justify;">=C2=A0t=
he BaseCharacteristic is=C2=A0</span><code style=3D"color: rgb(0, 160, 0); =
text-align: justify;">BN</code><span style=3D"color: rgb(0, 160, 0); font-f=
amily: &quot;Times New Roman&quot;; font-size: medium; text-align: justify;=
">. [</span><em style=3D"color: rgb(0, 160, 0); font-family: &quot;Times Ne=
w Roman&quot;; font-size: medium; text-align: justify;">Note:</em><span sty=
le=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font=
-size: medium; text-align: justify;">=C2=A0This means a specialization of=
=C2=A0</span><code style=3D"color: rgb(0, 160, 0); text-align: justify;">co=
njunction</code><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Ti=
mes New Roman&quot;; font-size: medium; text-align: justify;">=C2=A0does no=
t necessarily have a BaseCharacteristic of either=C2=A0</span><code style=
=3D"color: rgb(0, 160, 0); text-align: justify;">true_type</code><span styl=
e=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-=
size: medium; text-align: justify;">=C2=A0or=C2=A0</span><code style=3D"col=
or: rgb(0, 160, 0); text-align: justify;">false_type</code><span style=3D"c=
olor: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: =
medium; text-align: justify;">. =E2=80=94=C2=A0</span><em style=3D"color: r=
gb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: medium;=
 text-align: justify;">end note</em><span style=3D"color: rgb(0, 160, 0); f=
ont-family: &quot;Times New Roman&quot;; font-size: medium; text-align: jus=
tify;">]</span><br></div><div><span style=3D"color: rgb(0, 160, 0); font-fa=
mily: &quot;Times New Roman&quot;; font-size: medium; text-align: justify;"=
><br></span></div><div>Similar in the disjunction:=C2=A0</div><div><span st=
yle=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; fon=
t-size: medium; text-align: justify;">The BaseCharacteristic of a specializ=
ation=C2=A0</span><code style=3D"color: rgb(0, 160, 0); text-align: justify=
;">disjunction&lt;B1, ..., BN&gt;</code><span style=3D"color: rgb(0, 160, 0=
); font-family: &quot;Times New Roman&quot;; font-size: medium; text-align:=
 justify;">=C2=A0is the first type=C2=A0</span><code style=3D"color: rgb(0,=
 160, 0); text-align: justify;">Bi</code><span style=3D"color: rgb(0, 160, =
0); font-family: &quot;Times New Roman&quot;; font-size: medium; text-align=
: justify;">=C2=A0in the list=C2=A0</span><code style=3D"color: rgb(0, 160,=
 0); text-align: justify;">false_type, B1, ..., BN</code><span style=3D"col=
or: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: me=
dium; text-align: justify;">=C2=A0for which=C2=A0</span><code style=3D"colo=
r: rgb(0, 160, 0); text-align: justify;">Bi::value !=3D false</code><span s=
tyle=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; fo=
nt-size: medium; text-align: justify;">, or if every=C2=A0</span><code styl=
e=3D"color: rgb(0, 160, 0); text-align: justify;">Bi::value =3D=3D false</c=
ode><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roma=
n&quot;; font-size: medium; text-align: justify;">=C2=A0the BaseCharacteris=
tic is=C2=A0</span><code style=3D"color: rgb(0, 160, 0); text-align: justif=
y;">BN</code><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Times=
 New Roman&quot;; font-size: medium; text-align: justify;">. [</span><em st=
yle=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;; fon=
t-size: medium; text-align: justify;">Note:</em><span style=3D"color: rgb(0=
, 160, 0); font-family: &quot;Times New Roman&quot;; font-size: medium; tex=
t-align: justify;">=C2=A0This means a specialization of=C2=A0</span><code s=
tyle=3D"color: rgb(0, 160, 0); text-align: justify;">disjunction</code><spa=
n style=3D"color: rgb(0, 160, 0); font-family: &quot;Times New Roman&quot;;=
 font-size: medium; text-align: justify;">=C2=A0does not necessarily have a=
 BaseCharacteristic of either=C2=A0</span><code style=3D"color: rgb(0, 160,=
 0); text-align: justify;">true_type</code><span style=3D"color: rgb(0, 160=
, 0); font-family: &quot;Times New Roman&quot;; font-size: medium; text-ali=
gn: justify;">=C2=A0or=C2=A0</span><code style=3D"color: rgb(0, 160, 0); te=
xt-align: justify;">false_type</code><span style=3D"color: rgb(0, 160, 0); =
font-family: &quot;Times New Roman&quot;; font-size: medium; text-align: ju=
stify;">. =E2=80=94=C2=A0</span><em style=3D"color: rgb(0, 160, 0); font-fa=
mily: &quot;Times New Roman&quot;; font-size: medium; text-align: justify;"=
>end note</em><span style=3D"color: rgb(0, 160, 0); font-family: &quot;Time=
s New Roman&quot;; font-size: medium; text-align: justify;">]</span><br></d=
iv><div><br></div><div>I&#39;d like to propose a two new structures in `&lt=
;type_traits&gt;`: `std::greedy_conjunction` and `std::greedy_disjunction`.=
 Their results would very similar to the ones from `std::conjunciton` and `=
std::disjunction`, but their specification would give more flexibility to t=
he standard library creators.</div><div><br></div><div><br></div><div><b><f=
ont size=3D"4">Motivation and Scope</font></b></div><div><br></div><div>Wit=
h `std::conjuction` and `std::disjunction` restrictions in the standard, li=
brary creators are forced to make them in such (or similar) way:</div><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-wr=
ap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">class</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">struct</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> conjunction </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">true_type </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: #660;" class=3D"styled-by-prettify">};</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n 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><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> B1</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">struct</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> conjunction</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">B1</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> B1 </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #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 style=3D"color: #008;" class=3D"st=
yled-by-prettify">template</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> B1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/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: #660;" class=3D"styled-by-prettify">...</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Bn</span><span style=3D"color: #660;" cla=
ss=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">struct</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> conjunction</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">B1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Bn</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">:</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"styled-by-prettify">conditional_t</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">bool</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">B1</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">valu=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> conjunction</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Bn</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...&gt;,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> B1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 <br></span><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: #660;" class=3D"s=
tyled-by-prettify">...&gt;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> disjunction </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">false_type </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </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">template</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> B1</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> disjunction=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">B1</span><span s=
tyle=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=
: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> B1 </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: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></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"styled-by-prettify">class</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> B1</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: #008;" =
class=3D"styled-by-prettify">class</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pr=
ettify">Bn</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">struct</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> disjunction</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">B1</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">Bn</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">...&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">conditional_t</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>bool</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">B1</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">value</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> B1</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> disjunction</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled=
-by-prettify">Bn</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">...&gt;&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div><=
/code></div><div><br>=C2=A0 =C2=A0=C2=A0</div><div>There are strong grounds=
 to keep these implementations, e.g. short-circuiting, getting information =
on what type, recursion stopped etc. Although, because of these restriction=
s compilation time suffers in some cases.</div><div><br></div><div><b><font=
 size=3D"4">Why new,=C2=A0<u>very similar</u> traits?</font></b></div><div>=
<b>Abstract</b></div><div>During my pull request to folly (<a href=3D"https=
://github.com/facebook/folly/pull/643">https://github.com/facebook/folly/pu=
ll/643</a>) Jay Feldblum posted there a small benchmark script: <a href=3D"=
https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b">https:/=
/gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b</a>=C2=A0(big c=
redits for poking my brain with the idea). I was surprised that, let&#39;s =
say, the naive implementation compiles faster that the standard one.=C2=A0<=
/div><div><br></div><div>I decided to benchmark this idea deeper:</div><div=
>-problem was to find in a types sequence if there is a type which T::value=
 is equal to 0</div><div>-for every benchmark sequence has 1024 types insid=
e</div><div>-tested sequences with two kinds of types: light and heavy to i=
nstantiate</div><div>-tested best and worse cases</div><div>-tested two new=
 implementations: fold expression and bool-pack</div><div>-core benchmark w=
as to measure the compilation time with given compiler (clang++-4.0/g++-6),=
 case (best/worse), type (light/heavy), implementation (proposed/standard).=
 Every compilation case was ran 500 times and average result was calculated=
..</div><div><br></div><div>Whole benchmarks code you can find in the gh rep=
o:=C2=A0<a href=3D"https://github.com/stryku/boolpack_vs_recursion">https:/=
/github.com/stryku/boolpack_vs_recursion</a></div><div><br></div><div>And h=
ere are the results (sorry for not posting it here, but table was too big a=
nd it was formatted in unreadable way):</div><div><a href=3D"https://raw.gi=
thubusercontent.com/stryku/boolpack_vs_recursion/master/output">https://raw=
..githubusercontent.com/stryku/boolpack_vs_recursion/master/output</a></div>=
<div><br></div><div>As you can see, standard implementation is way better w=
hen we deal with the best case. It can compile 80x(!) faster than the propo=
sed ones. Problem starts when the worse cases occurs.=C2=A0</div><div>Stand=
ard library creators would be able to implement `greedy_conjunction` and `g=
reedy_disjunction` in a way that they compiles up to around 6x faster than =
the standard one. Users would be able choose implementation which will suit=
 best, based on what cases they are mostly expecting.</div><div><br></div><=
div><font size=3D"4"><b>Specification</b></font></div><div>Since it&#39;s a=
 pre-proposal I don&#39;t want to post fully described specification. I&#39=
;m thinking about it in this way:</div><div><br></div><div>`std::greedy_con=
junction` would be an alias or would derive from a type, which has a conste=
xpr member `value` which can be converted to bool and is equal to:</div><di=
v>-false if any bool(Tn::value0 =3D=3D false</div><div>-true otherwise</div=
><div><br></div><div><div>`std::greedy_disjunction` would be an alias or wo=
uld derive from a type, which has a constexpr member `value` which can be c=
onverted to bool and is equal to:</div><div>-false if all bool(Tn::value) =
=3D=3D false</div><div>-true otherwise</div></div><div><br></div><div><font=
 size=3D"4"><b>Example implementations</b></font></div><div>bool-pack (this=
 one seems to compile faster than fold expression):</div><div class=3D"pret=
typrint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(1=
87, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wor=
d;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Bn</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">struct</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> __bools </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">template</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">Tn</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> <br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
uct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> greedy=
_disjunction</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">negation</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">is_same</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">__bools</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">bool</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
Tn</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">value</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)...&gt;,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> __bools</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;(</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Tn</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">value </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">false</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">)...&gt;&gt;&gt;</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: #000;" class=3D"styled-by-prettif=
y"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">Tn</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> <br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> greedy_conjunction</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">:</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"styled-by-pret=
tify">is_same</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">__b=
ools</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Tn</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">value</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)...&gt;,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> __bools</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;(</span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Tn</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">value </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: #008;" class=3D"styled-by-prettify">true</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)...&gt;&gt;</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></div></code></div><div><br=
><br></div><div>fold expression:</div><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">typename</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Tn</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">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> greedy_disjunction </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">:</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"styled-by-prettify">bool_constant</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;(</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">false</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"> </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: #660;" class=3D"styled-by-prettify">||</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">Tn</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">value</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">))&gt;</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><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">template</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #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">Tn</span><span style=3D"color: #660;" class=3D"styl=
ed-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-prett=
ify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> greedy_conjunction </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">:</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"styled-by-prettify">bool_constan=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;(</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">true</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&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: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">bool</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
Tn</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">value</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">))&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br><b=
r></div><div><font size=3D"4"><b>Wordings:</b></font></div><div><b>There is=
 couple of questions</b></div><div>I asked them to myself a lot, during thi=
s pre-proposal.</div><div>-Is it in the C++ standard scope to care about ho=
w things will be implemented in standard library, even if the implementatio=
ns will be not efficient on compile-time level?</div><div>-Should the stand=
ard be changed because of standard library compilation time?</div><div><br>=
</div><div>And here&#39;s my conclusion (and reason why I&#39;m writing thi=
s post).</div><div>C++ standard purpose is not to specify a theoretical lan=
guage. It&#39;s created to be used by a lot of people in the real world. Gi=
ving a choice to user between implementations which differs in a compile-ti=
me efficiency is same thing as to give a choice between containers e.g. `st=
d::vector` and `std::list`. In some cases one implementation is better, in =
others the other one.</div><div><br></div><div><b>And of course the name</b=
></div><div>I thought about `strict_*` (like it&#39;s in Facebook/folly lib=
) instead of `greedy_*`, but I&#39;m sure that if this proposal is a thing =
community will propose better names.</div><div><br></div><div><br></div><di=
v>What do you think?</div><div><br></div><div>Mateusz (stryku) Janek</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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2=
%40isocpp.org</a>.<br />

------=_Part_5176_1211584219.1502281914949--

------=_Part_5175_1112885924.1502281914947--

.


Author: =?UTF-8?Q?Micha=C5=82_Dominiak?= <griwes@griwes.info>
Date: Wed, 09 Aug 2017 12:36:51 +0000
Raw View
--94eb2c03c1483c429c0556515619
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

You can already write your "greedy" things by just... deriving from
bool_constant directly (exactly like in your last snippet). You couldn't do
what the two traits are doing directly, and that's I believe is the only
justification of their existence. Your thing doesn't seem to be very useful=
..

On Wed, Aug 9, 2017 at 2:31 PM <mateusz.janek6@gmail.com> wrote:

> *Introduction*
>
> C++17 introduced besides the others two new structures in `<type_traits>`
> header: `std::conjuction` and `std::disjunction`. They are very useful in
> metaprogramming, but standard has in some way forced their implementation=
..
> In p0013r1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html> we
> can read:
> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> is
> the first type Bi in the list true_type, B1, ..., BN for which Bi::value
> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristic is =
BN. [
> *Note:* This means a specialization of conjunction does not necessarily
> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 *e=
nd note*]
>
> Similar in the disjunction:
> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> is
> the first type Bi in the list false_type, B1, ..., BN for which Bi::value
> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristic is =
BN. [
> *Note:* This means a specialization of disjunction does not necessarily
> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 *e=
nd note*]
>
> I'd like to propose a two new structures in `<type_traits>`:
> `std::greedy_conjunction` and `std::greedy_disjunction`. Their results
> would very similar to the ones from `std::conjunciton` and
> `std::disjunction`, but their specification would give more flexibility t=
o
> the standard library creators.
>
>
> *Motivation and Scope*
>
> With `std::conjuction` and `std::disjunction` restrictions in the
> standard, library creators are forced to make them in such (or similar) w=
ay:
> template<class...> struct conjunction : std::true_type { };
> template<class B1> struct conjunction<B1> : B1 { };
> template<class B1, class... Bn>
> struct conjunction<B1, Bn...>
>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
>
> template<class...> struct disjunction : std::false_type { };
> template<class B1> struct disjunction<B1> : B1 { };
> template<class B1, class... Bn>
> struct disjunction<B1, Bn...>
>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  { };
>
>
>
> There are strong grounds to keep these implementations, e.g.
> short-circuiting, getting information on what type, recursion stopped etc=
..
> Although, because of these restrictions compilation time suffers in some
> cases.
>
> *Why new, very similar traits?*
> *Abstract*
> During my pull request to folly (
> https://github.com/facebook/folly/pull/643) Jay Feldblum posted there a
> small benchmark script:
> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (big
> credits for poking my brain with the idea). I was surprised that, let's
> say, the naive implementation compiles faster that the standard one.
>
> I decided to benchmark this idea deeper:
> -problem was to find in a types sequence if there is a type which T::valu=
e
> is equal to 0
> -for every benchmark sequence has 1024 types inside
> -tested sequences with two kinds of types: light and heavy to instantiate
> -tested best and worse cases
> -tested two new implementations: fold expression and bool-pack
> -core benchmark was to measure the compilation time with given compiler
> (clang++-4.0/g++-6), case (best/worse), type (light/heavy), implementatio=
n
> (proposed/standard). Every compilation case was ran 500 times and average
> result was calculated.
>
> Whole benchmarks code you can find in the gh repo:
> https://github.com/stryku/boolpack_vs_recursion
>
> And here are the results (sorry for not posting it here, but table was to=
o
> big and it was formatted in unreadable way):
>
> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/out=
put
>
> As you can see, standard implementation is way better when we deal with
> the best case. It can compile 80x(!) faster than the proposed ones. Probl=
em
> starts when the worse cases occurs.
> Standard library creators would be able to implement `greedy_conjunction`
> and `greedy_disjunction` in a way that they compiles up to around 6x fast=
er
> than the standard one. Users would be able choose implementation which wi=
ll
> suit best, based on what cases they are mostly expecting.
>
> *Specification*
> Since it's a pre-proposal I don't want to post fully described
> specification. I'm thinking about it in this way:
>
> `std::greedy_conjunction` would be an alias or would derive from a type,
> which has a constexpr member `value` which can be converted to bool and i=
s
> equal to:
> -false if any bool(Tn::value0 =3D=3D false
> -true otherwise
>
> `std::greedy_disjunction` would be an alias or would derive from a type,
> which has a constexpr member `value` which can be converted to bool and i=
s
> equal to:
> -false if all bool(Tn::value) =3D=3D false
> -true otherwise
>
> *Example implementations*
> bool-pack (this one seems to compile faster than fold expression):
> template <bool... Bn>
> struct __bools {};
>
> template <typename... Tn>
> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn::
> value)...>, __bools<(Tn::value && false)...>>> {};
>
> template <typename... Tn>
> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,
> __bools<(Tn::value || true)...>> {};
>
>
> fold expression:
> template <typename... Tn>
> struct greedy_disjunction : std::bool_constant<(false || ... || bool(Tn::
> value))> {};
>
> template <typename... Tn>
> struct greedy_conjunction : std::bool_constant<(true && ... && bool(Tn::
> value))> {};
>
>
> *Wordings:*
> *There is couple of questions*
> I asked them to myself a lot, during this pre-proposal.
> -Is it in the C++ standard scope to care about how things will be
> implemented in standard library, even if the implementations will be not
> efficient on compile-time level?
> -Should the standard be changed because of standard library compilation
> time?
>
> And here's my conclusion (and reason why I'm writing this post).
> C++ standard purpose is not to specify a theoretical language. It's
> created to be used by a lot of people in the real world. Giving a choice =
to
> user between implementations which differs in a compile-time efficiency i=
s
> same thing as to give a choice between containers e.g. `std::vector` and
> `std::list`. In some cases one implementation is better, in others the
> other one.
>
> *And of course the name*
> I thought about `strict_*` (like it's in Facebook/folly lib) instead of
> `greedy_*`, but I'm sure that if this proposal is a thing community will
> propose better names.
>
>
> What do you think?
>
> Mateusz (stryku) Janek
>
> --
> 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/a79ce0b4-ca2=
d-4c37-b49e-cb707689a0e2%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca=
2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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/CAPCFJdSoAKm4SO4PQrs93ZGzH-nBexfO0X_3OEw4b5RJXqM=
49g%40mail.gmail.com.

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

<div dir=3D"ltr">You can already write your &quot;greedy&quot; things by ju=
st... deriving from bool_constant directly (exactly like in your last snipp=
et). You couldn&#39;t do what the two traits are doing directly, and that&#=
39;s I believe is the only justification of their existence. Your thing doe=
sn&#39;t seem to be very useful.</div><br><div class=3D"gmail_quote"><div d=
ir=3D"ltr">On Wed, Aug 9, 2017 at 2:31 PM &lt;<a href=3D"mailto:mateusz.jan=
ek6@gmail.com">mateusz.janek6@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div><b><font size=3D"4">Introduction<=
/font></b></div><div><br></div><div>C++17 introduced besides the others two=
 new structures in `&lt;type_traits&gt;` header: `std::conjuction` and `std=
::disjunction`. They are very useful in metaprogramming, but standard has i=
n some way forced their implementation.=C2=A0</div><div>In <a href=3D"http:=
//www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html" target=3D"=
_blank">p0013r1</a>=C2=A0we can read:</div><div><span style=3D"color:rgb(0,=
160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:=
justify">The BaseCharacteristic of a specialization=C2=A0</span><code style=
=3D"color:rgb(0,160,0);text-align:justify">conjunction&lt;B1, ..., BN&gt;</=
code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&qu=
ot;;font-size:medium;text-align:justify">=C2=A0is the first type=C2=A0</spa=
n><code style=3D"color:rgb(0,160,0);text-align:justify">Bi</code><span styl=
e=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:m=
edium;text-align:justify">=C2=A0in the list=C2=A0</span><code style=3D"colo=
r:rgb(0,160,0);text-align:justify">true_type, B1, ..., BN</code><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">=C2=A0for which=C2=A0</span><code style=3D"color:r=
gb(0,160,0);text-align:justify">Bi::value =3D=3D false</code><span style=3D=
"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:mediu=
m;text-align:justify">, or if every=C2=A0</span><code style=3D"color:rgb(0,=
160,0);text-align:justify">Bi::value !=3D false</code><span style=3D"color:=
rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-=
align:justify">=C2=A0the BaseCharacteristic is=C2=A0</span><code style=3D"c=
olor:rgb(0,160,0);text-align:justify">BN</code><span style=3D"color:rgb(0,1=
60,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:j=
ustify">. [</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times N=
ew Roman&quot;;font-size:medium;text-align:justify">Note:</em><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">=C2=A0This means a specialization of=C2=A0</span><=
code style=3D"color:rgb(0,160,0);text-align:justify">conjunction</code><spa=
n style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-=
size:medium;text-align:justify">=C2=A0does not necessarily have a BaseChara=
cteristic of either=C2=A0</span><code style=3D"color:rgb(0,160,0);text-alig=
n:justify">true_type</code><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0or=C2=
=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">false_type<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">. =E2=80=94=C2=A0</span><em style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">end note</em><span style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">]=
</span><br></div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;T=
imes New Roman&quot;;font-size:medium;text-align:justify"><br></span></div>=
<div>Similar in the disjunction:=C2=A0</div><div><span style=3D"color:rgb(0=
,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align=
:justify">The BaseCharacteristic of a specialization=C2=A0</span><code styl=
e=3D"color:rgb(0,160,0);text-align:justify">disjunction&lt;B1, ..., BN&gt;<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">=C2=A0is the first type=C2=A0</sp=
an><code style=3D"color:rgb(0,160,0);text-align:justify">Bi</code><span sty=
le=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:=
medium;text-align:justify">=C2=A0in the list=C2=A0</span><code style=3D"col=
or:rgb(0,160,0);text-align:justify">false_type, B1, ..., BN</code><span sty=
le=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:=
medium;text-align:justify">=C2=A0for which=C2=A0</span><code style=3D"color=
:rgb(0,160,0);text-align:justify">Bi::value !=3D false</code><span style=3D=
"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:mediu=
m;text-align:justify">, or if every=C2=A0</span><code style=3D"color:rgb(0,=
160,0);text-align:justify">Bi::value =3D=3D false</code><span style=3D"colo=
r:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;tex=
t-align:justify">=C2=A0the BaseCharacteristic is=C2=A0</span><code style=3D=
"color:rgb(0,160,0);text-align:justify">BN</code><span style=3D"color:rgb(0=
,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align=
:justify">. [</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times=
 New Roman&quot;;font-size:medium;text-align:justify">Note:</em><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">=C2=A0This means a specialization of=C2=A0</span><=
code style=3D"color:rgb(0,160,0);text-align:justify">disjunction</code><spa=
n style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-=
size:medium;text-align:justify">=C2=A0does not necessarily have a BaseChara=
cteristic of either=C2=A0</span><code style=3D"color:rgb(0,160,0);text-alig=
n:justify">true_type</code><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0or=C2=
=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">false_type<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">. =E2=80=94=C2=A0</span><em style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">end note</em><span style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">]=
</span><br></div><div><br></div><div>I&#39;d like to propose a two new stru=
ctures in `&lt;type_traits&gt;`: `std::greedy_conjunction` and `std::greedy=
_disjunction`. Their results would very similar to the ones from `std::conj=
unciton` and `std::disjunction`, but their specification would give more fl=
exibility to the standard library creators.</div><div><br></div><div><br></=
div><div><b><font size=3D"4">Motivation and Scope</font></b></div><div><br>=
</div><div>With `std::conjuction` and `std::disjunction` restrictions in th=
e standard, library creators are forced to make them in such (or similar) w=
ay:</div><div class=3D"m_4634687379900140548prettyprint" style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px;word-wrap:break-word"><code class=3D"m_4634687379900140548p=
rettyprint"><div class=3D"m_4634687379900140548subprettyprint"><span style=
=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify">template<=
/span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pr=
ettify">&lt;</span><span style=3D"color:#008" class=3D"m_463468737990014054=
8styled-by-prettify">class</span><span style=3D"color:#660" class=3D"m_4634=
687379900140548styled-by-prettify">...&gt;</span><span style=3D"color:#000"=
 class=3D"m_4634687379900140548styled-by-prettify"> </span><span style=3D"c=
olor:#008" class=3D"m_4634687379900140548styled-by-prettify">struct</span><=
span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"=
> conjunction </span><span style=3D"color:#660" class=3D"m_4634687379900140=
548styled-by-prettify">:</span><span style=3D"color:#000" class=3D"m_463468=
7379900140548styled-by-prettify"> std</span><span style=3D"color:#660" clas=
s=3D"m_4634687379900140548styled-by-prettify">::</span><span style=3D"color=
:#000" class=3D"m_4634687379900140548styled-by-prettify">true_type </span><=
span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify"=
>{</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by=
-prettify"> </span><span style=3D"color:#660" class=3D"m_463468737990014054=
8styled-by-prettify">};</span><span style=3D"color:#000" class=3D"m_4634687=
379900140548styled-by-prettify"><br></span><span style=3D"color:#008" class=
=3D"m_4634687379900140548styled-by-prettify">template</span><span style=3D"=
color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;</span><s=
pan style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify">=
class</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled=
-by-prettify"> B1</span><span style=3D"color:#660" class=3D"m_4634687379900=
140548styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_=
4634687379900140548styled-by-prettify"> </span><span style=3D"color:#008" c=
lass=3D"m_4634687379900140548styled-by-prettify">struct</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> conjunct=
ion</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-b=
y-prettify">&lt;</span><span style=3D"color:#000" class=3D"m_46346873799001=
40548styled-by-prettify">B1</span><span style=3D"color:#660" class=3D"m_463=
4687379900140548styled-by-prettify">&gt;</span><span style=3D"color:#000" c=
lass=3D"m_4634687379900140548styled-by-prettify"> </span><span style=3D"col=
or:#660" class=3D"m_4634687379900140548styled-by-prettify">:</span><span st=
yle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> B1 </=
span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pre=
ttify">{</span><span style=3D"color:#000" class=3D"m_4634687379900140548sty=
led-by-prettify"> </span><span style=3D"color:#660" class=3D"m_463468737990=
0140548styled-by-prettify">};</span><span style=3D"color:#000" class=3D"m_4=
634687379900140548styled-by-prettify"><br></span><span style=3D"color:#008"=
 class=3D"m_4634687379900140548styled-by-prettify">template</span><span sty=
le=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;</s=
pan><span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-pret=
tify">class</span><span style=3D"color:#000" class=3D"m_4634687379900140548=
styled-by-prettify"> B1</span><span style=3D"color:#660" class=3D"m_4634687=
379900140548styled-by-prettify">,</span><span style=3D"color:#000" class=3D=
"m_4634687379900140548styled-by-prettify"> </span><span style=3D"color:#008=
" class=3D"m_4634687379900140548styled-by-prettify">class</span><span style=
=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...</span=
><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettif=
y"> </span><span style=3D"color:#606" class=3D"m_4634687379900140548styled-=
by-prettify">Bn</span><span style=3D"color:#660" class=3D"m_463468737990014=
0548styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_46=
34687379900140548styled-by-prettify"><br></span><span style=3D"color:#008" =
class=3D"m_4634687379900140548styled-by-prettify">struct</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> conjunct=
ion</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-b=
y-prettify">&lt;</span><span style=3D"color:#000" class=3D"m_46346873799001=
40548styled-by-prettify">B1</span><span style=3D"color:#660" class=3D"m_463=
4687379900140548styled-by-prettify">,</span><span style=3D"color:#000" clas=
s=3D"m_4634687379900140548styled-by-prettify"> </span><span style=3D"color:=
#606" class=3D"m_4634687379900140548styled-by-prettify">Bn</span><span styl=
e=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...&gt;<=
/span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pr=
ettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660" class=3D"m_463=
4687379900140548styled-by-prettify">:</span><span style=3D"color:#000" clas=
s=3D"m_4634687379900140548styled-by-prettify"> std</span><span style=3D"col=
or:#660" class=3D"m_4634687379900140548styled-by-prettify">::</span><span s=
tyle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify">condi=
tional_t</span><span style=3D"color:#660" class=3D"m_4634687379900140548sty=
led-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_463468737=
9900140548styled-by-prettify">bool</span><span style=3D"color:#660" class=
=3D"m_4634687379900140548styled-by-prettify">(</span><span style=3D"color:#=
000" class=3D"m_4634687379900140548styled-by-prettify">B1</span><span style=
=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">::</span>=
<span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify=
">value</span><span style=3D"color:#660" class=3D"m_4634687379900140548styl=
ed-by-prettify">),</span><span style=3D"color:#000" class=3D"m_463468737990=
0140548styled-by-prettify"> conjunction</span><span style=3D"color:#660" cl=
ass=3D"m_4634687379900140548styled-by-prettify">&lt;</span><span style=3D"c=
olor:#606" class=3D"m_4634687379900140548styled-by-prettify">Bn</span><span=
 style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...=
&gt;,</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled=
-by-prettify"> B1</span><span style=3D"color:#660" class=3D"m_4634687379900=
140548styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_=
4634687379900140548styled-by-prettify"> </span><span style=3D"color:#660" c=
lass=3D"m_4634687379900140548styled-by-prettify">{};</span><span style=3D"c=
olor:#000" class=3D"m_4634687379900140548styled-by-prettify"><br>=C2=A0 =C2=
=A0 <br></span><span style=3D"color:#008" class=3D"m_4634687379900140548sty=
led-by-prettify">template</span><span style=3D"color:#660" class=3D"m_46346=
87379900140548styled-by-prettify">&lt;</span><span style=3D"color:#008" cla=
ss=3D"m_4634687379900140548styled-by-prettify">class</span><span style=3D"c=
olor:#660" class=3D"m_4634687379900140548styled-by-prettify">...&gt;</span>=
<span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify=
"> </span><span style=3D"color:#008" class=3D"m_4634687379900140548styled-b=
y-prettify">struct</span><span style=3D"color:#000" class=3D"m_463468737990=
0140548styled-by-prettify"> disjunction </span><span style=3D"color:#660" c=
lass=3D"m_4634687379900140548styled-by-prettify">:</span><span style=3D"col=
or:#000" class=3D"m_4634687379900140548styled-by-prettify"> std</span><span=
 style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">::<=
/span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pr=
ettify">false_type </span><span style=3D"color:#660" class=3D"m_46346873799=
00140548styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_4=
634687379900140548styled-by-prettify"> </span><span style=3D"color:#660" cl=
ass=3D"m_4634687379900140548styled-by-prettify">};</span><span style=3D"col=
or:#000" class=3D"m_4634687379900140548styled-by-prettify"><br></span><span=
 style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify">tem=
plate</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled=
-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_463468737990=
0140548styled-by-prettify">class</span><span style=3D"color:#000" class=3D"=
m_4634687379900140548styled-by-prettify"> B1</span><span style=3D"color:#66=
0" class=3D"m_4634687379900140548styled-by-prettify">&gt;</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </span><=
span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify"=
>struct</span><span style=3D"color:#000" class=3D"m_4634687379900140548styl=
ed-by-prettify"> disjunction</span><span style=3D"color:#660" class=3D"m_46=
34687379900140548styled-by-prettify">&lt;</span><span style=3D"color:#000" =
class=3D"m_4634687379900140548styled-by-prettify">B1</span><span style=3D"c=
olor:#660" class=3D"m_4634687379900140548styled-by-prettify">&gt;</span><sp=
an style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> =
</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-p=
rettify">:</span><span style=3D"color:#000" class=3D"m_4634687379900140548s=
tyled-by-prettify"> B1 </span><span style=3D"color:#660" class=3D"m_4634687=
379900140548styled-by-prettify">{</span><span style=3D"color:#000" class=3D=
"m_4634687379900140548styled-by-prettify"> </span><span style=3D"color:#660=
" class=3D"m_4634687379900140548styled-by-prettify">};</span><span style=3D=
"color:#000" class=3D"m_4634687379900140548styled-by-prettify"><br></span><=
span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify"=
>template</span><span style=3D"color:#660" class=3D"m_4634687379900140548st=
yled-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_46346873=
79900140548styled-by-prettify">class</span><span style=3D"color:#000" class=
=3D"m_4634687379900140548styled-by-prettify"> B1</span><span style=3D"color=
:#660" class=3D"m_4634687379900140548styled-by-prettify">,</span><span styl=
e=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </span>=
<span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify=
">class</span><span style=3D"color:#660" class=3D"m_4634687379900140548styl=
ed-by-prettify">...</span><span style=3D"color:#000" class=3D"m_46346873799=
00140548styled-by-prettify"> </span><span style=3D"color:#606" class=3D"m_4=
634687379900140548styled-by-prettify">Bn</span><span style=3D"color:#660" c=
lass=3D"m_4634687379900140548styled-by-prettify">&gt;</span><span style=3D"=
color:#000" class=3D"m_4634687379900140548styled-by-prettify"><br></span><s=
pan style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify">=
struct</span><span style=3D"color:#000" class=3D"m_4634687379900140548style=
d-by-prettify"> disjunction</span><span style=3D"color:#660" class=3D"m_463=
4687379900140548styled-by-prettify">&lt;</span><span style=3D"color:#000" c=
lass=3D"m_4634687379900140548styled-by-prettify">B1</span><span style=3D"co=
lor:#660" class=3D"m_4634687379900140548styled-by-prettify">,</span><span s=
tyle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </sp=
an><span style=3D"color:#606" class=3D"m_4634687379900140548styled-by-prett=
ify">Bn</span><span style=3D"color:#660" class=3D"m_4634687379900140548styl=
ed-by-prettify">...&gt;</span><span style=3D"color:#000" class=3D"m_4634687=
379900140548styled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#660" class=3D"m_4634687379900140548styled-by-prettify">:</span><span s=
tyle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> std<=
/span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pr=
ettify">::</span><span style=3D"color:#000" class=3D"m_4634687379900140548s=
tyled-by-prettify">conditional_t</span><span style=3D"color:#660" class=3D"=
m_4634687379900140548styled-by-prettify">&lt;</span><span style=3D"color:#0=
08" class=3D"m_4634687379900140548styled-by-prettify">bool</span><span styl=
e=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">(</span>=
<span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify=
">B1</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-=
by-prettify">::</span><span style=3D"color:#000" class=3D"m_463468737990014=
0548styled-by-prettify">value</span><span style=3D"color:#660" class=3D"m_4=
634687379900140548styled-by-prettify">),</span><span style=3D"color:#000" c=
lass=3D"m_4634687379900140548styled-by-prettify"> B1</span><span style=3D"c=
olor:#660" class=3D"m_4634687379900140548styled-by-prettify">,</span><span =
style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> dis=
junction</span><span style=3D"color:#660" class=3D"m_4634687379900140548sty=
led-by-prettify">&lt;</span><span style=3D"color:#606" class=3D"m_463468737=
9900140548styled-by-prettify">Bn</span><span style=3D"color:#660" class=3D"=
m_4634687379900140548styled-by-prettify">...&gt;&gt;</span><span style=3D"c=
olor:#000" class=3D"m_4634687379900140548styled-by-prettify"> =C2=A0</span>=
<span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify=
">{</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-b=
y-prettify"> </span><span style=3D"color:#660" class=3D"m_46346873799001405=
48styled-by-prettify">};</span><span style=3D"color:#000" class=3D"m_463468=
7379900140548styled-by-prettify"><br><br></span></div></code></div><div><br=
>=C2=A0 =C2=A0=C2=A0</div><div>There are strong grounds to keep these imple=
mentations, e.g. short-circuiting, getting information on what type, recurs=
ion stopped etc. Although, because of these restrictions compilation time s=
uffers in some cases.</div><div><br></div><div><b><font size=3D"4">Why new,=
=C2=A0<u>very similar</u> traits?</font></b></div><div><b>Abstract</b></div=
><div>During my pull request to folly (<a href=3D"https://github.com/facebo=
ok/folly/pull/643" target=3D"_blank">https://github.com/facebook/folly/pull=
/643</a>) Jay Feldblum posted there a small benchmark script: <a href=3D"ht=
tps://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b" target=3D=
"_blank">https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b=
</a>=C2=A0(big credits for poking my brain with the idea). I was surprised =
that, let&#39;s say, the naive implementation compiles faster that the stan=
dard one.=C2=A0</div><div><br></div><div>I decided to benchmark this idea d=
eeper:</div><div>-problem was to find in a types sequence if there is a typ=
e which T::value is equal to 0</div><div>-for every benchmark sequence has =
1024 types inside</div><div>-tested sequences with two kinds of types: ligh=
t and heavy to instantiate</div><div>-tested best and worse cases</div><div=
>-tested two new implementations: fold expression and bool-pack</div><div>-=
core benchmark was to measure the compilation time with given compiler (cla=
ng++-4.0/g++-6), case (best/worse), type (light/heavy), implementation (pro=
posed/standard). Every compilation case was ran 500 times and average resul=
t was calculated.</div><div><br></div><div>Whole benchmarks code you can fi=
nd in the gh repo:=C2=A0<a href=3D"https://github.com/stryku/boolpack_vs_re=
cursion" target=3D"_blank">https://github.com/stryku/boolpack_vs_recursion<=
/a></div><div><br></div><div>And here are the results (sorry for not postin=
g it here, but table was too big and it was formatted in unreadable way):</=
div><div><a href=3D"https://raw.githubusercontent.com/stryku/boolpack_vs_re=
cursion/master/output" target=3D"_blank">https://raw.githubusercontent.com/=
stryku/boolpack_vs_recursion/master/output</a></div><div><br></div><div>As =
you can see, standard implementation is way better when we deal with the be=
st case. It can compile 80x(!) faster than the proposed ones. Problem start=
s when the worse cases occurs.=C2=A0</div><div>Standard library creators wo=
uld be able to implement `greedy_conjunction` and `greedy_disjunction` in a=
 way that they compiles up to around 6x faster than the standard one. Users=
 would be able choose implementation which will suit best, based on what ca=
ses they are mostly expecting.</div><div><br></div><div><font size=3D"4"><b=
>Specification</b></font></div><div>Since it&#39;s a pre-proposal I don&#39=
;t want to post fully described specification. I&#39;m thinking about it in=
 this way:</div><div><br></div><div>`std::greedy_conjunction` would be an a=
lias or would derive from a type, which has a constexpr member `value` whic=
h can be converted to bool and is equal to:</div><div>-false if any bool(Tn=
::value0 =3D=3D false</div><div>-true otherwise</div><div><br></div><div><d=
iv>`std::greedy_disjunction` would be an alias or would derive from a type,=
 which has a constexpr member `value` which can be converted to bool and is=
 equal to:</div><div>-false if all bool(Tn::value) =3D=3D false</div><div>-=
true otherwise</div></div><div><br></div><div><font size=3D"4"><b>Example i=
mplementations</b></font></div><div>bool-pack (this one seems to compile fa=
ster than fold expression):</div><div class=3D"m_4634687379900140548prettyp=
rint" style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px;word-wrap:break-word"><code class=
=3D"m_4634687379900140548prettyprint"><div class=3D"m_4634687379900140548su=
bprettyprint"><span style=3D"color:#008" class=3D"m_4634687379900140548styl=
ed-by-prettify">template</span><span style=3D"color:#000" class=3D"m_463468=
7379900140548styled-by-prettify"> </span><span style=3D"color:#660" class=
=3D"m_4634687379900140548styled-by-prettify">&lt;</span><span style=3D"colo=
r:#008" class=3D"m_4634687379900140548styled-by-prettify">bool</span><span =
style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...<=
/span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pr=
ettify"> </span><span style=3D"color:#606" class=3D"m_4634687379900140548st=
yled-by-prettify">Bn</span><span style=3D"color:#660" class=3D"m_4634687379=
900140548styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D=
"m_4634687379900140548styled-by-prettify"><br></span><span style=3D"color:#=
008" class=3D"m_4634687379900140548styled-by-prettify">struct</span><span s=
tyle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> __bo=
ols </span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-=
by-prettify">{};</span><span style=3D"color:#000" class=3D"m_46346873799001=
40548styled-by-prettify"><br><br></span><span style=3D"color:#008" class=3D=
"m_4634687379900140548styled-by-prettify">template</span><span style=3D"col=
or:#000" class=3D"m_4634687379900140548styled-by-prettify"> </span><span st=
yle=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;</=
span><span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-pre=
ttify">typename</span><span style=3D"color:#660" class=3D"m_463468737990014=
0548styled-by-prettify">...</span><span style=3D"color:#000" class=3D"m_463=
4687379900140548styled-by-prettify"> </span><span style=3D"color:#606" clas=
s=3D"m_4634687379900140548styled-by-prettify">Tn</span><span style=3D"color=
:#660" class=3D"m_4634687379900140548styled-by-prettify">&gt;</span><span s=
tyle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> <br>=
</span><span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-p=
rettify">struct</span><span style=3D"color:#000" class=3D"m_463468737990014=
0548styled-by-prettify"> greedy_disjunction</span><span style=3D"color:#660=
" class=3D"m_4634687379900140548styled-by-prettify">:</span><span style=3D"=
color:#000" class=3D"m_4634687379900140548styled-by-prettify"> std</span><s=
pan style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">=
::</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by=
-prettify">negation</span><span style=3D"color:#660" class=3D"m_46346873799=
00140548styled-by-prettify">&lt;</span><span style=3D"color:#000" class=3D"=
m_4634687379900140548styled-by-prettify">std</span><span style=3D"color:#66=
0" class=3D"m_4634687379900140548styled-by-prettify">::</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify">is_same</=
span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pre=
ttify">&lt;</span><span style=3D"color:#000" class=3D"m_4634687379900140548=
styled-by-prettify">__bools</span><span style=3D"color:#660" class=3D"m_463=
4687379900140548styled-by-prettify">&lt;</span><span style=3D"color:#008" c=
lass=3D"m_4634687379900140548styled-by-prettify">bool</span><span style=3D"=
color:#660" class=3D"m_4634687379900140548styled-by-prettify">(</span><span=
 style=3D"color:#606" class=3D"m_4634687379900140548styled-by-prettify">Tn<=
/span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pr=
ettify">::</span><span style=3D"color:#000" class=3D"m_4634687379900140548s=
tyled-by-prettify">value</span><span style=3D"color:#660" class=3D"m_463468=
7379900140548styled-by-prettify">)...&gt;,</span><span style=3D"color:#000"=
 class=3D"m_4634687379900140548styled-by-prettify"> __bools</span><span sty=
le=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;(</=
span><span style=3D"color:#606" class=3D"m_4634687379900140548styled-by-pre=
ttify">Tn</span><span style=3D"color:#660" class=3D"m_4634687379900140548st=
yled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_4634687379=
900140548styled-by-prettify">value </span><span style=3D"color:#660" class=
=3D"m_4634687379900140548styled-by-prettify">&amp;&amp;</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </span><=
span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify"=
>false</span><span style=3D"color:#660" class=3D"m_4634687379900140548style=
d-by-prettify">)...&gt;&gt;&gt;</span><span style=3D"color:#000" class=3D"m=
_4634687379900140548styled-by-prettify"> </span><span style=3D"color:#660" =
class=3D"m_4634687379900140548styled-by-prettify">{};</span><span style=3D"=
color:#000" class=3D"m_4634687379900140548styled-by-prettify"><br><br></spa=
n><span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-pretti=
fy">template</span><span style=3D"color:#000" class=3D"m_463468737990014054=
8styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_46346873=
79900140548styled-by-prettify">&lt;</span><span style=3D"color:#008" class=
=3D"m_4634687379900140548styled-by-prettify">typename</span><span style=3D"=
color:#660" class=3D"m_4634687379900140548styled-by-prettify">...</span><sp=
an style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> =
</span><span style=3D"color:#606" class=3D"m_4634687379900140548styled-by-p=
rettify">Tn</span><span style=3D"color:#660" class=3D"m_4634687379900140548=
styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_463468=
7379900140548styled-by-prettify"> <br></span><span style=3D"color:#008" cla=
ss=3D"m_4634687379900140548styled-by-prettify">struct</span><span style=3D"=
color:#000" class=3D"m_4634687379900140548styled-by-prettify"> greedy_conju=
nction</span><span style=3D"color:#660" class=3D"m_4634687379900140548style=
d-by-prettify">:</span><span style=3D"color:#000" class=3D"m_46346873799001=
40548styled-by-prettify"> std</span><span style=3D"color:#660" class=3D"m_4=
634687379900140548styled-by-prettify">::</span><span style=3D"color:#000" c=
lass=3D"m_4634687379900140548styled-by-prettify">is_same</span><span style=
=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;</spa=
n><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pretti=
fy">__bools</span><span style=3D"color:#660" class=3D"m_4634687379900140548=
styled-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_463468=
7379900140548styled-by-prettify">bool</span><span style=3D"color:#660" clas=
s=3D"m_4634687379900140548styled-by-prettify">(</span><span style=3D"color:=
#606" class=3D"m_4634687379900140548styled-by-prettify">Tn</span><span styl=
e=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">::</span=
><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettif=
y">value</span><span style=3D"color:#660" class=3D"m_4634687379900140548sty=
led-by-prettify">)...&gt;,</span><span style=3D"color:#000" class=3D"m_4634=
687379900140548styled-by-prettify"> __bools</span><span style=3D"color:#660=
" class=3D"m_4634687379900140548styled-by-prettify">&lt;(</span><span style=
=3D"color:#606" class=3D"m_4634687379900140548styled-by-prettify">Tn</span>=
<span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify=
">::</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-=
by-prettify">value </span><span style=3D"color:#660" class=3D"m_46346873799=
00140548styled-by-prettify">||</span><span style=3D"color:#000" class=3D"m_=
4634687379900140548styled-by-prettify"> </span><span style=3D"color:#008" c=
lass=3D"m_4634687379900140548styled-by-prettify">true</span><span style=3D"=
color:#660" class=3D"m_4634687379900140548styled-by-prettify">)...&gt;&gt;<=
/span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pr=
ettify"> </span><span style=3D"color:#660" class=3D"m_4634687379900140548st=
yled-by-prettify">{};</span><span style=3D"color:#000" class=3D"m_463468737=
9900140548styled-by-prettify"><br></span></div></code></div><div><br><br></=
div><div>fold expression:</div><div class=3D"m_4634687379900140548prettypri=
nt" 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"=
m_4634687379900140548prettyprint"><div class=3D"m_4634687379900140548subpre=
ttyprint"><span style=3D"color:#008" class=3D"m_4634687379900140548styled-b=
y-prettify">template</span><span style=3D"color:#000" class=3D"m_4634687379=
900140548styled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_=
4634687379900140548styled-by-prettify">&lt;</span><span style=3D"color:#008=
" class=3D"m_4634687379900140548styled-by-prettify">typename</span><span st=
yle=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...</s=
pan><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-pret=
tify"> </span><span style=3D"color:#606" class=3D"m_4634687379900140548styl=
ed-by-prettify">Tn</span><span style=3D"color:#660" class=3D"m_463468737990=
0140548styled-by-prettify">&gt;</span><span style=3D"color:#000" class=3D"m=
_4634687379900140548styled-by-prettify"> <br></span><span style=3D"color:#0=
08" class=3D"m_4634687379900140548styled-by-prettify">struct</span><span st=
yle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> greed=
y_disjunction </span><span style=3D"color:#660" class=3D"m_4634687379900140=
548styled-by-prettify">:</span><span style=3D"color:#000" class=3D"m_463468=
7379900140548styled-by-prettify"> std</span><span style=3D"color:#660" clas=
s=3D"m_4634687379900140548styled-by-prettify">::</span><span style=3D"color=
:#000" class=3D"m_4634687379900140548styled-by-prettify">bool_constant</spa=
n><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pretti=
fy">&lt;(</span><span style=3D"color:#008" class=3D"m_4634687379900140548st=
yled-by-prettify">false</span><span style=3D"color:#000" class=3D"m_4634687=
379900140548styled-by-prettify"> </span><span style=3D"color:#660" class=3D=
"m_4634687379900140548styled-by-prettify">||</span><span style=3D"color:#00=
0" class=3D"m_4634687379900140548styled-by-prettify"> </span><span style=3D=
"color:#660" class=3D"m_4634687379900140548styled-by-prettify">...</span><s=
pan style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify">=
 </span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-=
prettify">||</span><span style=3D"color:#000" class=3D"m_463468737990014054=
8styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_46346873=
79900140548styled-by-prettify">bool</span><span style=3D"color:#660" class=
=3D"m_4634687379900140548styled-by-prettify">(</span><span style=3D"color:#=
606" class=3D"m_4634687379900140548styled-by-prettify">Tn</span><span style=
=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">::</span>=
<span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify=
">value</span><span style=3D"color:#660" class=3D"m_4634687379900140548styl=
ed-by-prettify">))&gt;</span><span style=3D"color:#000" class=3D"m_46346873=
79900140548styled-by-prettify"> </span><span style=3D"color:#660" class=3D"=
m_4634687379900140548styled-by-prettify">{};</span><span style=3D"color:#00=
0" class=3D"m_4634687379900140548styled-by-prettify"><br><br></span><span s=
tyle=3D"color:#008" class=3D"m_4634687379900140548styled-by-prettify">templ=
ate</span><span style=3D"color:#000" class=3D"m_4634687379900140548styled-b=
y-prettify"> </span><span style=3D"color:#660" class=3D"m_46346873799001405=
48styled-by-prettify">&lt;</span><span style=3D"color:#008" class=3D"m_4634=
687379900140548styled-by-prettify">typename</span><span style=3D"color:#660=
" class=3D"m_4634687379900140548styled-by-prettify">...</span><span style=
=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </span><=
span style=3D"color:#606" class=3D"m_4634687379900140548styled-by-prettify"=
>Tn</span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-b=
y-prettify">&gt;</span><span style=3D"color:#000" class=3D"m_46346873799001=
40548styled-by-prettify"> <br></span><span style=3D"color:#008" class=3D"m_=
4634687379900140548styled-by-prettify">struct</span><span style=3D"color:#0=
00" class=3D"m_4634687379900140548styled-by-prettify"> greedy_conjunction <=
/span><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pr=
ettify">:</span><span style=3D"color:#000" class=3D"m_4634687379900140548st=
yled-by-prettify"> std</span><span style=3D"color:#660" class=3D"m_46346873=
79900140548styled-by-prettify">::</span><span style=3D"color:#000" class=3D=
"m_4634687379900140548styled-by-prettify">bool_constant</span><span style=
=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">&lt;(</sp=
an><span style=3D"color:#008" class=3D"m_4634687379900140548styled-by-prett=
ify">true</span><span style=3D"color:#000" class=3D"m_4634687379900140548st=
yled-by-prettify"> </span><span style=3D"color:#660" class=3D"m_46346873799=
00140548styled-by-prettify">&amp;&amp;</span><span style=3D"color:#000" cla=
ss=3D"m_4634687379900140548styled-by-prettify"> </span><span style=3D"color=
:#660" class=3D"m_4634687379900140548styled-by-prettify">...</span><span st=
yle=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettify"> </spa=
n><span style=3D"color:#660" class=3D"m_4634687379900140548styled-by-pretti=
fy">&amp;&amp;</span><span style=3D"color:#000" class=3D"m_4634687379900140=
548styled-by-prettify"> </span><span style=3D"color:#008" class=3D"m_463468=
7379900140548styled-by-prettify">bool</span><span style=3D"color:#660" clas=
s=3D"m_4634687379900140548styled-by-prettify">(</span><span style=3D"color:=
#606" class=3D"m_4634687379900140548styled-by-prettify">Tn</span><span styl=
e=3D"color:#660" class=3D"m_4634687379900140548styled-by-prettify">::</span=
><span style=3D"color:#000" class=3D"m_4634687379900140548styled-by-prettif=
y">value</span><span style=3D"color:#660" class=3D"m_4634687379900140548sty=
led-by-prettify">))&gt;</span><span style=3D"color:#000" class=3D"m_4634687=
379900140548styled-by-prettify"> </span><span style=3D"color:#660" class=3D=
"m_4634687379900140548styled-by-prettify">{};</span><span style=3D"color:#0=
00" class=3D"m_4634687379900140548styled-by-prettify"><br></span></div></co=
de></div><div><br><br></div><div><font size=3D"4"><b>Wordings:</b></font></=
div><div><b>There is couple of questions</b></div><div>I asked them to myse=
lf a lot, during this pre-proposal.</div><div>-Is it in the C++ standard sc=
ope to care about how things will be implemented in standard library, even =
if the implementations will be not efficient on compile-time level?</div><d=
iv>-Should the standard be changed because of standard library compilation =
time?</div><div><br></div><div>And here&#39;s my conclusion (and reason why=
 I&#39;m writing this post).</div><div>C++ standard purpose is not to speci=
fy a theoretical language. It&#39;s created to be used by a lot of people i=
n the real world. Giving a choice to user between implementations which dif=
fers in a compile-time efficiency is same thing as to give a choice between=
 containers e.g. `std::vector` and `std::list`. In some cases one implement=
ation is better, in others the other one.</div><div><br></div><div><b>And o=
f course the name</b></div><div>I thought about `strict_*` (like it&#39;s i=
n Facebook/folly lib) instead of `greedy_*`, but I&#39;m sure that if this =
proposal is a thing community will propose better names.</div><div><br></di=
v><div><br></div><div>What do you think?</div><div><br></div><div>Mateusz (=
stryku) Janek</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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-=
4c37-b49e-cb707689a0e2%40isocpp.org</a>.<br>
</blockquote></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/CAPCFJdSoAKm4SO4PQrs93ZGzH-nBexfO0X_3=
OEw4b5RJXqM49g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPCFJdSoAKm4SO4P=
Qrs93ZGzH-nBexfO0X_3OEw4b5RJXqM49g%40mail.gmail.com</a>.<br />

--94eb2c03c1483c429c0556515619--

.


Author: mateusz.janek6@gmail.com
Date: Wed, 9 Aug 2017 14:22:53 -0700 (PDT)
Raw View
------=_Part_231_1307637170.1502313773268
Content-Type: multipart/alternative;
 boundary="----=_Part_232_1616450242.1502313773269"

------=_Part_232_1616450242.1502313773269
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

These traits are as useful as current conjunction and disjunction are -=20
they compute the same result, but additionally give user a choice about=20
compilation time and IMO that's a useful addition.

W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Micha=C5=
=82 Dominiak=20
napisa=C5=82:
>
> You can already write your "greedy" things by just... deriving from=20
> bool_constant directly (exactly like in your last snippet). You couldn't =
do=20
> what the two traits are doing directly, and that's I believe is the only=
=20
> justification of their existence. Your thing doesn't seem to be very usef=
ul.
>
> On Wed, Aug 9, 2017 at 2:31 PM <mateusz...@gmail.com <javascript:>> wrote=
:
>
>> *Introduction*
>>
>> C++17 introduced besides the others two new structures in `<type_traits>=
`=20
>> header: `std::conjuction` and `std::disjunction`. They are very useful i=
n=20
>> metaprogramming, but standard has in some way forced their implementatio=
n.=20
>> In p0013r1=20
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html> w=
e=20
>> can read:
>> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> is=
=20
>> the first type Bi in the list true_type, B1, ..., BN for which Bi::value=
=20
>> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristic is=
 BN. [
>> *Note:* This means a specialization of conjunction does not necessarily=
=20
>> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 *=
end note*
>> ]
>>
>> Similar in the disjunction:=20
>> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> is=
=20
>> the first type Bi in the list false_type, B1, ..., BN for which Bi::valu=
e=20
>> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristic is=
 BN. [
>> *Note:* This means a specialization of disjunction does not necessarily=
=20
>> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 *=
end note*
>> ]
>>
>> I'd like to propose a two new structures in `<type_traits>`:=20
>> `std::greedy_conjunction` and `std::greedy_disjunction`. Their results=
=20
>> would very similar to the ones from `std::conjunciton` and=20
>> `std::disjunction`, but their specification would give more flexibility =
to=20
>> the standard library creators.
>>
>>
>> *Motivation and Scope*
>>
>> With `std::conjuction` and `std::disjunction` restrictions in the=20
>> standard, library creators are forced to make them in such (or similar) =
way:
>> template<class...> struct conjunction : std::true_type { };
>> template<class B1> struct conjunction<B1> : B1 { };
>> template<class B1, class... Bn>
>> struct conjunction<B1, Bn...>=20
>>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
>>    =20
>> template<class...> struct disjunction : std::false_type { };
>> template<class B1> struct disjunction<B1> : B1 { };
>> template<class B1, class... Bn>
>> struct disjunction<B1, Bn...>=20
>>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  { };
>>
>>
>>    =20
>> There are strong grounds to keep these implementations, e.g.=20
>> short-circuiting, getting information on what type, recursion stopped et=
c.=20
>> Although, because of these restrictions compilation time suffers in some=
=20
>> cases.
>>
>> *Why new, very similar traits?*
>> *Abstract*
>> During my pull request to folly (
>> https://github.com/facebook/folly/pull/643) Jay Feldblum posted there a=
=20
>> small benchmark script:=20
>> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (big=
=20
>> credits for poking my brain with the idea). I was surprised that, let's=
=20
>> say, the naive implementation compiles faster that the standard one.=20
>>
>> I decided to benchmark this idea deeper:
>> -problem was to find in a types sequence if there is a type which=20
>> T::value is equal to 0
>> -for every benchmark sequence has 1024 types inside
>> -tested sequences with two kinds of types: light and heavy to instantiat=
e
>> -tested best and worse cases
>> -tested two new implementations: fold expression and bool-pack
>> -core benchmark was to measure the compilation time with given compiler=
=20
>> (clang++-4.0/g++-6), case (best/worse), type (light/heavy), implementati=
on=20
>> (proposed/standard). Every compilation case was ran 500 times and averag=
e=20
>> result was calculated.
>>
>> Whole benchmarks code you can find in the gh repo:=20
>> https://github.com/stryku/boolpack_vs_recursion
>>
>> And here are the results (sorry for not posting it here, but table was=
=20
>> too big and it was formatted in unreadable way):
>>
>> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/ou=
tput
>>
>> As you can see, standard implementation is way better when we deal with=
=20
>> the best case. It can compile 80x(!) faster than the proposed ones. Prob=
lem=20
>> starts when the worse cases occurs.=20
>> Standard library creators would be able to implement `greedy_conjunction=
`=20
>> and `greedy_disjunction` in a way that they compiles up to around 6x fas=
ter=20
>> than the standard one. Users would be able choose implementation which w=
ill=20
>> suit best, based on what cases they are mostly expecting.
>>
>> *Specification*
>> Since it's a pre-proposal I don't want to post fully described=20
>> specification. I'm thinking about it in this way:
>>
>> `std::greedy_conjunction` would be an alias or would derive from a type,=
=20
>> which has a constexpr member `value` which can be converted to bool and =
is=20
>> equal to:
>> -false if any bool(Tn::value0 =3D=3D false
>> -true otherwise
>>
>> `std::greedy_disjunction` would be an alias or would derive from a type,=
=20
>> which has a constexpr member `value` which can be converted to bool and =
is=20
>> equal to:
>> -false if all bool(Tn::value) =3D=3D false
>> -true otherwise
>>
>> *Example implementations*
>> bool-pack (this one seems to compile faster than fold expression):
>> template <bool... Bn>
>> struct __bools {};
>>
>> template <typename... Tn>=20
>> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn::
>> value)...>, __bools<(Tn::value && false)...>>> {};
>>
>> template <typename... Tn>=20
>> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,=20
>> __bools<(Tn::value || true)...>> {};
>>
>>
>> fold expression:
>> template <typename... Tn>=20
>> struct greedy_disjunction : std::bool_constant<(false || ... || bool(Tn:=
:
>> value))> {};
>>
>> template <typename... Tn>=20
>> struct greedy_conjunction : std::bool_constant<(true && ... && bool(Tn::
>> value))> {};
>>
>>
>> *Wordings:*
>> *There is couple of questions*
>> I asked them to myself a lot, during this pre-proposal.
>> -Is it in the C++ standard scope to care about how things will be=20
>> implemented in standard library, even if the implementations will be not=
=20
>> efficient on compile-time level?
>> -Should the standard be changed because of standard library compilation=
=20
>> time?
>>
>> And here's my conclusion (and reason why I'm writing this post).
>> C++ standard purpose is not to specify a theoretical language. It's=20
>> created to be used by a lot of people in the real world. Giving a choice=
 to=20
>> user between implementations which differs in a compile-time efficiency =
is=20
>> same thing as to give a choice between containers e.g. `std::vector` and=
=20
>> `std::list`. In some cases one implementation is better, in others the=
=20
>> other one.
>>
>> *And of course the name*
>> I thought about `strict_*` (like it's in Facebook/folly lib) instead of=
=20
>> `greedy_*`, but I'm sure that if this proposal is a thing community will=
=20
>> propose better names.
>>
>>
>> What do you think?
>>
>> Mateusz (stryku) Janek
>>
>> --=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit=20
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca=
2d-4c37-b49e-cb707689a0e2%40isocpp.org=20
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-c=
a2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>

--=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/4b2924fd-0a54-45eb-a2c3-55ddbb5edd73%40isocpp.or=
g.

------=_Part_232_1616450242.1502313773269
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">These traits are as useful as current conjunction and disj=
unction are - they compute the same result, but additionally give user a ch=
oice about compilation time and IMO that&#39;s a useful addition.<br><br>W =
dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Micha=C5=82=
 Dominiak napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">You can already write your &quot;greedy&quot; things by just... d=
eriving from bool_constant directly (exactly like in your last snippet). Yo=
u couldn&#39;t do what the two traits are doing directly, and that&#39;s I =
believe is the only justification of their existence. Your thing doesn&#39;=
t seem to be very useful.</div><br><div class=3D"gmail_quote"><div dir=3D"l=
tr">On Wed, Aug 9, 2017 at 2:31 PM &lt;<a href=3D"javascript:" target=3D"_b=
lank" gdf-obfuscated-mailto=3D"GC9zGPQjBwAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D=
&#39;javascript:&#39;;return true;">mateusz...@gmail.com</a>&gt; wrote:<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><b><font size=3D=
"4">Introduction</font></b></div><div><br></div><div>C++17 introduced besid=
es the others two new structures in `&lt;type_traits&gt;` header: `std::con=
juction` and `std::disjunction`. They are very useful in metaprogramming, b=
ut standard has in some way forced their implementation.=C2=A0</div><div>In=
 <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1=
..html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;h=
ttp://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2=
Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNHrhD3oGJRVXphYJvzGExp6I3jexQ&#39;;return true;" onclick=3D"this.hr=
ef=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjt=
c1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x=
3d1\x26usg\x3dAFQjCNHrhD3oGJRVXphYJvzGExp6I3jexQ&#39;;return true;">p0013r1=
</a>=C2=A0we can read:</div><div><span style=3D"color:rgb(0,160,0);font-fam=
ily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">The Ba=
seCharacteristic of a specialization=C2=A0</span><code style=3D"color:rgb(0=
,160,0);text-align:justify">conjunction&lt;B1, ..., BN&gt;</code><span styl=
e=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:m=
edium;text-align:justify">=C2=A0is the first type=C2=A0</span><code style=
=3D"color:rgb(0,160,0);text-align:justify">Bi</code><span style=3D"color:rg=
b(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-al=
ign:justify">=C2=A0in the list=C2=A0</span><code style=3D"color:rgb(0,160,0=
);text-align:justify">true_type, B1, ..., BN</code><span style=3D"color:rgb=
(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-ali=
gn:justify">=C2=A0for which=C2=A0</span><code style=3D"color:rgb(0,160,0);t=
ext-align:justify">Bi::value =3D=3D false</code><span style=3D"color:rgb(0,=
160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:=
justify">, or if every=C2=A0</span><code style=3D"color:rgb(0,160,0);text-a=
lign:justify">Bi::value !=3D false</code><span style=3D"color:rgb(0,160,0);=
font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify=
">=C2=A0the BaseCharacteristic is=C2=A0</span><code style=3D"color:rgb(0,16=
0,0);text-align:justify">BN</code><span style=3D"color:rgb(0,160,0);font-fa=
mily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">. [</=
span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot=
;;font-size:medium;text-align:justify">Note:</em><span style=3D"color:rgb(0=
,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align=
:justify">=C2=A0This means a specialization of=C2=A0</span><code style=3D"c=
olor:rgb(0,160,0);text-align:justify">conjunction</code><span style=3D"colo=
r:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;tex=
t-align:justify">=C2=A0does not necessarily have a BaseCharacteristic of ei=
ther=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">true=
_type</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New R=
oman&quot;;font-size:medium;text-align:justify">=C2=A0or=C2=A0</span><code =
style=3D"color:rgb(0,160,0);text-align:justify">false_type</code><span styl=
e=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:m=
edium;text-align:justify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"color:r=
gb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-a=
lign:justify">end note</em><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">]</span><br>=
</div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify"><br></span></div><div>Simila=
r in the disjunction:=C2=A0</div><div><span style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">T=
he BaseCharacteristic of a specialization=C2=A0</span><code style=3D"color:=
rgb(0,160,0);text-align:justify">disjunction&lt;B1, ..., BN&gt;</code><span=
 style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-s=
ize:medium;text-align:justify">=C2=A0is the first type=C2=A0</span><code st=
yle=3D"color:rgb(0,160,0);text-align:justify">Bi</code><span style=3D"color=
:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text=
-align:justify">=C2=A0in the list=C2=A0</span><code style=3D"color:rgb(0,16=
0,0);text-align:justify">false_type, B1, ..., BN</code><span style=3D"color=
:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text=
-align:justify">=C2=A0for which=C2=A0</span><code style=3D"color:rgb(0,160,=
0);text-align:justify">Bi::value !=3D false</code><span style=3D"color:rgb(=
0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-alig=
n:justify">, or if every=C2=A0</span><code style=3D"color:rgb(0,160,0);text=
-align:justify">Bi::value =3D=3D false</code><span style=3D"color:rgb(0,160=
,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:jus=
tify">=C2=A0the BaseCharacteristic is=C2=A0</span><code style=3D"color:rgb(=
0,160,0);text-align:justify">BN</code><span style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">.=
 [</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&=
quot;;font-size:medium;text-align:justify">Note:</em><span style=3D"color:r=
gb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-a=
lign:justify">=C2=A0This means a specialization of=C2=A0</span><code style=
=3D"color:rgb(0,160,0);text-align:justify">disjunction</code><span style=3D=
"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:mediu=
m;text-align:justify">=C2=A0does not necessarily have a BaseCharacteristic =
of either=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify"=
>true_type</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times =
New Roman&quot;;font-size:medium;text-align:justify">=C2=A0or=C2=A0</span><=
code style=3D"color:rgb(0,160,0);text-align:justify">false_type</code><span=
 style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-s=
ize:medium;text-align:justify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"co=
lor:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;t=
ext-align:justify">end note</em><span style=3D"color:rgb(0,160,0);font-fami=
ly:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">]</span=
><br></div><div><br></div><div>I&#39;d like to propose a two new structures=
 in `&lt;type_traits&gt;`: `std::greedy_conjunction` and `std::greedy_disju=
nction`. Their results would very similar to the ones from `std::conjuncito=
n` and `std::disjunction`, but their specification would give more flexibil=
ity to the standard library creators.</div><div><br></div><div><br></div><d=
iv><b><font size=3D"4">Motivation and Scope</font></b></div><div><br></div>=
<div>With `std::conjuction` and `std::disjunction` restrictions in the stan=
dard, library creators are forced to make them in such (or similar) way:</d=
iv><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:#008">template</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#008">class</span><span style=3D"color:#660">...&=
gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">str=
uct</span><span style=3D"color:#000"> conjunction </span><span style=3D"col=
or:#660">:</span><span style=3D"color:#000"> std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">true_type </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></span><span style=3D"color:=
#008">template</span><span style=3D"color:#660">&lt;</span><span style=3D"c=
olor:#008">class</span><span style=3D"color:#000"> B1</span><span style=3D"=
color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#008">struct</span><span style=3D"color:#000"> conjunction</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#000">B1</span><span s=
tyle=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">:</span><span style=3D"color:#000"> B1 </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">};</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> B1</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">class</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Bn</span><span style=3D"col=
or:#660">&gt;</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#008">struct</span><span style=3D"color:#000"> conjunction</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#000">B1</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;</span><span sty=
le=3D"color:#000"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">:</s=
pan><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">conditional_t</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">bool</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">B1</span><span style=3D"color:#660">:=
:</span><span style=3D"color:#000">va<wbr>lue</span><span style=3D"color:#6=
60">),</span><span style=3D"color:#000"> conjunction</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#606">Bn</span><span style=3D"co=
lor:#660">...&gt;,</span><span style=3D"color:#000"> B1</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <br>=
</span><span style=3D"color:#008">template</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#66=
0">...&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">struct</span><span style=3D"color:#000"> disjunction </span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">false_type </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">};</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#008">class</span><span style=3D"color:#000"> B1</span><span=
 style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#008">struct</span><span style=3D"color:#000"> disjunction</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">B1</sp=
an><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">:</span><span style=3D"color:#000"> B1 </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></span><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">class</span><span style=3D"color:#000"> B1</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">class</span><span style=3D"color:#660">...</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#606">Bn</span><span sty=
le=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#008">struct</span><span style=3D"color:#000"> disjunction</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">B1</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;</span><=
span style=3D"color:#000"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#6=
60">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">conditional_t</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#008">bool</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">B1</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">va<wbr>lue</span><span style=3D"=
color:#660">),</span><span style=3D"color:#000"> B1</span><span style=3D"co=
lor:#660">,</span><span style=3D"color:#000"> disjunction</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#606">Bn</span><span style=
=3D"color:#660">...&gt;&gt;</span><span style=3D"color:#000"> =C2=A0</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><br></span></=
div></code></div><div><br>=C2=A0 =C2=A0=C2=A0</div><div>There are strong gr=
ounds to keep these implementations, e.g. short-circuiting, getting informa=
tion on what type, recursion stopped etc. Although, because of these restri=
ctions compilation time suffers in some cases.</div><div><br></div><div><b>=
<font size=3D"4">Why new,=C2=A0<u>very similar</u> traits?</font></b></div>=
<div><b>Abstract</b></div><div>During my pull request to folly (<a href=3D"=
https://github.com/facebook/folly/pull/643" target=3D"_blank" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3=
A%2F%2Fgithub.com%2Ffacebook%2Ffolly%2Fpull%2F643\x26sa\x3dD\x26sntz\x3d1\x=
26usg\x3dAFQjCNFmOzRzYUaerIKsE3rogxWBbtocbw&#39;;return true;" onclick=3D"t=
his.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2F=
facebook%2Ffolly%2Fpull%2F643\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzR=
zYUaerIKsE3rogxWBbtocbw&#39;;return true;">https://github.com/facebook/<wbr=
>folly/pull/643</a>) Jay Feldblum posted there a small benchmark script: <a=
 href=3D"https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b=
" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https:=
//www.google.com/url?q\x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5=
374aaaa11b03f08919d25b1555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-=
eDaheXnAHTmJ5rTlEJgRA&#39;;return true;" onclick=3D"this.href=3D&#39;https:=
//www.google.com/url?q\x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5=
374aaaa11b03f08919d25b1555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-=
eDaheXnAHTmJ5rTlEJgRA&#39;;return true;">https://gist.github.com/<wbr>yfeld=
blum/<wbr>ffae5374aaaa11b03f08919d25b155<wbr>5b</a>=C2=A0(big credits for p=
oking my brain with the idea). I was surprised that, let&#39;s say, the nai=
ve implementation compiles faster that the standard one.=C2=A0</div><div><b=
r></div><div>I decided to benchmark this idea deeper:</div><div>-problem wa=
s to find in a types sequence if there is a type which T::value is equal to=
 0</div><div>-for every benchmark sequence has 1024 types inside</div><div>=
-tested sequences with two kinds of types: light and heavy to instantiate</=
div><div>-tested best and worse cases</div><div>-tested two new implementat=
ions: fold expression and bool-pack</div><div>-core benchmark was to measur=
e the compilation time with given compiler (clang++-4.0/g++-6), case (best/=
worse), type (light/heavy), implementation (proposed/standard). Every compi=
lation case was ran 500 times and average result was calculated.</div><div>=
<br></div><div>Whole benchmarks code you can find in the gh repo:=C2=A0<a h=
ref=3D"https://github.com/stryku/boolpack_vs_recursion" target=3D"_blank" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?=
q\x3dhttps%3A%2F%2Fgithub.com%2Fstryku%2Fboolpack_vs_recursion\x26sa\x3dD\x=
26sntz\x3d1\x26usg\x3dAFQjCNHICyJnr6jjlrCVLCKQErJdqh0rLg&#39;;return true;"=
 onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2F=
github.com%2Fstryku%2Fboolpack_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNHICyJnr6jjlrCVLCKQErJdqh0rLg&#39;;return true;">https://github.com=
/<wbr>stryku/boolpack_vs_recursion</a></div><div><br></div><div>And here ar=
e the results (sorry for not posting it here, but table was too big and it =
was formatted in unreadable way):</div><div><a href=3D"https://raw.githubus=
ercontent.com/stryku/boolpack_vs_recursion/master/output" target=3D"_blank"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/ur=
l?q\x3dhttps%3A%2F%2Fraw.githubusercontent.com%2Fstryku%2Fboolpack_vs_recur=
sion%2Fmaster%2Foutput\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQ=
g2amM08KY4FDz5dQ&#39;;return true;" onclick=3D"this.href=3D&#39;https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fraw.githubusercontent.com%2Fstryku%2Fboo=
lpack_vs_recursion%2Fmaster%2Foutput\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQj=
CNFy33FwRHZtVQg2amM08KY4FDz5dQ&#39;;return true;">https://raw.githubusercon=
tent.<wbr>com/stryku/boolpack_vs_<wbr>recursion/master/output</a></div><div=
><br></div><div>As you can see, standard implementation is way better when =
we deal with the best case. It can compile 80x(!) faster than the proposed =
ones. Problem starts when the worse cases occurs.=C2=A0</div><div>Standard =
library creators would be able to implement `greedy_conjunction` and `greed=
y_disjunction` in a way that they compiles up to around 6x faster than the =
standard one. Users would be able choose implementation which will suit bes=
t, based on what cases they are mostly expecting.</div><div><br></div><div>=
<font size=3D"4"><b>Specification</b></font></div><div>Since it&#39;s a pre=
-proposal I don&#39;t want to post fully described specification. I&#39;m t=
hinking about it in this way:</div><div><br></div><div>`std::greedy_conjunc=
tion` would be an alias or would derive from a type, which has a constexpr =
member `value` which can be converted to bool and is equal to:</div><div>-f=
alse if any bool(Tn::value0 =3D=3D false</div><div>-true otherwise</div><di=
v><br></div><div><div>`std::greedy_disjunction` would be an alias or would =
derive from a type, which has a constexpr member `value` which can be conve=
rted to bool and is equal to:</div><div>-false if all bool(Tn::value) =3D=
=3D false</div><div>-true otherwise</div></div><div><br></div><div><font si=
ze=3D"4"><b>Example implementations</b></font></div><div>bool-pack (this on=
e seems to compile faster than fold expression):</div><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">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">bool</span><span style=3D"color:=
#660">...</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Bn</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000=
"><br></span><span style=3D"color:#008">struct</span><span style=3D"color:#=
000"> __bools </span><span style=3D"color:#660">{};</span><span style=3D"co=
lor:#000"><br><br></span><span style=3D"color:#008">template</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#008">typename</span><span style=3D"color:#660">...</span><span =
style=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><span styl=
e=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><span st=
yle=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_disjunct=
ion</span><span style=3D"color:#660">:</span><span style=3D"color:#000"> st=
d</span><span style=3D"color:#660">::</span><span style=3D"color:#000">nega=
tion</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">i=
s_same</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#00=
0">__<wbr>bools</span><span style=3D"color:#660">&lt;</span><span style=3D"=
color:#008">bool</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#606">Tn</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">value</span><span style=3D"color:#660">)...&gt;,</span><span style=
=3D"color:#000"> __bools</span><span style=3D"color:#660">&lt;(</span><span=
 style=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">value </span><span style=3D"color:#660">&amp;&amp;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">false</span>=
<span style=3D"color:#660">)...&gt;&gt;&gt;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{};</span><span style=3D"color:#000"><=
br><br></span><span style=3D"color:#008">template</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#008">typename</span><span style=3D"color:#660">...</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#606">Tn</span><span style=3D"color:=
#660">&gt;</span><span style=3D"color:#000"> <br></span><span style=3D"colo=
r:#008">struct</span><span style=3D"color:#000"> greedy_conjunction</span><=
span style=3D"color:#660">:</span><span style=3D"color:#000"> std</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#000">is_same</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#000">__bools</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000"><wbr>value</=
span><span style=3D"color:#660">)...&gt;,</span><span style=3D"color:#000">=
 __bools</span><span style=3D"color:#660">&lt;(</span><span style=3D"color:=
#606">Tn</span><span style=3D"color:#660">::</span><span style=3D"color:#00=
0">value </span><span style=3D"color:#660">||</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">true</span><span style=3D"color:#660=
">)...&gt;&gt;</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">{};</span><span style=3D"color:#000"><br></span></div></code></div>=
<div><br><br></div><div>fold expression:</div><div style=3D"background-colo=
r: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:#008">templ=
ate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt=
;</span><span style=3D"color:#008">typename</span><span style=3D"color:#660=
">...</span><span style=3D"color:#000"> </span><span style=3D"color:#606">T=
n</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <=
br></span><span style=3D"color:#008">struct</span><span style=3D"color:#000=
"> greedy_disjunction </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">bool_constant</span><span style=3D"color:#660">&lt;(</span>=
<span style=3D"color:#008">false</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">||</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">...</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">||</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span style=
=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span style=3D=
"color:#000">value</span><span style=3D"color:#660">))&gt;</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">{};</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#008">typename</span><span style=3D"color:#660">...</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><spa=
n style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><s=
pan style=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_co=
njunction </span><span style=3D"color:#660">:</span><span style=3D"color:#0=
00"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#00=
0">bool_constant</span><span style=3D"color:#660">&lt;(</span><span style=
=3D"color:#008">true</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">...</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">value</span><span style=3D"color:#660">))&gt;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{};</span><span styl=
e=3D"color:#000"><br></span></div></code></div><div><br><br></div><div><fon=
t size=3D"4"><b>Wordings:</b></font></div><div><b>There is couple of questi=
ons</b></div><div>I asked them to myself a lot, during this pre-proposal.</=
div><div>-Is it in the C++ standard scope to care about how things will be =
implemented in standard library, even if the implementations will be not ef=
ficient on compile-time level?</div><div>-Should the standard be changed be=
cause of standard library compilation time?</div><div><br></div><div>And he=
re&#39;s my conclusion (and reason why I&#39;m writing this post).</div><di=
v>C++ standard purpose is not to specify a theoretical language. It&#39;s c=
reated to be used by a lot of people in the real world. Giving a choice to =
user between implementations which differs in a compile-time efficiency is =
same thing as to give a choice between containers e.g. `std::vector` and `s=
td::list`. In some cases one implementation is better, in others the other =
one.</div><div><br></div><div><b>And of course the name</b></div><div>I tho=
ught about `strict_*` (like it&#39;s in Facebook/folly lib) instead of `gre=
edy_*`, but I&#39;m sure that if this proposal is a thing community will pr=
opose better names.</div><div><br></div><div><br></div><div>What do you thi=
nk?</div><div><br></div><div>Mateusz (stryku) Janek</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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
GC9zGPQjBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"GC9zGPQjBwAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/a79ce0b4-ca2d-4c37-<wbr>b49e-=
cb707689a0e2%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></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/4b2924fd-0a54-45eb-a2c3-55ddbb5edd73%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/4b2924fd-0a54-45eb-a2c3-55ddbb5edd73=
%40isocpp.org</a>.<br />

------=_Part_232_1616450242.1502313773269--

------=_Part_231_1307637170.1502313773268--

.


Author: mateusz.janek6@gmail.com
Date: Thu, 17 Aug 2017 01:17:19 -0700 (PDT)
Raw View
------=_Part_883_1274865372.1502957839975
Content-Type: multipart/alternative;
 boundary="----=_Part_884_1492112671.1502957839977"

------=_Part_884_1492112671.1502957839977
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello again,
I am wondering if lack of response in this thread means that my idea has=20
been already rejected? If yes then could anyone explain why?

I might be wrong but this is why I'm not convicted by the current arguments=
:

>You can already write your "greedy" things by just... deriving from=20
bool_constant directly (exactly like in your last snippet).
I assume that your point is that it's easy to implement by the user on his=
=20
own. I'm not convicted because there is a lot of stuff in the standard=20
library that are easy to implement, e.g. std::negation

>Your thing doesn't seem to be very useful.
Not sure if I follow. If they are not useful =3D> std::conjunction and=20
disjunction are not as well (:
As you can see they compute almost same result as std::conjunction and=20
disjunction, plus they give a choice to the user about the compilation time=
..

The only thing that concerns me here is if it's in the standard library=20
scope to care about the compilation time.

Thanks in advance,
Mateusz Janek

W dniu =C5=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkownik=20
mateusz...@gmail.com napisa=C5=82:
>
> These traits are as useful as current conjunction and disjunction are -=
=20
> they compute the same result, but additionally give user a choice about=
=20
> compilation time and IMO that's a useful addition.
>
> W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Micha=
=C5=82 Dominiak=20
> napisa=C5=82:
>>
>> You can already write your "greedy" things by just... deriving from=20
>> bool_constant directly (exactly like in your last snippet). You couldn't=
 do=20
>> what the two traits are doing directly, and that's I believe is the only=
=20
>> justification of their existence. Your thing doesn't seem to be very use=
ful.
>>
>> On Wed, Aug 9, 2017 at 2:31 PM <mateusz...@gmail.com> wrote:
>>
>>> *Introduction*
>>>
>>> C++17 introduced besides the others two new structures in=20
>>> `<type_traits>` header: `std::conjuction` and `std::disjunction`. They =
are=20
>>> very useful in metaprogramming, but standard has in some way forced the=
ir=20
>>> implementation.=20
>>> In p0013r1=20
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html> =
we=20
>>> can read:
>>> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> is=
=20
>>> the first type Bi in the list true_type, B1, ..., BN for which Bi::valu=
e=20
>>> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristic i=
s BN. [
>>> *Note:* This means a specialization of conjunction does not necessarily=
=20
>>> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 =
*end=20
>>> note*]
>>>
>>> Similar in the disjunction:=20
>>> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> is=
=20
>>> the first type Bi in the list false_type, B1, ..., BN for which Bi::val=
ue=20
>>> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristic i=
s BN. [
>>> *Note:* This means a specialization of disjunction does not necessarily=
=20
>>> have a BaseCharacteristic of either true_type or false_type. =E2=80=94 =
*end=20
>>> note*]
>>>
>>> I'd like to propose a two new structures in `<type_traits>`:=20
>>> `std::greedy_conjunction` and `std::greedy_disjunction`. Their results=
=20
>>> would very similar to the ones from `std::conjunciton` and=20
>>> `std::disjunction`, but their specification would give more flexibility=
 to=20
>>> the standard library creators.
>>>
>>>
>>> *Motivation and Scope*
>>>
>>> With `std::conjuction` and `std::disjunction` restrictions in the=20
>>> standard, library creators are forced to make them in such (or similar)=
 way:
>>> template<class...> struct conjunction : std::true_type { };
>>> template<class B1> struct conjunction<B1> : B1 { };
>>> template<class B1, class... Bn>
>>> struct conjunction<B1, Bn...>=20
>>>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
>>>    =20
>>> template<class...> struct disjunction : std::false_type { };
>>> template<class B1> struct disjunction<B1> : B1 { };
>>> template<class B1, class... Bn>
>>> struct disjunction<B1, Bn...>=20
>>>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  { };
>>>
>>>
>>>    =20
>>> There are strong grounds to keep these implementations, e.g.=20
>>> short-circuiting, getting information on what type, recursion stopped e=
tc.=20
>>> Although, because of these restrictions compilation time suffers in som=
e=20
>>> cases.
>>>
>>> *Why new, very similar traits?*
>>> *Abstract*
>>> During my pull request to folly (
>>> https://github.com/facebook/folly/pull/643) Jay Feldblum posted there a=
=20
>>> small benchmark script:=20
>>> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (big=
=20
>>> credits for poking my brain with the idea). I was surprised that, let's=
=20
>>> say, the naive implementation compiles faster that the standard one.=20
>>>
>>> I decided to benchmark this idea deeper:
>>> -problem was to find in a types sequence if there is a type which=20
>>> T::value is equal to 0
>>> -for every benchmark sequence has 1024 types inside
>>> -tested sequences with two kinds of types: light and heavy to instantia=
te
>>> -tested best and worse cases
>>> -tested two new implementations: fold expression and bool-pack
>>> -core benchmark was to measure the compilation time with given compiler=
=20
>>> (clang++-4.0/g++-6), case (best/worse), type (light/heavy), implementat=
ion=20
>>> (proposed/standard). Every compilation case was ran 500 times and avera=
ge=20
>>> result was calculated.
>>>
>>> Whole benchmarks code you can find in the gh repo:=20
>>> https://github.com/stryku/boolpack_vs_recursion
>>>
>>> And here are the results (sorry for not posting it here, but table was=
=20
>>> too big and it was formatted in unreadable way):
>>>
>>> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/o=
utput
>>>
>>> As you can see, standard implementation is way better when we deal with=
=20
>>> the best case. It can compile 80x(!) faster than the proposed ones. Pro=
blem=20
>>> starts when the worse cases occurs.=20
>>> Standard library creators would be able to implement=20
>>> `greedy_conjunction` and `greedy_disjunction` in a way that they compil=
es=20
>>> up to around 6x faster than the standard one. Users would be able choos=
e=20
>>> implementation which will suit best, based on what cases they are mostl=
y=20
>>> expecting.
>>>
>>> *Specification*
>>> Since it's a pre-proposal I don't want to post fully described=20
>>> specification. I'm thinking about it in this way:
>>>
>>> `std::greedy_conjunction` would be an alias or would derive from a type=
,=20
>>> which has a constexpr member `value` which can be converted to bool and=
 is=20
>>> equal to:
>>> -false if any bool(Tn::value0 =3D=3D false
>>> -true otherwise
>>>
>>> `std::greedy_disjunction` would be an alias or would derive from a type=
,=20
>>> which has a constexpr member `value` which can be converted to bool and=
 is=20
>>> equal to:
>>> -false if all bool(Tn::value) =3D=3D false
>>> -true otherwise
>>>
>>> *Example implementations*
>>> bool-pack (this one seems to compile faster than fold expression):
>>> template <bool... Bn>
>>> struct __bools {};
>>>
>>> template <typename... Tn>=20
>>> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn::
>>> value)...>, __bools<(Tn::value && false)...>>> {};
>>>
>>> template <typename... Tn>=20
>>> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,=20
>>> __bools<(Tn::value || true)...>> {};
>>>
>>>
>>> fold expression:
>>> template <typename... Tn>=20
>>> struct greedy_disjunction : std::bool_constant<(false || ... || bool(Tn
>>> ::value))> {};
>>>
>>> template <typename... Tn>=20
>>> struct greedy_conjunction : std::bool_constant<(true && ... && bool(Tn:=
:
>>> value))> {};
>>>
>>>
>>> *Wordings:*
>>> *There is couple of questions*
>>> I asked them to myself a lot, during this pre-proposal.
>>> -Is it in the C++ standard scope to care about how things will be=20
>>> implemented in standard library, even if the implementations will be no=
t=20
>>> efficient on compile-time level?
>>> -Should the standard be changed because of standard library compilation=
=20
>>> time?
>>>
>>> And here's my conclusion (and reason why I'm writing this post).
>>> C++ standard purpose is not to specify a theoretical language. It's=20
>>> created to be used by a lot of people in the real world. Giving a choic=
e to=20
>>> user between implementations which differs in a compile-time efficiency=
 is=20
>>> same thing as to give a choice between containers e.g. `std::vector` an=
d=20
>>> `std::list`. In some cases one implementation is better, in others the=
=20
>>> other one.
>>>
>>> *And of course the name*
>>> I thought about `strict_*` (like it's in Facebook/folly lib) instead of=
=20
>>> `greedy_*`, but I'm sure that if this proposal is a thing community wil=
l=20
>>> propose better names.
>>>
>>>
>>> What do you think?
>>>
>>> Mateusz (stryku) Janek
>>>
>>> --=20
>>> You received this message because you are subscribed to the Google=20
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>> an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> To view this discussion on the web visit=20
>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-c=
a2d-4c37-b49e-cb707689a0e2%40isocpp.org=20
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-=
ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=3Dfo=
oter>
>>> .
>>>
>>

--=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/81a6a1fa-a331-483e-8f4d-4184c661b106%40isocpp.or=
g.

------=_Part_884_1492112671.1502957839977
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello again,</div><div>I am wondering if lack of resp=
onse in this thread means that my idea has been already rejected? If yes th=
en could anyone explain why?</div><div><br></div><div>I might be wrong but =
this is why I&#39;m not convicted by the current arguments:</div><div><br><=
/div><div>&gt;You can already write your &quot;greedy&quot; things by just.=
... deriving from bool_constant directly (exactly like in your last snippet)=
..</div><div>I assume that your point is that it&#39;s easy to implement by =
the user on his own. I&#39;m not convicted because there is a lot of stuff =
in the standard library that are easy to implement, e.g. std::negation</div=
><div><br></div><div>&gt;Your thing doesn&#39;t seem to be very useful.</di=
v><div>Not sure if I follow. If they are not useful =3D&gt; std::conjunctio=
n and disjunction are not as well (:</div><div>As you can see they compute =
almost same result as std::conjunction and disjunction, plus they give a ch=
oice to the user about the compilation time.</div><div><br></div><div>The o=
nly thing that concerns me here is if it&#39;s in the standard library scop=
e to care about the compilation time.</div><div><br></div><div>Thanks in ad=
vance,</div><div>Mateusz Janek</div><br>W dniu =C5=9Broda, 9 sierpnia 2017 =
23:22:53 UTC+2 u=C5=BCytkownik mateusz...@gmail.com napisa=C5=82:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">These traits are as use=
ful as current conjunction and disjunction are - they compute the same resu=
lt, but additionally give user a choice about compilation time and IMO that=
&#39;s a useful addition.<br><br>W dniu =C5=9Broda, 9 sierpnia 2017 14:37:0=
5 UTC+2 u=C5=BCytkownik Micha=C5=82 Dominiak napisa=C5=82:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">You can already write your &quot;gr=
eedy&quot; things by just... deriving from bool_constant directly (exactly =
like in your last snippet). You couldn&#39;t do what the two traits are doi=
ng directly, and that&#39;s I believe is the only justification of their ex=
istence. Your thing doesn&#39;t seem to be very useful.</div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr">On Wed, Aug 9, 2017 at 2:31 PM &lt;<a rel=
=3D"nofollow">mateusz...@gmail.com</a>&gt; wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><b><font size=3D"4">Introduction</font=
></b></div><div><br></div><div>C++17 introduced besides the others two new =
structures in `&lt;type_traits&gt;` header: `std::conjuction` and `std::dis=
junction`. They are very useful in metaprogramming, but standard has in som=
e way forced their implementation.=C2=A0</div><div>In <a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html" rel=3D"nofollow=
" target=3D"_blank" onmousedown=3D"this.href=3D&#39;http://www.google.com/u=
rl?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%=
2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHrhD3oGJRVXph=
YJvzGExp6I3jexQ&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.g=
oogle.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdoc=
s%2Fpapers%2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHr=
hD3oGJRVXphYJvzGExp6I3jexQ&#39;;return true;">p0013r1</a>=C2=A0we can read:=
</div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">The BaseCharacteristic of a =
specialization=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:jus=
tify">conjunction&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0=
);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justi=
fy">=C2=A0is the first type=C2=A0</span><code style=3D"color:rgb(0,160,0);t=
ext-align:justify">Bi</code><span style=3D"color:rgb(0,160,0);font-family:&=
quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0in th=
e list=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">tr=
ue_type, B1, ..., BN</code><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0for wh=
ich=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi::v=
alue =3D=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&quot=
;Times New Roman&quot;;font-size:medium;text-align:justify">, or if every=
=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi::valu=
e !=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Time=
s New Roman&quot;;font-size:medium;text-align:justify">=C2=A0the BaseCharac=
teristic is=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justif=
y">BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New R=
oman&quot;;font-size:medium;text-align:justify">. [</span><em style=3D"colo=
r:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;tex=
t-align:justify">Note:</em><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0This m=
eans a specialization of=C2=A0</span><code style=3D"color:rgb(0,160,0);text=
-align:justify">conjunction</code><span style=3D"color:rgb(0,160,0);font-fa=
mily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0does not necessarily have a BaseCharacteristic of either=C2=A0</span><co=
de style=3D"color:rgb(0,160,0);text-align:justify">true_type</code><span st=
yle=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size=
:medium;text-align:justify">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0=
,160,0);text-align:justify">false_type</code><span style=3D"color:rgb(0,160=
,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:jus=
tify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"color:rgb(0,160,0);font-fam=
ily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">end no=
te</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&=
quot;;font-size:medium;text-align:justify">]</span><br></div><div><span sty=
le=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:=
medium;text-align:justify"><br></span></div><div>Similar in the disjunction=
:=C2=A0</div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;Times=
 New Roman&quot;;font-size:medium;text-align:justify">The BaseCharacteristi=
c of a specialization=C2=A0</span><code style=3D"color:rgb(0,160,0);text-al=
ign:justify">disjunction&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(=
0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-alig=
n:justify">=C2=A0is the first type=C2=A0</span><code style=3D"color:rgb(0,1=
60,0);text-align:justify">Bi</code><span style=3D"color:rgb(0,160,0);font-f=
amily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0in the list=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:jus=
tify">false_type, B1, ..., BN</code><span style=3D"color:rgb(0,160,0);font-=
family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0for which=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justi=
fy">Bi::value !=3D false</code><span style=3D"color:rgb(0,160,0);font-famil=
y:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">, or if =
every=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi:=
:value =3D=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&qu=
ot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0the Bas=
eCharacteristic is=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align=
:justify">BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Time=
s New Roman&quot;;font-size:medium;text-align:justify">. [</span><em style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">Note:</em><span style=3D"color:rgb(0,160,0);font-f=
amily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0This means a specialization of=C2=A0</span><code style=3D"color:rgb(0,16=
0,0);text-align:justify">disjunction</code><span style=3D"color:rgb(0,160,0=
);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justi=
fy">=C2=A0does not necessarily have a BaseCharacteristic of either=C2=A0</s=
pan><code style=3D"color:rgb(0,160,0);text-align:justify">true_type</code><=
span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;fo=
nt-size:medium;text-align:justify">=C2=A0or=C2=A0</span><code style=3D"colo=
r:rgb(0,160,0);text-align:justify">false_type</code><span style=3D"color:rg=
b(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-al=
ign:justify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"color:rgb(0,160,0);f=
ont-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify"=
>end note</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New=
 Roman&quot;;font-size:medium;text-align:justify">]</span><br></div><div><b=
r></div><div>I&#39;d like to propose a two new structures in `&lt;type_trai=
ts&gt;`: `std::greedy_conjunction` and `std::greedy_disjunction`. Their res=
ults would very similar to the ones from `std::conjunciton` and `std::disju=
nction`, but their specification would give more flexibility to the standar=
d library creators.</div><div><br></div><div><br></div><div><b><font size=
=3D"4">Motivation and Scope</font></b></div><div><br></div><div>With `std::=
conjuction` and `std::disjunction` restrictions in the standard, library cr=
eators are forced to make them in such (or similar) way:</div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"c=
olor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#660">...&gt;</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><span =
style=3D"color:#000"> conjunction </span><span style=3D"color:#660">:</span=
><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">true_type </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">template</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct=
</span><span style=3D"color:#000"> conjunction</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#6=
60">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> B1 </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">c=
lass</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">class=
</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> conjunction</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Bn=
</span><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000">=
 <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">:</span><span style=3D=
"color:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"=
color:#000">conditional_t</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">B1</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">va<wbr>lue</span><span style=3D"color:#660">),</span><span=
 style=3D"color:#000"> conjunction</span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;,=
</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{};</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <br></span><span style=3D"=
color:#008">template</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#008">class</span><span style=3D"color:#660">...&gt;</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><span=
 style=3D"color:#000"> disjunction </span><span style=3D"color:#660">:</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">false_type </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">template=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">stru=
ct</span><span style=3D"color:#000"> disjunction</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:=
#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">:</span><span style=3D"color:#000"> B1 </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></span><span style=3D"color:#008">temp=
late</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008"=
>class</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#008">struc=
t</span><span style=3D"color:#000"> disjunction</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Bn</span><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000=
"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">conditional_t</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">B1</span><span style=3D"color:#660">::</span><span =
style=3D"color:#000">va<wbr>lue</span><span style=3D"color:#660">),</span><=
span style=3D"color:#000"> B1</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> disjunction</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;=
&gt;</span><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}=
;</span><span style=3D"color:#000"><br><br></span></div></code></div><div><=
br>=C2=A0 =C2=A0=C2=A0</div><div>There are strong grounds to keep these imp=
lementations, e.g. short-circuiting, getting information on what type, recu=
rsion stopped etc. Although, because of these restrictions compilation time=
 suffers in some cases.</div><div><br></div><div><b><font size=3D"4">Why ne=
w,=C2=A0<u>very similar</u> traits?</font></b></div><div><b>Abstract</b></d=
iv><div>During my pull request to folly (<a href=3D"https://github.com/face=
book/folly/pull/643" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this=
..href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffac=
ebook%2Ffolly%2Fpull%2F643\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzRzYU=
aerIKsE3rogxWBbtocbw&#39;;return true;" onclick=3D"this.href=3D&#39;https:/=
/www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffacebook%2Ffolly%2Fpull=
%2F643\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzRzYUaerIKsE3rogxWBbtocbw=
&#39;;return true;">https://github.com/facebook/<wbr>folly/pull/643</a>) Ja=
y Feldblum posted there a small benchmark script: <a href=3D"https://gist.g=
ithub.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b" rel=3D"nofollow" targ=
et=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1=
555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#=
39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1=
555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#=
39;;return true;">https://gist.github.com/<wbr>yfeldblum/<wbr>ffae5374aaaa1=
1b03f08919d25b155<wbr>5b</a>=C2=A0(big credits for poking my brain with the=
 idea). I was surprised that, let&#39;s say, the naive implementation compi=
les faster that the standard one.=C2=A0</div><div><br></div><div>I decided =
to benchmark this idea deeper:</div><div>-problem was to find in a types se=
quence if there is a type which T::value is equal to 0</div><div>-for every=
 benchmark sequence has 1024 types inside</div><div>-tested sequences with =
two kinds of types: light and heavy to instantiate</div><div>-tested best a=
nd worse cases</div><div>-tested two new implementations: fold expression a=
nd bool-pack</div><div>-core benchmark was to measure the compilation time =
with given compiler (clang++-4.0/g++-6), case (best/worse), type (light/hea=
vy), implementation (proposed/standard). Every compilation case was ran 500=
 times and average result was calculated.</div><div><br></div><div>Whole be=
nchmarks code you can find in the gh repo:=C2=A0<a href=3D"https://github.c=
om/stryku/boolpack_vs_recursion" rel=3D"nofollow" target=3D"_blank" onmouse=
down=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgith=
ub.com%2Fstryku%2Fboolpack_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNHICyJnr6jjlrCVLCKQErJdqh0rLg&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fstryku%2=
Fboolpack_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHICyJnr6jjlr=
CVLCKQErJdqh0rLg&#39;;return true;">https://github.com/<wbr>stryku/boolpack=
_vs_recursion</a></div><div><br></div><div>And here are the results (sorry =
for not posting it here, but table was too big and it was formatted in unre=
adable way):</div><div><a href=3D"https://raw.githubusercontent.com/stryku/=
boolpack_vs_recursion/master/output" rel=3D"nofollow" target=3D"_blank" onm=
ousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2F=
raw.githubusercontent.com%2Fstryku%2Fboolpack_vs_recursion%2Fmaster%2Foutpu=
t\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08KY4FDz5dQ&#39;=
;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3d=
https%3A%2F%2Fraw.githubusercontent.com%2Fstryku%2Fboolpack_vs_recursion%2F=
master%2Foutput\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08=
KY4FDz5dQ&#39;;return true;">https://raw.githubusercontent.<wbr>com/stryku/=
boolpack_vs_<wbr>recursion/master/output</a></div><div><br></div><div>As yo=
u can see, standard implementation is way better when we deal with the best=
 case. It can compile 80x(!) faster than the proposed ones. Problem starts =
when the worse cases occurs.=C2=A0</div><div>Standard library creators woul=
d be able to implement `greedy_conjunction` and `greedy_disjunction` in a w=
ay that they compiles up to around 6x faster than the standard one. Users w=
ould be able choose implementation which will suit best, based on what case=
s they are mostly expecting.</div><div><br></div><div><font size=3D"4"><b>S=
pecification</b></font></div><div>Since it&#39;s a pre-proposal I don&#39;t=
 want to post fully described specification. I&#39;m thinking about it in t=
his way:</div><div><br></div><div>`std::greedy_conjunction` would be an ali=
as or would derive from a type, which has a constexpr member `value` which =
can be converted to bool and is equal to:</div><div>-false if any bool(Tn::=
value0 =3D=3D false</div><div>-true otherwise</div><div><br></div><div><div=
>`std::greedy_disjunction` would be an alias or would derive from a type, w=
hich has a constexpr member `value` which can be converted to bool and is e=
qual to:</div><div>-false if all bool(Tn::value) =3D=3D false</div><div>-tr=
ue otherwise</div></div><div><br></div><div><font size=3D"4"><b>Example imp=
lementations</b></font></div><div>bool-pack (this one seems to compile fast=
er than fold expression):</div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-=
wrap:break-word"><code><div><span style=3D"color:#008">template</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#008">bool</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#606">Bn</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">struct</span><span style=3D"color:#000"> __bools </span><s=
pan style=3D"color:#660">{};</span><span style=3D"color:#000"><br><br></spa=
n><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typena=
me</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"> <br></span><span style=3D"color:#008">stru=
ct</span><span style=3D"color:#000"> greedy_disjunction</span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">negation</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#000">std</span><span st=
yle=3D"color:#660">::</span><span style=3D"color:#000">is_same</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#000">__<wbr>bools</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">value</span>=
<span style=3D"color:#660">)...&gt;,</span><span style=3D"color:#000"> __bo=
ols</span><span style=3D"color:#660">&lt;(</span><span style=3D"color:#606"=
>Tn</span><span style=3D"color:#660">::</span><span style=3D"color:#000">va=
lue </span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">false</span><span style=3D"color:=
#660">)...&gt;&gt;&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{};</span><span style=3D"color:#000"><br><br></span><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span>=
<span style=3D"color:#660">...</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Tn</span><span style=3D"color:#660">&gt;</span><spa=
n style=3D"color:#000"> <br></span><span style=3D"color:#008">struct</span>=
<span style=3D"color:#000"> greedy_conjunction</span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">is_same</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#000">__bools</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">bool</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#606">Tn</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000"><wbr>value</span><span style=3D"c=
olor:#660">)...&gt;,</span><span style=3D"color:#000"> __bools</span><span =
style=3D"color:#660">&lt;(</span><span style=3D"color:#606">Tn</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">value </span><span=
 style=3D"color:#660">||</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">true</span><span style=3D"color:#660">)...&gt;&gt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{};</span><sp=
an style=3D"color:#000"><br></span></div></code></div><div><br><br></div><d=
iv>fold expression:</div><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:b=
reak-word"><code><div><span style=3D"color:#008">template</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><span sty=
le=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_disjuncti=
on </span><span style=3D"color:#660">:</span><span style=3D"color:#000"> st=
d</span><span style=3D"color:#660">::</span><span style=3D"color:#000">bool=
_constant</span><span style=3D"color:#660">&lt;(</span><span style=3D"color=
:#008">false</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">||</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">...</span><span style=3D"color:#000"> </span><span style=3D"color:#660">|=
|</span><span style=3D"color:#000"> </span><span style=3D"color:#008">bool<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">value</spa=
n><span style=3D"color:#660">))&gt;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">{};</span><span style=3D"color:#000"><br><br><=
/span><span style=3D"color:#008">template</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#660">...</span><span style=3D"color:#000=
"> </span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> <br></span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> greedy_conjunction </span><span st=
yle=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">bool_constant</span><s=
pan style=3D"color:#660">&lt;(</span><span style=3D"color:#008">true</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">...</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">bool</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">value</span><=
span style=3D"color:#660">))&gt;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{};</span><span style=3D"color:#000"><br></span><=
/div></code></div><div><br><br></div><div><font size=3D"4"><b>Wordings:</b>=
</font></div><div><b>There is couple of questions</b></div><div>I asked the=
m to myself a lot, during this pre-proposal.</div><div>-Is it in the C++ st=
andard scope to care about how things will be implemented in standard libra=
ry, even if the implementations will be not efficient on compile-time level=
?</div><div>-Should the standard be changed because of standard library com=
pilation time?</div><div><br></div><div>And here&#39;s my conclusion (and r=
eason why I&#39;m writing this post).</div><div>C++ standard purpose is not=
 to specify a theoretical language. It&#39;s created to be used by a lot of=
 people in the real world. Giving a choice to user between implementations =
which differs in a compile-time efficiency is same thing as to give a choic=
e between containers e.g. `std::vector` and `std::list`. In some cases one =
implementation is better, in others the other one.</div><div><br></div><div=
><b>And of course the name</b></div><div>I thought about `strict_*` (like i=
t&#39;s in Facebook/folly lib) instead of `greedy_*`, but I&#39;m sure that=
 if this proposal is a thing community will propose better names.</div><div=
><br></div><div><br></div><div>What do you think?</div><div><br></div><div>=
Mateusz (stryku) Janek</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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/a79ce0b4-ca2d-4c37-<wbr>b49e-=
cb707689a0e2%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></div></blockquote></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/81a6a1fa-a331-483e-8f4d-4184c661b106%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a331-483e-8f4d-4184c661b106=
%40isocpp.org</a>.<br />

------=_Part_884_1492112671.1502957839977--

------=_Part_883_1274865372.1502957839975--

.


Author: =?UTF-8?Q?Micha=C5=82_Dominiak?= <griwes@griwes.info>
Date: Thu, 17 Aug 2017 08:26:00 +0000
Raw View
--001a114db740cc70910556eec3f3
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

What I meant is that you don't really need a specific trait.

You can't obtain the result of std::{con,dis}junction directly, without
using a layer of abstraction for the laziness.

You can, however, obtain the result of the greedy operation directly - by
just &&ing or ||ing the values of the traits you'd pass to this trait.
Evaluation in templates is already eager that way, and it's no problem to
&& or || them together even in generic contexts, especially since we have
fold expressions now.

The reason for the traits that we have is laziness. If you don't need
laziness, you don't need the trait.

On Thu, Aug 17, 2017, 10:17 AM <mateusz.janek6@gmail.com> wrote:

> Hello again,
> I am wondering if lack of response in this thread means that my idea has
> been already rejected? If yes then could anyone explain why?
>
> I might be wrong but this is why I'm not convicted by the current
> arguments:
>
> >You can already write your "greedy" things by just... deriving from
> bool_constant directly (exactly like in your last snippet).
> I assume that your point is that it's easy to implement by the user on hi=
s
> own. I'm not convicted because there is a lot of stuff in the standard
> library that are easy to implement, e.g. std::negation
>
> >Your thing doesn't seem to be very useful.
> Not sure if I follow. If they are not useful =3D> std::conjunction and
> disjunction are not as well (:
> As you can see they compute almost same result as std::conjunction and
> disjunction, plus they give a choice to the user about the compilation ti=
me.
>
> The only thing that concerns me here is if it's in the standard library
> scope to care about the compilation time.
>
> Thanks in advance,
> Mateusz Janek
>
> W dniu =C5=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkownik
> mateusz...@gmail.com napisa=C5=82:
>>
>> These traits are as useful as current conjunction and disjunction are -
>> they compute the same result, but additionally give user a choice about
>> compilation time and IMO that's a useful addition.
>>
>> W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Micha=
=C5=82 Dominiak
>> napisa=C5=82:
>>>
>>> You can already write your "greedy" things by just... deriving from
>>> bool_constant directly (exactly like in your last snippet). You couldn'=
t do
>>> what the two traits are doing directly, and that's I believe is the onl=
y
>>> justification of their existence. Your thing doesn't seem to be very us=
eful.
>>>
>>> On Wed, Aug 9, 2017 at 2:31 PM <mateusz...@gmail.com> wrote:
>>>
>>>> *Introduction*
>>>>
>>>> C++17 introduced besides the others two new structures in
>>>> `<type_traits>` header: `std::conjuction` and `std::disjunction`. They=
 are
>>>> very useful in metaprogramming, but standard has in some way forced th=
eir
>>>> implementation.
>>>> In p0013r1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html>=
 we
>>>> can read:
>>>> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> is
>>>> the first type Bi in the list true_type, B1, ..., BN for which Bi::val=
ue
>>>> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristic =
is BN.
>>>> [*Note:* This means a specialization of conjunction does not
>>>> necessarily have a BaseCharacteristic of either true_type or false_typ=
e.
>>>> =E2=80=94 *end note*]
>>>>
>>>> Similar in the disjunction:
>>>> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> is
>>>> the first type Bi in the list false_type, B1, ..., BN for which Bi::va=
lue
>>>> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristic =
is BN.
>>>> [*Note:* This means a specialization of disjunction does not
>>>> necessarily have a BaseCharacteristic of either true_type or false_typ=
e.
>>>> =E2=80=94 *end note*]
>>>>
>>>> I'd like to propose a two new structures in `<type_traits>`:
>>>> `std::greedy_conjunction` and `std::greedy_disjunction`. Their results
>>>> would very similar to the ones from `std::conjunciton` and
>>>> `std::disjunction`, but their specification would give more flexibilit=
y to
>>>> the standard library creators.
>>>>
>>>>
>>>> *Motivation and Scope*
>>>>
>>>> With `std::conjuction` and `std::disjunction` restrictions in the
>>>> standard, library creators are forced to make them in such (or similar=
) way:
>>>> template<class...> struct conjunction : std::true_type { };
>>>> template<class B1> struct conjunction<B1> : B1 { };
>>>> template<class B1, class... Bn>
>>>> struct conjunction<B1, Bn...>
>>>>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
>>>>
>>>> template<class...> struct disjunction : std::false_type { };
>>>> template<class B1> struct disjunction<B1> : B1 { };
>>>> template<class B1, class... Bn>
>>>> struct disjunction<B1, Bn...>
>>>>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  { }=
;
>>>>
>>>>
>>>>
>>>> There are strong grounds to keep these implementations, e.g.
>>>> short-circuiting, getting information on what type, recursion stopped =
etc.
>>>> Although, because of these restrictions compilation time suffers in so=
me
>>>> cases.
>>>>
>>>> *Why new, very similar traits?*
>>>> *Abstract*
>>>> During my pull request to folly (
>>>> https://github.com/facebook/folly/pull/643) Jay Feldblum posted there
>>>> a small benchmark script:
>>>> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (bi=
g
>>>> credits for poking my brain with the idea). I was surprised that, let'=
s
>>>> say, the naive implementation compiles faster that the standard one.
>>>>
>>>> I decided to benchmark this idea deeper:
>>>> -problem was to find in a types sequence if there is a type which
>>>> T::value is equal to 0
>>>> -for every benchmark sequence has 1024 types inside
>>>> -tested sequences with two kinds of types: light and heavy to
>>>> instantiate
>>>> -tested best and worse cases
>>>> -tested two new implementations: fold expression and bool-pack
>>>> -core benchmark was to measure the compilation time with given compile=
r
>>>> (clang++-4.0/g++-6), case (best/worse), type (light/heavy), implementa=
tion
>>>> (proposed/standard). Every compilation case was ran 500 times and aver=
age
>>>> result was calculated.
>>>>
>>>> Whole benchmarks code you can find in the gh repo:
>>>> https://github.com/stryku/boolpack_vs_recursion
>>>>
>>>> And here are the results (sorry for not posting it here, but table was
>>>> too big and it was formatted in unreadable way):
>>>>
>>>> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/=
output
>>>>
>>>> As you can see, standard implementation is way better when we deal wit=
h
>>>> the best case. It can compile 80x(!) faster than the proposed ones. Pr=
oblem
>>>> starts when the worse cases occurs.
>>>> Standard library creators would be able to implement
>>>> `greedy_conjunction` and `greedy_disjunction` in a way that they compi=
les
>>>> up to around 6x faster than the standard one. Users would be able choo=
se
>>>> implementation which will suit best, based on what cases they are most=
ly
>>>> expecting.
>>>>
>>>> *Specification*
>>>> Since it's a pre-proposal I don't want to post fully described
>>>> specification. I'm thinking about it in this way:
>>>>
>>>> `std::greedy_conjunction` would be an alias or would derive from a
>>>> type, which has a constexpr member `value` which can be converted to b=
ool
>>>> and is equal to:
>>>> -false if any bool(Tn::value0 =3D=3D false
>>>> -true otherwise
>>>>
>>>> `std::greedy_disjunction` would be an alias or would derive from a
>>>> type, which has a constexpr member `value` which can be converted to b=
ool
>>>> and is equal to:
>>>> -false if all bool(Tn::value) =3D=3D false
>>>> -true otherwise
>>>>
>>>> *Example implementations*
>>>> bool-pack (this one seems to compile faster than fold expression):
>>>> template <bool... Bn>
>>>> struct __bools {};
>>>>
>>>> template <typename... Tn>
>>>> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn:=
:
>>>> value)...>, __bools<(Tn::value && false)...>>> {};
>>>>
>>>> template <typename... Tn>
>>>> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,
>>>> __bools<(Tn::value || true)...>> {};
>>>>
>>>>
>>>> fold expression:
>>>> template <typename... Tn>
>>>> struct greedy_disjunction : std::bool_constant<(false || ... || bool(T=
n
>>>> ::value))> {};
>>>>
>>>> template <typename... Tn>
>>>> struct greedy_conjunction : std::bool_constant<(true && ... && bool(Tn
>>>> ::value))> {};
>>>>
>>>>
>>>> *Wordings:*
>>>> *There is couple of questions*
>>>> I asked them to myself a lot, during this pre-proposal.
>>>> -Is it in the C++ standard scope to care about how things will be
>>>> implemented in standard library, even if the implementations will be n=
ot
>>>> efficient on compile-time level?
>>>> -Should the standard be changed because of standard library compilatio=
n
>>>> time?
>>>>
>>>> And here's my conclusion (and reason why I'm writing this post).
>>>> C++ standard purpose is not to specify a theoretical language. It's
>>>> created to be used by a lot of people in the real world. Giving a choi=
ce to
>>>> user between implementations which differs in a compile-time efficienc=
y is
>>>> same thing as to give a choice between containers e.g. `std::vector` a=
nd
>>>> `std::list`. In some cases one implementation is better, in others the
>>>> other one.
>>>>
>>>> *And of course the name*
>>>> I thought about `strict_*` (like it's in Facebook/folly lib) instead o=
f
>>>> `greedy_*`, but I'm sure that if this proposal is a thing community wi=
ll
>>>> propose better names.
>>>>
>>>>
>>>> What do you think?
>>>>
>>>> Mateusz (stryku) Janek
>>>>
>>>> --
>>>> 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-proposal...@isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4-=
ca2d-4c37-b49e-cb707689a0e2%40isocpp.org
>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4=
-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=3Df=
ooter>
>>>> .
>>>>
>>> --
> 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/81a6a1fa-a33=
1-483e-8f4d-4184c661b106%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a3=
31-483e-8f4d-4184c661b106%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=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/CAPCFJdTA7pfnGu8uQ7FBu-qj%3DUCJuRO78G-CYovSz9gAx=
PNSmw%40mail.gmail.com.

--001a114db740cc70910556eec3f3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr">What I meant is that you don&#39;t really need a specific tr=
ait.</p>
<p dir=3D"ltr">You can&#39;t obtain the result of std::{con,dis}junction di=
rectly, without using a layer of abstraction for the laziness.</p>
<p dir=3D"ltr">You can, however, obtain the result of the greedy operation =
directly - by just &amp;&amp;ing or ||ing the values of the traits you&#39;=
d pass to this trait. Evaluation in templates is already eager that way, an=
d it&#39;s no problem to &amp;&amp; or || them together even in generic con=
texts, especially since we have fold expressions now.</p>
<p dir=3D"ltr">The reason for the traits that we have is laziness. If you d=
on&#39;t need laziness, you don&#39;t need the trait.</p>
<br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 17, 2017, 10:17=
 AM  &lt;<a href=3D"mailto:mateusz.janek6@gmail.com">mateusz.janek6@gmail.c=
om</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div>Hello again,</div><div>I am wondering if lack of response in this thre=
ad means that my idea has been already rejected? If yes then could anyone e=
xplain why?</div><div><br></div><div>I might be wrong but this is why I&#39=
;m not convicted by the current arguments:</div></div><div dir=3D"ltr"><div=
><br></div><div>&gt;You can already write your &quot;greedy&quot; things by=
 just... deriving from bool_constant directly (exactly like in your last sn=
ippet).</div></div><div dir=3D"ltr"><div>I assume that your point is that i=
t&#39;s easy to implement by the user on his own. I&#39;m not convicted bec=
ause there is a lot of stuff in the standard library that are easy to imple=
ment, e.g. std::negation</div></div><div dir=3D"ltr"><div><br></div><div>&g=
t;Your thing doesn&#39;t seem to be very useful.</div></div><div dir=3D"ltr=
"><div>Not sure if I follow. If they are not useful =3D&gt; std::conjunctio=
n and disjunction are not as well (:</div><div>As you can see they compute =
almost same result as std::conjunction and disjunction, plus they give a ch=
oice to the user about the compilation time.</div><div><br></div><div>The o=
nly thing that concerns me here is if it&#39;s in the standard library scop=
e to care about the compilation time.</div><div><br></div><div>Thanks in ad=
vance,</div><div>Mateusz Janek</div></div><div dir=3D"ltr"><br>W dniu =C5=
=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkownik <a href=3D"mailto:m=
ateusz...@gmail.com" target=3D"_blank">mateusz...@gmail.com</a> napisa=C5=
=82:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">These traits a=
re as useful as current conjunction and disjunction are - they compute the =
same result, but additionally give user a choice about compilation time and=
 IMO that&#39;s a useful addition.<br><br>W dniu =C5=9Broda, 9 sierpnia 201=
7 14:37:05 UTC+2 u=C5=BCytkownik Micha=C5=82 Dominiak napisa=C5=82:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr">You can already write your=
 &quot;greedy&quot; things by just... deriving from bool_constant directly =
(exactly like in your last snippet). You couldn&#39;t do what the two trait=
s are doing directly, and that&#39;s I believe is the only justification of=
 their existence. Your thing doesn&#39;t seem to be very useful.</div><br><=
div class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Aug 9, 2017 at 2:31 PM &=
lt;<a rel=3D"nofollow">mateusz...@gmail.com</a>&gt; wrote:<br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div><b><font size=3D"4">Introduct=
ion</font></b></div><div><br></div><div>C++17 introduced besides the others=
 two new structures in `&lt;type_traits&gt;` header: `std::conjuction` and =
`std::disjunction`. They are very useful in metaprogramming, but standard h=
as in some way forced their implementation.=C2=A0</div><div>In <a href=3D"h=
ttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html" rel=3D=
"nofollow" target=3D"_blank">p0013r1</a>=C2=A0we can read:</div><div><span =
style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-si=
ze:medium;text-align:justify">The BaseCharacteristic of a specialization=C2=
=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">conjunction=
&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0);font-family:&qu=
ot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0is the =
first type=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify=
">Bi</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0in the list=C2=A0</spa=
n><code style=3D"color:rgb(0,160,0);text-align:justify">true_type, B1, ...,=
 BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Rom=
an&quot;;font-size:medium;text-align:justify">=C2=A0for which=C2=A0</span><=
code style=3D"color:rgb(0,160,0);text-align:justify">Bi::value =3D=3D false=
</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&=
quot;;font-size:medium;text-align:justify">, or if every=C2=A0</span><code =
style=3D"color:rgb(0,160,0);text-align:justify">Bi::value !=3D false</code>=
<span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;f=
ont-size:medium;text-align:justify">=C2=A0the BaseCharacteristic is=C2=A0</=
span><code style=3D"color:rgb(0,160,0);text-align:justify">BN</code><span s=
tyle=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-siz=
e:medium;text-align:justify">. [</span><em style=3D"color:rgb(0,160,0);font=
-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">No=
te:</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman=
&quot;;font-size:medium;text-align:justify">=C2=A0This means a specializati=
on of=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">con=
junction</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times Ne=
w Roman&quot;;font-size:medium;text-align:justify">=C2=A0does not necessari=
ly have a BaseCharacteristic of either=C2=A0</span><code style=3D"color:rgb=
(0,160,0);text-align:justify">true_type</code><span style=3D"color:rgb(0,16=
0,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:ju=
stify">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:ju=
stify">false_type</code><span style=3D"color:rgb(0,160,0);font-family:&quot=
;Times New Roman&quot;;font-size:medium;text-align:justify">. =E2=80=94=C2=
=A0</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman=
&quot;;font-size:medium;text-align:justify">end note</em><span style=3D"col=
or:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;te=
xt-align:justify">]</span><br></div><div><span style=3D"color:rgb(0,160,0);=
font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify=
"><br></span></div><div>Similar in the disjunction:=C2=A0</div><div><span s=
tyle=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-siz=
e:medium;text-align:justify">The BaseCharacteristic of a specialization=C2=
=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">disjunction=
&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0);font-family:&qu=
ot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0is the =
first type=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify=
">Bi</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0in the list=C2=A0</spa=
n><code style=3D"color:rgb(0,160,0);text-align:justify">false_type, B1, ...=
, BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0for which=C2=A0</span>=
<code style=3D"color:rgb(0,160,0);text-align:justify">Bi::value !=3D false<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">, or if every=C2=A0</span><code s=
tyle=3D"color:rgb(0,160,0);text-align:justify">Bi::value =3D=3D false</code=
><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;=
font-size:medium;text-align:justify">=C2=A0the BaseCharacteristic is=C2=A0<=
/span><code style=3D"color:rgb(0,160,0);text-align:justify">BN</code><span =
style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-si=
ze:medium;text-align:justify">. [</span><em style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">N=
ote:</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roma=
n&quot;;font-size:medium;text-align:justify">=C2=A0This means a specializat=
ion of=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">di=
sjunction</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times N=
ew Roman&quot;;font-size:medium;text-align:justify">=C2=A0does not necessar=
ily have a BaseCharacteristic of either=C2=A0</span><code style=3D"color:rg=
b(0,160,0);text-align:justify">true_type</code><span style=3D"color:rgb(0,1=
60,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:j=
ustify">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:j=
ustify">false_type</code><span style=3D"color:rgb(0,160,0);font-family:&quo=
t;Times New Roman&quot;;font-size:medium;text-align:justify">. =E2=80=94=C2=
=A0</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman=
&quot;;font-size:medium;text-align:justify">end note</em><span style=3D"col=
or:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;te=
xt-align:justify">]</span><br></div><div><br></div><div>I&#39;d like to pro=
pose a two new structures in `&lt;type_traits&gt;`: `std::greedy_conjunctio=
n` and `std::greedy_disjunction`. Their results would very similar to the o=
nes from `std::conjunciton` and `std::disjunction`, but their specification=
 would give more flexibility to the standard library creators.</div><div><b=
r></div><div><br></div><div><b><font size=3D"4">Motivation and Scope</font>=
</b></div><div><br></div><div>With `std::conjuction` and `std::disjunction`=
 restrictions in the standard, library creators are forced to make them in =
such (or similar) way:</div><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">template</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span =
style=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">struct</span><span style=3D"color:#000"> conjunction =
</span><span style=3D"color:#660">:</span><span style=3D"color:#000"> std</=
span><span style=3D"color:#660">::</span><span style=3D"color:#000">true_ty=
pe </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></s=
pan><span style=3D"color:#008">template</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">class</span><span style=3D"color:#000">=
 B1</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 conjunction</span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#000">B1</span><span style=3D"color:#660">&gt;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">:</span><span style=3D"color:#00=
0"> B1 </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=
></span><span style=3D"color:#008">template</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#0=
00"> B1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">class</span><span style=3D"color:#660">=
....</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Bn<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> =
conjunction</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#000">B1</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">=
....&gt;</span><span style=3D"color:#000"> <br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">conditional_t</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">B1</span><span=
 style=3D"color:#660">::</span><span style=3D"color:#000">value</span><span=
 style=3D"color:#660">),</span><span style=3D"color:#000"> conjunction</spa=
n><span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Bn</span=
><span style=3D"color:#660">...&gt;,</span><span style=3D"color:#000"> B1</=
span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">{};</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 <br></span><span style=3D"color:#008">template</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span sty=
le=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">struct</span><span style=3D"color:#000"> disjunction </s=
pan><span style=3D"color:#660">:</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">false_type=
 </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">class</span><span style=3D"color:#000"> B=
1</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> d=
isjunction</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#000">B1</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">:</span><span style=3D"color:#000"=
> B1 </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><=
/span><span style=3D"color:#008">template</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000=
"> B1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">class</span><span style=3D"color:#660">..=
..</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Bn</s=
pan><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> di=
sjunction</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">B1</span><span style=3D"color:#660">,</span><span style=3D"color:#000=
"> </span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">..=
..&gt;</span><span style=3D"color:#000"> <br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">conditional_t</span><sp=
an style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">B1</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">value</span><span =
style=3D"color:#660">),</span><span style=3D"color:#000"> B1</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> disjunction</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#606">Bn</span><sp=
an style=3D"color:#660">...&gt;&gt;</span><span style=3D"color:#000"> =C2=
=A0</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><br=
></span></div></code></div><div><br>=C2=A0 =C2=A0=C2=A0</div><div>There are=
 strong grounds to keep these implementations, e.g. short-circuiting, getti=
ng information on what type, recursion stopped etc. Although, because of th=
ese restrictions compilation time suffers in some cases.</div><div><br></di=
v><div><b><font size=3D"4">Why new,=C2=A0<u>very similar</u> traits?</font>=
</b></div><div><b>Abstract</b></div><div>During my pull request to folly (<=
a href=3D"https://github.com/facebook/folly/pull/643" rel=3D"nofollow" targ=
et=3D"_blank">https://github.com/facebook/folly/pull/643</a>) Jay Feldblum =
posted there a small benchmark script: <a href=3D"https://gist.github.com/y=
feldblum/ffae5374aaaa11b03f08919d25b1555b" rel=3D"nofollow" target=3D"_blan=
k">https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b</a>=
=C2=A0(big credits for poking my brain with the idea). I was surprised that=
, let&#39;s say, the naive implementation compiles faster that the standard=
 one.=C2=A0</div><div><br></div><div>I decided to benchmark this idea deepe=
r:</div><div>-problem was to find in a types sequence if there is a type wh=
ich T::value is equal to 0</div><div>-for every benchmark sequence has 1024=
 types inside</div><div>-tested sequences with two kinds of types: light an=
d heavy to instantiate</div><div>-tested best and worse cases</div><div>-te=
sted two new implementations: fold expression and bool-pack</div><div>-core=
 benchmark was to measure the compilation time with given compiler (clang++=
-4.0/g++-6), case (best/worse), type (light/heavy), implementation (propose=
d/standard). Every compilation case was ran 500 times and average result wa=
s calculated.</div><div><br></div><div>Whole benchmarks code you can find i=
n the gh repo:=C2=A0<a href=3D"https://github.com/stryku/boolpack_vs_recurs=
ion" rel=3D"nofollow" target=3D"_blank">https://github.com/stryku/boolpack_=
vs_recursion</a></div><div><br></div><div>And here are the results (sorry f=
or not posting it here, but table was too big and it was formatted in unrea=
dable way):</div><div><a href=3D"https://raw.githubusercontent.com/stryku/b=
oolpack_vs_recursion/master/output" rel=3D"nofollow" target=3D"_blank">http=
s://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master/output</a=
></div><div><br></div><div>As you can see, standard implementation is way b=
etter when we deal with the best case. It can compile 80x(!) faster than th=
e proposed ones. Problem starts when the worse cases occurs.=C2=A0</div><di=
v>Standard library creators would be able to implement `greedy_conjunction`=
 and `greedy_disjunction` in a way that they compiles up to around 6x faste=
r than the standard one. Users would be able choose implementation which wi=
ll suit best, based on what cases they are mostly expecting.</div><div><br>=
</div><div><font size=3D"4"><b>Specification</b></font></div><div>Since it&=
#39;s a pre-proposal I don&#39;t want to post fully described specification=
.. I&#39;m thinking about it in this way:</div><div><br></div><div>`std::gre=
edy_conjunction` would be an alias or would derive from a type, which has a=
 constexpr member `value` which can be converted to bool and is equal to:</=
div><div>-false if any bool(Tn::value0 =3D=3D false</div><div>-true otherwi=
se</div><div><br></div><div><div>`std::greedy_disjunction` would be an alia=
s or would derive from a type, which has a constexpr member `value` which c=
an be converted to bool and is equal to:</div><div>-false if all bool(Tn::v=
alue) =3D=3D false</div><div>-true otherwise</div></div><div><br></div><div=
><font size=3D"4"><b>Example implementations</b></font></div><div>bool-pack=
 (this one seems to compile faster than fold expression):</div><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:#008">template</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</span><span st=
yle=3D"color:#660">...</span><span style=3D"color:#000"> </span><span style=
=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">struct</span><span st=
yle=3D"color:#000"> __bools </span><span style=3D"color:#660">{};</span><sp=
an style=3D"color:#000"><br><br></span><span style=3D"color:#008">template<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#008">typename</span><span style=3D"color:#660">..=
..</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Tn</s=
pan><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br><=
/span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> g=
reedy_disjunction</span><span style=3D"color:#660">:</span><span style=3D"c=
olor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">negation</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">is_same</span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#000">__bools</span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">value</span><span style=3D"color:#660">)...&gt;,</span><=
span style=3D"color:#000"> __bools</span><span style=3D"color:#660">&lt;(</=
span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">value </span><span style=3D"color:#660">&amp;&=
amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">fa=
lse</span><span style=3D"color:#660">)...&gt;&gt;&gt;</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">{};</span><span style=3D"col=
or:#000"><br><br></span><span style=3D"color:#008">template</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><span sty=
le=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_conjuncti=
on</span><span style=3D"color:#660">:</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">is_sa=
me</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">_=
_bools</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#00=
8">bool</span><span style=3D"color:#660">(</span><span style=3D"color:#606"=
>Tn</span><span style=3D"color:#660">::</span><span style=3D"color:#000">va=
lue</span><span style=3D"color:#660">)...&gt;,</span><span style=3D"color:#=
000"> __bools</span><span style=3D"color:#660">&lt;(</span><span style=3D"c=
olor:#606">Tn</span><span style=3D"color:#660">::</span><span style=3D"colo=
r:#000">value </span><span style=3D"color:#660">||</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">true</span><span style=3D"color=
:#660">)...&gt;&gt;</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">{};</span><span style=3D"color:#000"><br></span></div></code><=
/div><div><br><br></div><div>fold expression:</div><div style=3D"background=
-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bo=
rder-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">=
template</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">typename</span><span style=3D"color=
:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Tn</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"> <br></span><span style=3D"color:#008">struct</span><span style=3D"color=
:#000"> greedy_disjunction </span><span style=3D"color:#660">:</span><span =
style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span s=
tyle=3D"color:#000">bool_constant</span><span style=3D"color:#660">&lt;(</s=
pan><span style=3D"color:#008">false</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">||</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">...</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">||</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">value</span><span style=3D"color:#660">))&gt;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{};</span><span styl=
e=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#008">typename</span><span style=3D"color:#660">...</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><sp=
an style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><=
span style=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_c=
onjunction </span><span style=3D"color:#660">:</span><span style=3D"color:#=
000"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#0=
00">bool_constant</span><span style=3D"color:#660">&lt;(</span><span style=
=3D"color:#008">true</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">...</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">value</span><span style=3D"color:#660">))&gt;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{};</span><span styl=
e=3D"color:#000"><br></span></div></code></div><div><br><br></div><div><fon=
t size=3D"4"><b>Wordings:</b></font></div><div><b>There is couple of questi=
ons</b></div><div>I asked them to myself a lot, during this pre-proposal.</=
div><div>-Is it in the C++ standard scope to care about how things will be =
implemented in standard library, even if the implementations will be not ef=
ficient on compile-time level?</div><div>-Should the standard be changed be=
cause of standard library compilation time?</div><div><br></div><div>And he=
re&#39;s my conclusion (and reason why I&#39;m writing this post).</div><di=
v>C++ standard purpose is not to specify a theoretical language. It&#39;s c=
reated to be used by a lot of people in the real world. Giving a choice to =
user between implementations which differs in a compile-time efficiency is =
same thing as to give a choice between containers e.g. `std::vector` and `s=
td::list`. In some cases one implementation is better, in others the other =
one.</div><div><br></div><div><b>And of course the name</b></div><div>I tho=
ught about `strict_*` (like it&#39;s in Facebook/folly lib) instead of `gre=
edy_*`, but I&#39;m sure that if this proposal is a thing community will pr=
opose better names.</div><div><br></div><div><br></div><div>What do you thi=
nk?</div><div><br></div><div>Mateusz (stryku) Janek</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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-proposa=
ls/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org</a>.<br>
</blockquote></div>
</blockquote></div></blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/81a6a1fa-a331-483e-8f4d-4184c661b106%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a331-=
483e-8f4d-4184c661b106%40isocpp.org</a>.<br>
</blockquote></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/CAPCFJdTA7pfnGu8uQ7FBu-qj%3DUCJuRO78G=
-CYovSz9gAxPNSmw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPCFJdTA7pfnGu=
8uQ7FBu-qj%3DUCJuRO78G-CYovSz9gAxPNSmw%40mail.gmail.com</a>.<br />

--001a114db740cc70910556eec3f3--

.


Author: shmitti.guardia@gmail.com
Date: Thu, 17 Aug 2017 03:02:56 -0700 (PDT)
Raw View
------=_Part_868_1660773175.1502964176680
Content-Type: multipart/alternative;
 boundary="----=_Part_869_151071870.1502964176681"

------=_Part_869_151071870.1502964176681
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Got it. Thank you!

W dniu czwartek, 17 sierpnia 2017 10:26:13 UTC+2 u=C5=BCytkownik Micha=C5=
=82 Dominiak=20
napisa=C5=82:
>
> What I meant is that you don't really need a specific trait.
>
> You can't obtain the result of std::{con,dis}junction directly, without=
=20
> using a layer of abstraction for the laziness.
>
> You can, however, obtain the result of the greedy operation directly - by=
=20
> just &&ing or ||ing the values of the traits you'd pass to this trait.=20
> Evaluation in templates is already eager that way, and it's no problem to=
=20
> && or || them together even in generic contexts, especially since we have=
=20
> fold expressions now.
>
> The reason for the traits that we have is laziness. If you don't need=20
> laziness, you don't need the trait.
>
> On Thu, Aug 17, 2017, 10:17 AM <mateusz...@gmail.com <javascript:>> wrote=
:
>
>> Hello again,
>> I am wondering if lack of response in this thread means that my idea has=
=20
>> been already rejected? If yes then could anyone explain why?
>>
>> I might be wrong but this is why I'm not convicted by the current=20
>> arguments:
>>
>> >You can already write your "greedy" things by just... deriving from=20
>> bool_constant directly (exactly like in your last snippet).
>> I assume that your point is that it's easy to implement by the user on=
=20
>> his own. I'm not convicted because there is a lot of stuff in the standa=
rd=20
>> library that are easy to implement, e.g. std::negation
>>
>> >Your thing doesn't seem to be very useful.
>> Not sure if I follow. If they are not useful =3D> std::conjunction and=
=20
>> disjunction are not as well (:
>> As you can see they compute almost same result as std::conjunction and=
=20
>> disjunction, plus they give a choice to the user about the compilation t=
ime.
>>
>> The only thing that concerns me here is if it's in the standard library=
=20
>> scope to care about the compilation time.
>>
>> Thanks in advance,
>> Mateusz Janek
>>
>> W dniu =C5=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkownik=20
>> mateusz...@gmail.com napisa=C5=82:
>>>
>>> These traits are as useful as current conjunction and disjunction are -=
=20
>>> they compute the same result, but additionally give user a choice about=
=20
>>> compilation time and IMO that's a useful addition.
>>>
>>> W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Micha=
=C5=82 Dominiak=20
>>> napisa=C5=82:
>>>>
>>>> You can already write your "greedy" things by just... deriving from=20
>>>> bool_constant directly (exactly like in your last snippet). You couldn=
't do=20
>>>> what the two traits are doing directly, and that's I believe is the on=
ly=20
>>>> justification of their existence. Your thing doesn't seem to be very u=
seful.
>>>>
>>>> On Wed, Aug 9, 2017 at 2:31 PM <mateusz...@gmail.com> wrote:
>>>>
>>>>> *Introduction*
>>>>>
>>>>> C++17 introduced besides the others two new structures in=20
>>>>> `<type_traits>` header: `std::conjuction` and `std::disjunction`. The=
y are=20
>>>>> very useful in metaprogramming, but standard has in some way forced t=
heir=20
>>>>> implementation.=20
>>>>> In p0013r1=20
>>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html=
> we=20
>>>>> can read:
>>>>> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> i=
s=20
>>>>> the first type Bi in the list true_type, B1, ..., BN for which Bi::va=
lue=20
>>>>> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristic=
 is BN.=20
>>>>> [*Note:* This means a specialization of conjunction does not=20
>>>>> necessarily have a BaseCharacteristic of either true_type or=20
>>>>> false_type. =E2=80=94 *end note*]
>>>>>
>>>>> Similar in the disjunction:=20
>>>>> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> i=
s=20
>>>>> the first type Bi in the list false_type, B1, ..., BN for which Bi::v=
alue=20
>>>>> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristic=
 is BN.=20
>>>>> [*Note:* This means a specialization of disjunction does not=20
>>>>> necessarily have a BaseCharacteristic of either true_type or=20
>>>>> false_type. =E2=80=94 *end note*]
>>>>>
>>>>> I'd like to propose a two new structures in `<type_traits>`:=20
>>>>> `std::greedy_conjunction` and `std::greedy_disjunction`. Their result=
s=20
>>>>> would very similar to the ones from `std::conjunciton` and=20
>>>>> `std::disjunction`, but their specification would give more flexibili=
ty to=20
>>>>> the standard library creators.
>>>>>
>>>>>
>>>>> *Motivation and Scope*
>>>>>
>>>>> With `std::conjuction` and `std::disjunction` restrictions in the=20
>>>>> standard, library creators are forced to make them in such (or simila=
r) way:
>>>>> template<class...> struct conjunction : std::true_type { };
>>>>> template<class B1> struct conjunction<B1> : B1 { };
>>>>> template<class B1, class... Bn>
>>>>> struct conjunction<B1, Bn...>=20
>>>>>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {};
>>>>>    =20
>>>>> template<class...> struct disjunction : std::false_type { };
>>>>> template<class B1> struct disjunction<B1> : B1 { };
>>>>> template<class B1, class... Bn>
>>>>> struct disjunction<B1, Bn...>=20
>>>>>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  {=
=20
>>>>> };
>>>>>
>>>>>
>>>>>    =20
>>>>> There are strong grounds to keep these implementations, e.g.=20
>>>>> short-circuiting, getting information on what type, recursion stopped=
 etc.=20
>>>>> Although, because of these restrictions compilation time suffers in s=
ome=20
>>>>> cases.
>>>>>
>>>>> *Why new, very similar traits?*
>>>>> *Abstract*
>>>>> During my pull request to folly (
>>>>> https://github.com/facebook/folly/pull/643) Jay Feldblum posted there=
=20
>>>>> a small benchmark script:=20
>>>>> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (b=
ig=20
>>>>> credits for poking my brain with the idea). I was surprised that, let=
's=20
>>>>> say, the naive implementation compiles faster that the standard one.=
=20
>>>>>
>>>>> I decided to benchmark this idea deeper:
>>>>> -problem was to find in a types sequence if there is a type which=20
>>>>> T::value is equal to 0
>>>>> -for every benchmark sequence has 1024 types inside
>>>>> -tested sequences with two kinds of types: light and heavy to=20
>>>>> instantiate
>>>>> -tested best and worse cases
>>>>> -tested two new implementations: fold expression and bool-pack
>>>>> -core benchmark was to measure the compilation time with given=20
>>>>> compiler (clang++-4.0/g++-6), case (best/worse), type (light/heavy),=
=20
>>>>> implementation (proposed/standard). Every compilation case was ran 50=
0=20
>>>>> times and average result was calculated.
>>>>>
>>>>> Whole benchmarks code you can find in the gh repo:=20
>>>>> https://github.com/stryku/boolpack_vs_recursion
>>>>>
>>>>> And here are the results (sorry for not posting it here, but table wa=
s=20
>>>>> too big and it was formatted in unreadable way):
>>>>>
>>>>> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/master=
/output
>>>>>
>>>>> As you can see, standard implementation is way better when we deal=20
>>>>> with the best case. It can compile 80x(!) faster than the proposed on=
es.=20
>>>>> Problem starts when the worse cases occurs.=20
>>>>> Standard library creators would be able to implement=20
>>>>> `greedy_conjunction` and `greedy_disjunction` in a way that they comp=
iles=20
>>>>> up to around 6x faster than the standard one. Users would be able cho=
ose=20
>>>>> implementation which will suit best, based on what cases they are mos=
tly=20
>>>>> expecting.
>>>>>
>>>>> *Specification*
>>>>> Since it's a pre-proposal I don't want to post fully described=20
>>>>> specification. I'm thinking about it in this way:
>>>>>
>>>>> `std::greedy_conjunction` would be an alias or would derive from a=20
>>>>> type, which has a constexpr member `value` which can be converted to =
bool=20
>>>>> and is equal to:
>>>>> -false if any bool(Tn::value0 =3D=3D false
>>>>> -true otherwise
>>>>>
>>>>> `std::greedy_disjunction` would be an alias or would derive from a=20
>>>>> type, which has a constexpr member `value` which can be converted to =
bool=20
>>>>> and is equal to:
>>>>> -false if all bool(Tn::value) =3D=3D false
>>>>> -true otherwise
>>>>>
>>>>> *Example implementations*
>>>>> bool-pack (this one seems to compile faster than fold expression):
>>>>> template <bool... Bn>
>>>>> struct __bools {};
>>>>>
>>>>> template <typename... Tn>=20
>>>>> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(Tn
>>>>> ::value)...>, __bools<(Tn::value && false)...>>> {};
>>>>>
>>>>> template <typename... Tn>=20
>>>>> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,=
=20
>>>>> __bools<(Tn::value || true)...>> {};
>>>>>
>>>>>
>>>>> fold expression:
>>>>> template <typename... Tn>=20
>>>>> struct greedy_disjunction : std::bool_constant<(false || ... || bool(
>>>>> Tn::value))> {};
>>>>>
>>>>> template <typename... Tn>=20
>>>>> struct greedy_conjunction : std::bool_constant<(true && ... && bool(T=
n
>>>>> ::value))> {};
>>>>>
>>>>>
>>>>> *Wordings:*
>>>>> *There is couple of questions*
>>>>> I asked them to myself a lot, during this pre-proposal.
>>>>> -Is it in the C++ standard scope to care about how things will be=20
>>>>> implemented in standard library, even if the implementations will be =
not=20
>>>>> efficient on compile-time level?
>>>>> -Should the standard be changed because of standard library=20
>>>>> compilation time?
>>>>>
>>>>> And here's my conclusion (and reason why I'm writing this post).
>>>>> C++ standard purpose is not to specify a theoretical language. It's=
=20
>>>>> created to be used by a lot of people in the real world. Giving a cho=
ice to=20
>>>>> user between implementations which differs in a compile-time efficien=
cy is=20
>>>>> same thing as to give a choice between containers e.g. `std::vector` =
and=20
>>>>> `std::list`. In some cases one implementation is better, in others th=
e=20
>>>>> other one.
>>>>>
>>>>> *And of course the name*
>>>>> I thought about `strict_*` (like it's in Facebook/folly lib) instead=
=20
>>>>> of `greedy_*`, but I'm sure that if this proposal is a thing communit=
y will=20
>>>>> propose better names.
>>>>>
>>>>>
>>>>> What do you think?
>>>>>
>>>>> Mateusz (stryku) Janek
>>>>>
>>>>> --=20
>>>>> You received this message because you are subscribed to the Google=20
>>>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, sen=
d=20
>>>>> an email to std-proposal...@isocpp.org.
>>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>>> To view this discussion on the web visit=20
>>>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b4=
-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org=20
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b=
4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=3D=
footer>
>>>>> .
>>>>>
>>>> --=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit=20
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a3=
31-483e-8f4d-4184c661b106%40isocpp.org=20
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a=
331-483e-8f4d-4184c661b106%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoo=
ter>
>> .
>>
>

--=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/12275369-dca3-40aa-b37c-93d60ffc3db8%40isocpp.or=
g.

------=_Part_869_151071870.1502964176681
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Got it. Thank you!<br><br>W dniu czwartek, 17 sierpnia 201=
7 10:26:13 UTC+2 u=C5=BCytkownik Micha=C5=82 Dominiak napisa=C5=82:<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><p dir=3D"ltr">What I meant is that yo=
u don&#39;t really need a specific trait.</p>
<p dir=3D"ltr">You can&#39;t obtain the result of std::{con,dis}junction di=
rectly, without using a layer of abstraction for the laziness.</p>
<p dir=3D"ltr">You can, however, obtain the result of the greedy operation =
directly - by just &amp;&amp;ing or ||ing the values of the traits you&#39;=
d pass to this trait. Evaluation in templates is already eager that way, an=
d it&#39;s no problem to &amp;&amp; or || them together even in generic con=
texts, especially since we have fold expressions now.</p>
<p dir=3D"ltr">The reason for the traits that we have is laziness. If you d=
on&#39;t need laziness, you don&#39;t need the trait.</p>
<br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 17, 2017, 10:17=
 AM  &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"942XN0vsCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:=
&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;">mateusz...@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div>Hello again,</div><div>I am wondering if lack of=
 response in this thread means that my idea has been already rejected? If y=
es then could anyone explain why?</div><div><br></div><div>I might be wrong=
 but this is why I&#39;m not convicted by the current arguments:</div></div=
><div dir=3D"ltr"><div><br></div><div>&gt;You can already write your &quot;=
greedy&quot; things by just... deriving from bool_constant directly (exactl=
y like in your last snippet).</div></div><div dir=3D"ltr"><div>I assume tha=
t your point is that it&#39;s easy to implement by the user on his own. I&#=
39;m not convicted because there is a lot of stuff in the standard library =
that are easy to implement, e.g. std::negation</div></div><div dir=3D"ltr">=
<div><br></div><div>&gt;Your thing doesn&#39;t seem to be very useful.</div=
></div><div dir=3D"ltr"><div>Not sure if I follow. If they are not useful =
=3D&gt; std::conjunction and disjunction are not as well (:</div><div>As yo=
u can see they compute almost same result as std::conjunction and disjuncti=
on, plus they give a choice to the user about the compilation time.</div><d=
iv><br></div><div>The only thing that concerns me here is if it&#39;s in th=
e standard library scope to care about the compilation time.</div><div><br>=
</div><div>Thanks in advance,</div><div>Mateusz Janek</div></div><div dir=
=3D"ltr"><br>W dniu =C5=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkow=
nik <a>mateusz...@gmail.com</a> napisa=C5=82:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr">These traits are as useful as current conjunctio=
n and disjunction are - they compute the same result, but additionally give=
 user a choice about compilation time and IMO that&#39;s a useful addition.=
<br><br>W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik M=
icha=C5=82 Dominiak napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr">You can already write your &quot;greedy&quot; things by just=
.... deriving from bool_constant directly (exactly like in your last snippet=
). You couldn&#39;t do what the two traits are doing directly, and that&#39=
;s I believe is the only justification of their existence. Your thing doesn=
&#39;t seem to be very useful.</div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Wed, Aug 9, 2017 at 2:31 PM &lt;<a rel=3D"nofollow">mateusz...@=
gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><b><font size=3D"4">Introduction</font></b></div><div><br></d=
iv><div>C++17 introduced besides the others two new structures in `&lt;type=
_traits&gt;` header: `std::conjuction` and `std::disjunction`. They are ver=
y useful in metaprogramming, but standard has in some way forced their impl=
ementation.=C2=A0</div><div>In <a href=3D"http://www.open-std.org/jtc1/sc22=
/wg21/docs/papers/2015/p0013r1.html" rel=3D"nofollow" target=3D"_blank" onm=
ousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fww=
w.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp0013r1.html\x=
26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHrhD3oGJRVXphYJvzGExp6I3jexQ&#39;;re=
turn true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp=
%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2015%2Fp00=
13r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHrhD3oGJRVXphYJvzGExp6I3j=
exQ&#39;;return true;">p0013r1</a>=C2=A0we can read:</div><div><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">The BaseCharacteristic of a specialization=C2=A0</=
span><code style=3D"color:rgb(0,160,0);text-align:justify">conjunction&lt;B=
1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Ti=
mes New Roman&quot;;font-size:medium;text-align:justify">=C2=A0is the first=
 type=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">=C2=A0in the list=C2=A0</span><co=
de style=3D"color:rgb(0,160,0);text-align:justify">true_type, B1, ..., BN</=
code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&qu=
ot;;font-size:medium;text-align:justify">=C2=A0for which=C2=A0</span><code =
style=3D"color:rgb(0,160,0);text-align:justify">Bi::value =3D=3D false</cod=
e><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;=
;font-size:medium;text-align:justify">, or if every=C2=A0</span><code style=
=3D"color:rgb(0,160,0);text-align:justify">Bi::value !=3D false</code><span=
 style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-s=
ize:medium;text-align:justify">=C2=A0the BaseCharacteristic is=C2=A0</span>=
<code style=3D"color:rgb(0,160,0);text-align:justify">BN</code><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">. [</span><em style=3D"color:rgb(0,160,0);font-fam=
ily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">Note:<=
/em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quo=
t;;font-size:medium;text-align:justify">=C2=A0This means a specialization o=
f=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">conjunc=
tion</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0does not necessarily h=
ave a BaseCharacteristic of either=C2=A0</span><code style=3D"color:rgb(0,1=
60,0);text-align:justify">true_type</code><span style=3D"color:rgb(0,160,0)=
;font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justif=
y">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justif=
y">false_type</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Tim=
es New Roman&quot;;font-size:medium;text-align:justify"><wbr>. =E2=80=94=C2=
=A0</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman=
&quot;;font-size:medium;text-align:justify">end note</em><span style=3D"col=
or:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;te=
xt-align:justify">]</span><br></div><div><span style=3D"color:rgb(0,160,0);=
font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify=
"><br></span></div><div>Similar in the disjunction:=C2=A0</div><div><span s=
tyle=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-siz=
e:medium;text-align:justify">The BaseCharacteristic of a specialization=C2=
=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">disjunction=
&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0);font-family:&qu=
ot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0is the =
first type=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify=
">Bi</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0in the list=C2=A0</spa=
n><code style=3D"color:rgb(0,160,0);text-align:justify">false_type, B1, ...=
, BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">=C2=A0for which=C2=A0</span>=
<code style=3D"color:rgb(0,160,0);text-align:justify">Bi::value !=3D false<=
/code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&q=
uot;;font-size:medium;text-align:justify">, or if every=C2=A0</span><code s=
tyle=3D"color:rgb(0,160,0);text-align:justify">Bi::value =3D=3D false</code=
><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;=
font-size:medium;text-align:justify">=C2=A0the BaseCharacteristic is=C2=A0<=
/span><code style=3D"color:rgb(0,160,0);text-align:justify">BN</code><span =
style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-si=
ze:medium;text-align:justify">. [</span><em style=3D"color:rgb(0,160,0);fon=
t-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">N=
ote:</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roma=
n&quot;;font-size:medium;text-align:justify">=C2=A0This means a specializat=
ion of=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">di=
sjunction</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times N=
ew Roman&quot;;font-size:medium;text-align:justify">=C2=A0does not necessar=
ily have a BaseCharacteristic of either=C2=A0</span><code style=3D"color:rg=
b(0,160,0);text-align:justify">true_type</code><span style=3D"color:rgb(0,1=
60,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:j=
ustify">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:j=
ustify">false_type</code><span style=3D"color:rgb(0,160,0);font-family:&quo=
t;Times New Roman&quot;;font-size:medium;text-align:justify"><wbr>. =E2=80=
=94=C2=A0</span><em style=3D"color:rgb(0,160,0);font-family:&quot;Times New=
 Roman&quot;;font-size:medium;text-align:justify">end note</em><span style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">]</span><br></div><div><br></div><div>I&#39;d like=
 to propose a two new structures in `&lt;type_traits&gt;`: `std::greedy_con=
junction` and `std::greedy_disjunction`. Their results would very similar t=
o the ones from `std::conjunciton` and `std::disjunction`, but their specif=
ication would give more flexibility to the standard library creators.</div>=
<div><br></div><div><br></div><div><b><font size=3D"4">Motivation and Scope=
</font></b></div><div><br></div><div>With `std::conjuction` and `std::disju=
nction` restrictions in the standard, library creators are forced to make t=
hem in such (or similar) way:</div><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-wrap:break-word"><code><div><span style=3D"color:#008">template</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span=
><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">struct</span><span style=3D"color:#000"> conju=
nction </span><span style=3D"color:#660">:</span><span style=3D"color:#000"=
> std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">=
true_type </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></span><span style=3D"color:#008">template</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color=
:#000"> B1</span><span style=3D"color:#660">&gt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">struct</span><span style=3D"color=
:#000"> conjunction</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#000">B1</span><span style=3D"color:#660">&gt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D"c=
olor:#000"> B1 </span><span style=3D"color:#660">{</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#=
000"><br></span><span style=3D"color:#008">template</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"=
color:#000"> B1</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#008">class</span><span style=3D"colo=
r:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color:#=
606">Bn</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#008">struct</span><span style=3D"color=
:#000"> conjunction</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#000">B1</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#606">Bn</span><span style=3D"colo=
r:#660">...&gt;</span><span style=3D"color:#000"> <br>=C2=A0 =C2=A0 </span>=
<span style=3D"color:#660">:</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">conditional_t<=
/span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">B1</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#000">va<wbr>lu=
e</span><span style=3D"color:#660">),</span><span style=3D"color:#000"> con=
junction</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
606">Bn</span><span style=3D"color:#660">...&gt;,</span><span style=3D"colo=
r:#000"> B1</span><span style=3D"color:#660">&gt;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{};</span><span style=3D"color:#=
000"><br>=C2=A0 =C2=A0 <br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</sp=
an><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">struct</span><span style=3D"color:#000"> dis=
junction </span><span style=3D"color:#660">:</span><span style=3D"color:#00=
0"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">false_type </span><span style=3D"color:#660">{</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">template</span><span style=3D"colo=
r:#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"co=
lor:#000"> B1</span><span style=3D"color:#660">&gt;</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">struct</span><span style=3D"co=
lor:#000"> disjunction</span><span style=3D"color:#660">&lt;</span><span st=
yle=3D"color:#000">B1</span><span style=3D"color:#660">&gt;</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D=
"color:#000"> B1 </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#008">template</span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> B1</span><span style=3D"color:#660">,</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">class</span><span style=3D"=
color:#660">...</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#606">Bn</span><span style=3D"color:#660">&gt;</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">struct</span><span style=3D"c=
olor:#000"> disjunction</span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#000">B1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Bn</span><span style=3D"=
color:#660">...&gt;</span><span style=3D"color:#000"> <br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:#660">:</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">conditiona=
l_t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
bool</span><span style=3D"color:#660">(</span><span style=3D"color:#000">B1=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">va<wb=
r>lue</span><span style=3D"color:#660">),</span><span style=3D"color:#000">=
 B1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> di=
sjunction</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Bn</span><span style=3D"color:#660">...&gt;&gt;</span><span style=3D"=
color:#000"> =C2=A0</span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br><br></span></div></code></div><div><br>=C2=A0 =C2=A0=C2=A0</di=
v><div>There are strong grounds to keep these implementations, e.g. short-c=
ircuiting, getting information on what type, recursion stopped etc. Althoug=
h, because of these restrictions compilation time suffers in some cases.</d=
iv><div><br></div><div><b><font size=3D"4">Why new,=C2=A0<u>very similar</u=
> traits?</font></b></div><div><b>Abstract</b></div><div>During my pull req=
uest to folly (<a href=3D"https://github.com/facebook/folly/pull/643" rel=
=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffacebook%2Ffolly%2Fpull%2F6=
43\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzRzYUaerIKsE3rogxWBbtocbw&#39=
;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3=
dhttps%3A%2F%2Fgithub.com%2Ffacebook%2Ffolly%2Fpull%2F643\x26sa\x3dD\x26snt=
z\x3d1\x26usg\x3dAFQjCNFmOzRzYUaerIKsE3rogxWBbtocbw&#39;;return true;">http=
s://github.com/facebook/<wbr>folly/pull/643</a>) Jay Feldblum posted there =
a small benchmark script: <a href=3D"https://gist.github.com/yfeldblum/ffae=
5374aaaa11b03f08919d25b1555b" rel=3D"nofollow" target=3D"_blank" onmousedow=
n=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgist.gi=
thub.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1555b\x26sa\x3dD\x26sntz\=
x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#39;;return true;" onclic=
k=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgist.gi=
thub.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1555b\x26sa\x3dD\x26sntz\=
x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#39;;return true;">https:=
//gist.github.com/<wbr>yfeldblum/<wbr>ffae5374aaaa11b03f08919d25b155<wbr>5b=
</a>=C2=A0(big credits for poking my brain with the idea). I was surprised =
that, let&#39;s say, the naive implementation compiles faster that the stan=
dard one.=C2=A0</div><div><br></div><div>I decided to benchmark this idea d=
eeper:</div><div>-problem was to find in a types sequence if there is a typ=
e which T::value is equal to 0</div><div>-for every benchmark sequence has =
1024 types inside</div><div>-tested sequences with two kinds of types: ligh=
t and heavy to instantiate</div><div>-tested best and worse cases</div><div=
>-tested two new implementations: fold expression and bool-pack</div><div>-=
core benchmark was to measure the compilation time with given compiler (cla=
ng++-4.0/g++-6), case (best/worse), type (light/heavy), implementation (pro=
posed/standard). Every compilation case was ran 500 times and average resul=
t was calculated.</div><div><br></div><div>Whole benchmarks code you can fi=
nd in the gh repo:=C2=A0<a href=3D"https://github.com/stryku/boolpack_vs_re=
cursion" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39=
;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fstryku%2Fboolpa=
ck_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHICyJnr6jjlrCVLCKQE=
rJdqh0rLg&#39;;return true;" onclick=3D"this.href=3D&#39;https://www.google=
..com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fstryku%2Fboolpack_vs_recursion\x26=
sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHICyJnr6jjlrCVLCKQErJdqh0rLg&#39;;retu=
rn true;">https://github.com/<wbr>stryku/boolpack_vs_recursion</a></div><di=
v><br></div><div>And here are the results (sorry for not posting it here, b=
ut table was too big and it was formatted in unreadable way):</div><div><a =
href=3D"https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/mast=
er/output" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#=
39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fraw.githubusercontent.com%=
2Fstryku%2Fboolpack_vs_recursion%2Fmaster%2Foutput\x26sa\x3dD\x26sntz\x3d1\=
x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08KY4FDz5dQ&#39;;return true;" onclick=3D"=
this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fraw.githubus=
ercontent.com%2Fstryku%2Fboolpack_vs_recursion%2Fmaster%2Foutput\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08KY4FDz5dQ&#39;;return true=
;">https://raw.githubusercontent.<wbr>com/stryku/boolpack_vs_<wbr>recursion=
/master/output</a></div><div><br></div><div>As you can see, standard implem=
entation is way better when we deal with the best case. It can compile 80x(=
!) faster than the proposed ones. Problem starts when the worse cases occur=
s.=C2=A0</div><div>Standard library creators would be able to implement `gr=
eedy_conjunction` and `greedy_disjunction` in a way that they compiles up t=
o around 6x faster than the standard one. Users would be able choose implem=
entation which will suit best, based on what cases they are mostly expectin=
g.</div><div><br></div><div><font size=3D"4"><b>Specification</b></font></d=
iv><div>Since it&#39;s a pre-proposal I don&#39;t want to post fully descri=
bed specification. I&#39;m thinking about it in this way:</div><div><br></d=
iv><div>`std::greedy_conjunction` would be an alias or would derive from a =
type, which has a constexpr member `value` which can be converted to bool a=
nd is equal to:</div><div>-false if any bool(Tn::value0 =3D=3D false</div><=
div>-true otherwise</div><div><br></div><div><div>`std::greedy_disjunction`=
 would be an alias or would derive from a type, which has a constexpr membe=
r `value` which can be converted to bool and is equal to:</div><div>-false =
if all bool(Tn::value) =3D=3D false</div><div>-true otherwise</div></div><d=
iv><br></div><div><font size=3D"4"><b>Example implementations</b></font></d=
iv><div>bool-pack (this one seems to compile faster than fold expression):<=
/div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</=
span><span style=3D"color:#660">...</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct</s=
pan><span style=3D"color:#000"> __bools </span><span style=3D"color:#660">{=
};</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">typename</span><span style=3D"co=
lor:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color=
:#606">Tn</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> <br></span><span style=3D"color:#008">struct</span><span style=3D"co=
lor:#000"> greedy_disjunction</span><span style=3D"color:#660">:</span><spa=
n style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span=
 style=3D"color:#000">negation</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#000">std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">is_same</span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#000">__<wbr>bools</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#008">bool</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">::<=
/span><span style=3D"color:#000">value</span><span style=3D"color:#660">)..=
..&gt;,</span><span style=3D"color:#000"> __bools</span><span style=3D"color=
:#660">&lt;(</span><span style=3D"color:#606">Tn</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">value </span><span style=3D"colo=
r:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">false</span><span style=3D"color:#660">)...&gt;&gt;&gt;</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{};</span><spa=
n style=3D"color:#000"><br><br></span><span style=3D"color:#008">template</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#008">typename</span><span style=3D"color:#660">...=
</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Tn</sp=
an><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></=
span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> gr=
eedy_conjunction</span><span style=3D"color:#660">:</span><span style=3D"co=
lor:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">is_same</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#000">__bools</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span style=
=3D"color:#606">Tn</span><span style=3D"color:#660">::</span><span style=3D=
"color:#000"><wbr>value</span><span style=3D"color:#660">)...&gt;,</span><s=
pan style=3D"color:#000"> __bools</span><span style=3D"color:#660">&lt;(</s=
pan><span style=3D"color:#606">Tn</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">value </span><span style=3D"color:#660">||</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">true</span>=
<span style=3D"color:#660">)...&gt;&gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{};</span><span style=3D"color:#000"><br><=
/span></div></code></div><div><br><br></div><div>fold expression:</div><div=
 style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px;word-wrap:break-word"><code><div><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span>=
<span style=3D"color:#660">...</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Tn</span><span style=3D"color:#660">&gt;</span><spa=
n style=3D"color:#000"> <br></span><span style=3D"color:#008">struct</span>=
<span style=3D"color:#000"> greedy_disjunction </span><span style=3D"color:=
#660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">bool_constant</span><span style=3D"=
color:#660">&lt;(</span><span style=3D"color:#008">false</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">||</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">...</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">||</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">bool</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">:=
:</span><span style=3D"color:#000">value</span><span style=3D"color:#660">)=
)&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
};</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">typename</span><span style=3D"co=
lor:#660">...</span><span style=3D"color:#000"> </span><span style=3D"color=
:#606">Tn</span><span style=3D"color:#660">&gt;</span><span style=3D"color:=
#000"> <br></span><span style=3D"color:#008">struct</span><span style=3D"co=
lor:#000"> greedy_conjunction </span><span style=3D"color:#660">:</span><sp=
an style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">bool_constant</span><span style=3D"color:#660">&lt;(=
</span><span style=3D"color:#008">true</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">bool</span><span style=3D"color:#660">=
(</span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">::</=
span><span style=3D"color:#000">value</span><span style=3D"color:#660">))&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{};<=
/span><span style=3D"color:#000"><br></span></div></code></div><div><br><br=
></div><div><font size=3D"4"><b>Wordings:</b></font></div><div><b>There is =
couple of questions</b></div><div>I asked them to myself a lot, during this=
 pre-proposal.</div><div>-Is it in the C++ standard scope to care about how=
 things will be implemented in standard library, even if the implementation=
s will be not efficient on compile-time level?</div><div>-Should the standa=
rd be changed because of standard library compilation time?</div><div><br><=
/div><div>And here&#39;s my conclusion (and reason why I&#39;m writing this=
 post).</div><div>C++ standard purpose is not to specify a theoretical lang=
uage. It&#39;s created to be used by a lot of people in the real world. Giv=
ing a choice to user between implementations which differs in a compile-tim=
e efficiency is same thing as to give a choice between containers e.g. `std=
::vector` and `std::list`. In some cases one implementation is better, in o=
thers the other one.</div><div><br></div><div><b>And of course the name</b>=
</div><div>I thought about `strict_*` (like it&#39;s in Facebook/folly lib)=
 instead of `greedy_*`, but I&#39;m sure that if this proposal is a thing c=
ommunity will propose better names.</div><div><br></div><div><br></div><div=
>What do you think?</div><div><br></div><div>Mateusz (stryku) Janek</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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/a79ce0b4-ca2d-4c37-<wbr>b49e-=
cb707689a0e2%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></div></blockquote></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"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
942XN0vsCQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"942XN0vsCQAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@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/81a6a1fa-a331-483e-8f4d-4184c661b106%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a331-483e-8f4d-4184c661b106%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/81a6a1fa-a331-483e-8f4d-4184c661b106%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/81a6a1fa-a331-483e-<wbr>8f4d-=
4184c661b106%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></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/12275369-dca3-40aa-b37c-93d60ffc3db8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/12275369-dca3-40aa-b37c-93d60ffc3db8=
%40isocpp.org</a>.<br />

------=_Part_869_151071870.1502964176681--

------=_Part_868_1660773175.1502964176680--

.


Author: mateusz.janek6@gmail.com
Date: Sat, 19 Aug 2017 14:25:23 -0700 (PDT)
Raw View
------=_Part_1332_1167394811.1503177923293
Content-Type: multipart/alternative;
 boundary="----=_Part_1333_1665635495.1503177923295"

------=_Part_1333_1665635495.1503177923295
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Sorry, didn't realize that I was on wrong account.

W dniu czwartek, 17 sierpnia 2017 12:02:56 UTC+2 u=C5=BCytkownik=20
shmitti...@gmail.com napisa=C5=82:
>
> Got it. Thank you!
>
> W dniu czwartek, 17 sierpnia 2017 10:26:13 UTC+2 u=C5=BCytkownik Micha=C5=
=82=20
> Dominiak napisa=C5=82:
>>
>> What I meant is that you don't really need a specific trait.
>>
>> You can't obtain the result of std::{con,dis}junction directly, without=
=20
>> using a layer of abstraction for the laziness.
>>
>> You can, however, obtain the result of the greedy operation directly - b=
y=20
>> just &&ing or ||ing the values of the traits you'd pass to this trait.=
=20
>> Evaluation in templates is already eager that way, and it's no problem t=
o=20
>> && or || them together even in generic contexts, especially since we hav=
e=20
>> fold expressions now.
>>
>> The reason for the traits that we have is laziness. If you don't need=20
>> laziness, you don't need the trait.
>>
>> On Thu, Aug 17, 2017, 10:17 AM <mateusz...@gmail.com> wrote:
>>
>>> Hello again,
>>> I am wondering if lack of response in this thread means that my idea ha=
s=20
>>> been already rejected? If yes then could anyone explain why?
>>>
>>> I might be wrong but this is why I'm not convicted by the current=20
>>> arguments:
>>>
>>> >You can already write your "greedy" things by just... deriving from=20
>>> bool_constant directly (exactly like in your last snippet).
>>> I assume that your point is that it's easy to implement by the user on=
=20
>>> his own. I'm not convicted because there is a lot of stuff in the stand=
ard=20
>>> library that are easy to implement, e.g. std::negation
>>>
>>> >Your thing doesn't seem to be very useful.
>>> Not sure if I follow. If they are not useful =3D> std::conjunction and=
=20
>>> disjunction are not as well (:
>>> As you can see they compute almost same result as std::conjunction and=
=20
>>> disjunction, plus they give a choice to the user about the compilation =
time.
>>>
>>> The only thing that concerns me here is if it's in the standard library=
=20
>>> scope to care about the compilation time.
>>>
>>> Thanks in advance,
>>> Mateusz Janek
>>>
>>> W dniu =C5=9Broda, 9 sierpnia 2017 23:22:53 UTC+2 u=C5=BCytkownik=20
>>> mateusz...@gmail.com napisa=C5=82:
>>>>
>>>> These traits are as useful as current conjunction and disjunction are =
-=20
>>>> they compute the same result, but additionally give user a choice abou=
t=20
>>>> compilation time and IMO that's a useful addition.
>>>>
>>>> W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 UTC+2 u=C5=BCytkownik Mich=
a=C5=82 Dominiak=20
>>>> napisa=C5=82:
>>>>>
>>>>> You can already write your "greedy" things by just... deriving from=
=20
>>>>> bool_constant directly (exactly like in your last snippet). You could=
n't do=20
>>>>> what the two traits are doing directly, and that's I believe is the o=
nly=20
>>>>> justification of their existence. Your thing doesn't seem to be very =
useful.
>>>>>
>>>>> On Wed, Aug 9, 2017 at 2:31 PM <mateusz...@gmail.com> wrote:
>>>>>
>>>>>> *Introduction*
>>>>>>
>>>>>> C++17 introduced besides the others two new structures in=20
>>>>>> `<type_traits>` header: `std::conjuction` and `std::disjunction`. Th=
ey are=20
>>>>>> very useful in metaprogramming, but standard has in some way forced =
their=20
>>>>>> implementation.=20
>>>>>> In p0013r1=20
>>>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.htm=
l> we=20
>>>>>> can read:
>>>>>> The BaseCharacteristic of a specialization conjunction<B1, ..., BN> =
is=20
>>>>>> the first type Bi in the list true_type, B1, ..., BN for which Bi::v=
alue=20
>>>>>> =3D=3D false, or if every Bi::value !=3D false the BaseCharacteristi=
c is BN.=20
>>>>>> [*Note:* This means a specialization of conjunction does not=20
>>>>>> necessarily have a BaseCharacteristic of either true_type or=20
>>>>>> false_type. =E2=80=94 *end note*]
>>>>>>
>>>>>> Similar in the disjunction:=20
>>>>>> The BaseCharacteristic of a specialization disjunction<B1, ..., BN> =
is=20
>>>>>> the first type Bi in the list false_type, B1, ..., BN for which Bi::=
value=20
>>>>>> !=3D false, or if every Bi::value =3D=3D false the BaseCharacteristi=
c is BN.=20
>>>>>> [*Note:* This means a specialization of disjunction does not=20
>>>>>> necessarily have a BaseCharacteristic of either true_type or=20
>>>>>> false_type. =E2=80=94 *end note*]
>>>>>>
>>>>>> I'd like to propose a two new structures in `<type_traits>`:=20
>>>>>> `std::greedy_conjunction` and `std::greedy_disjunction`. Their resul=
ts=20
>>>>>> would very similar to the ones from `std::conjunciton` and=20
>>>>>> `std::disjunction`, but their specification would give more flexibil=
ity to=20
>>>>>> the standard library creators.
>>>>>>
>>>>>>
>>>>>> *Motivation and Scope*
>>>>>>
>>>>>> With `std::conjuction` and `std::disjunction` restrictions in the=20
>>>>>> standard, library creators are forced to make them in such (or simil=
ar) way:
>>>>>> template<class...> struct conjunction : std::true_type { };
>>>>>> template<class B1> struct conjunction<B1> : B1 { };
>>>>>> template<class B1, class... Bn>
>>>>>> struct conjunction<B1, Bn...>=20
>>>>>>     : std::conditional_t<bool(B1::value), conjunction<Bn...>, B1> {}=
;
>>>>>>    =20
>>>>>> template<class...> struct disjunction : std::false_type { };
>>>>>> template<class B1> struct disjunction<B1> : B1 { };
>>>>>> template<class B1, class... Bn>
>>>>>> struct disjunction<B1, Bn...>=20
>>>>>>     : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  {=
=20
>>>>>> };
>>>>>>
>>>>>>
>>>>>>    =20
>>>>>> There are strong grounds to keep these implementations, e.g.=20
>>>>>> short-circuiting, getting information on what type, recursion stoppe=
d etc.=20
>>>>>> Although, because of these restrictions compilation time suffers in =
some=20
>>>>>> cases.
>>>>>>
>>>>>> *Why new, very similar traits?*
>>>>>> *Abstract*
>>>>>> During my pull request to folly (
>>>>>> https://github.com/facebook/folly/pull/643) Jay Feldblum posted=20
>>>>>> there a small benchmark script:=20
>>>>>> https://gist.github.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b (=
big=20
>>>>>> credits for poking my brain with the idea). I was surprised that, le=
t's=20
>>>>>> say, the naive implementation compiles faster that the standard one.=
=20
>>>>>>
>>>>>> I decided to benchmark this idea deeper:
>>>>>> -problem was to find in a types sequence if there is a type which=20
>>>>>> T::value is equal to 0
>>>>>> -for every benchmark sequence has 1024 types inside
>>>>>> -tested sequences with two kinds of types: light and heavy to=20
>>>>>> instantiate
>>>>>> -tested best and worse cases
>>>>>> -tested two new implementations: fold expression and bool-pack
>>>>>> -core benchmark was to measure the compilation time with given=20
>>>>>> compiler (clang++-4.0/g++-6), case (best/worse), type (light/heavy),=
=20
>>>>>> implementation (proposed/standard). Every compilation case was ran 5=
00=20
>>>>>> times and average result was calculated.
>>>>>>
>>>>>> Whole benchmarks code you can find in the gh repo:=20
>>>>>> https://github.com/stryku/boolpack_vs_recursion
>>>>>>
>>>>>> And here are the results (sorry for not posting it here, but table=
=20
>>>>>> was too big and it was formatted in unreadable way):
>>>>>>
>>>>>> https://raw.githubusercontent.com/stryku/boolpack_vs_recursion/maste=
r/output
>>>>>>
>>>>>> As you can see, standard implementation is way better when we deal=
=20
>>>>>> with the best case. It can compile 80x(!) faster than the proposed o=
nes.=20
>>>>>> Problem starts when the worse cases occurs.=20
>>>>>> Standard library creators would be able to implement=20
>>>>>> `greedy_conjunction` and `greedy_disjunction` in a way that they com=
piles=20
>>>>>> up to around 6x faster than the standard one. Users would be able ch=
oose=20
>>>>>> implementation which will suit best, based on what cases they are mo=
stly=20
>>>>>> expecting.
>>>>>>
>>>>>> *Specification*
>>>>>> Since it's a pre-proposal I don't want to post fully described=20
>>>>>> specification. I'm thinking about it in this way:
>>>>>>
>>>>>> `std::greedy_conjunction` would be an alias or would derive from a=
=20
>>>>>> type, which has a constexpr member `value` which can be converted to=
 bool=20
>>>>>> and is equal to:
>>>>>> -false if any bool(Tn::value0 =3D=3D false
>>>>>> -true otherwise
>>>>>>
>>>>>> `std::greedy_disjunction` would be an alias or would derive from a=
=20
>>>>>> type, which has a constexpr member `value` which can be converted to=
 bool=20
>>>>>> and is equal to:
>>>>>> -false if all bool(Tn::value) =3D=3D false
>>>>>> -true otherwise
>>>>>>
>>>>>> *Example implementations*
>>>>>> bool-pack (this one seems to compile faster than fold expression):
>>>>>> template <bool... Bn>
>>>>>> struct __bools {};
>>>>>>
>>>>>> template <typename... Tn>=20
>>>>>> struct greedy_disjunction: std::negation<std::is_same<__bools<bool(T=
n
>>>>>> ::value)...>, __bools<(Tn::value && false)...>>> {};
>>>>>>
>>>>>> template <typename... Tn>=20
>>>>>> struct greedy_conjunction: std::is_same<__bools<bool(Tn::value)...>,=
=20
>>>>>> __bools<(Tn::value || true)...>> {};
>>>>>>
>>>>>>
>>>>>> fold expression:
>>>>>> template <typename... Tn>=20
>>>>>> struct greedy_disjunction : std::bool_constant<(false || ... || bool=
(
>>>>>> Tn::value))> {};
>>>>>>
>>>>>> template <typename... Tn>=20
>>>>>> struct greedy_conjunction : std::bool_constant<(true && ... && bool(
>>>>>> Tn::value))> {};
>>>>>>
>>>>>>
>>>>>> *Wordings:*
>>>>>> *There is couple of questions*
>>>>>> I asked them to myself a lot, during this pre-proposal.
>>>>>> -Is it in the C++ standard scope to care about how things will be=20
>>>>>> implemented in standard library, even if the implementations will be=
 not=20
>>>>>> efficient on compile-time level?
>>>>>> -Should the standard be changed because of standard library=20
>>>>>> compilation time?
>>>>>>
>>>>>> And here's my conclusion (and reason why I'm writing this post).
>>>>>> C++ standard purpose is not to specify a theoretical language. It's=
=20
>>>>>> created to be used by a lot of people in the real world. Giving a ch=
oice to=20
>>>>>> user between implementations which differs in a compile-time efficie=
ncy is=20
>>>>>> same thing as to give a choice between containers e.g. `std::vector`=
 and=20
>>>>>> `std::list`. In some cases one implementation is better, in others t=
he=20
>>>>>> other one.
>>>>>>
>>>>>> *And of course the name*
>>>>>> I thought about `strict_*` (like it's in Facebook/folly lib) instead=
=20
>>>>>> of `greedy_*`, but I'm sure that if this proposal is a thing communi=
ty will=20
>>>>>> propose better names.
>>>>>>
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>> Mateusz (stryku) Janek
>>>>>>
>>>>>> --=20
>>>>>> You received this message because you are subscribed to the Google=
=20
>>>>>> Groups "ISO C++ Standard - Future Proposals" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,=20
>>>>>> send an email to std-proposal...@isocpp.org.
>>>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>>>> To view this discussion on the web visit=20
>>>>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0b=
4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org=20
>>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a79ce0=
b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium=3Demail&utm_source=
=3Dfooter>
>>>>>> .
>>>>>>
>>>>> --=20
>>> You received this message because you are subscribed to the Google=20
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>> an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> To view this discussion on the web visit=20
>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a=
331-483e-8f4d-4184c661b106%40isocpp.org=20
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a6a1fa-=
a331-483e-8f4d-4184c661b106%40isocpp.org?utm_medium=3Demail&utm_source=3Dfo=
oter>
>>> .
>>>
>>

--=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/7c36554f-ee04-4818-a56d-583681ab1bde%40isocpp.or=
g.

------=_Part_1333_1665635495.1503177923295
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Sorry, didn&#39;t realize that I was on wrong account.<br>=
<br>W dniu czwartek, 17 sierpnia 2017 12:02:56 UTC+2 u=C5=BCytkownik shmitt=
i...@gmail.com napisa=C5=82:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr">Got it. Thank you!<br><br>W dniu czwartek, 17 sierpnia 2017 =
10:26:13 UTC+2 u=C5=BCytkownik Micha=C5=82 Dominiak napisa=C5=82:<blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><p dir=3D"ltr">What I meant is that you don&#=
39;t really need a specific trait.</p>
<p dir=3D"ltr">You can&#39;t obtain the result of std::{con,dis}junction di=
rectly, without using a layer of abstraction for the laziness.</p>
<p dir=3D"ltr">You can, however, obtain the result of the greedy operation =
directly - by just &amp;&amp;ing or ||ing the values of the traits you&#39;=
d pass to this trait. Evaluation in templates is already eager that way, an=
d it&#39;s no problem to &amp;&amp; or || them together even in generic con=
texts, especially since we have fold expressions now.</p>
<p dir=3D"ltr">The reason for the traits that we have is laziness. If you d=
on&#39;t need laziness, you don&#39;t need the trait.</p>
<br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Aug 17, 2017, 10:17=
 AM  &lt;<a rel=3D"nofollow">mateusz...@gmail.com</a>&gt; wrote:<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hello again,</div><div>=
I am wondering if lack of response in this thread means that my idea has be=
en already rejected? If yes then could anyone explain why?</div><div><br></=
div><div>I might be wrong but this is why I&#39;m not convicted by the curr=
ent arguments:</div></div><div dir=3D"ltr"><div><br></div><div>&gt;You can =
already write your &quot;greedy&quot; things by just... deriving from bool_=
constant directly (exactly like in your last snippet).</div></div><div dir=
=3D"ltr"><div>I assume that your point is that it&#39;s easy to implement b=
y the user on his own. I&#39;m not convicted because there is a lot of stuf=
f in the standard library that are easy to implement, e.g. std::negation</d=
iv></div><div dir=3D"ltr"><div><br></div><div>&gt;Your thing doesn&#39;t se=
em to be very useful.</div></div><div dir=3D"ltr"><div>Not sure if I follow=
.. If they are not useful =3D&gt; std::conjunction and disjunction are not a=
s well (:</div><div>As you can see they compute almost same result as std::=
conjunction and disjunction, plus they give a choice to the user about the =
compilation time.</div><div><br></div><div>The only thing that concerns me =
here is if it&#39;s in the standard library scope to care about the compila=
tion time.</div><div><br></div><div>Thanks in advance,</div><div>Mateusz Ja=
nek</div></div><div dir=3D"ltr"><br>W dniu =C5=9Broda, 9 sierpnia 2017 23:2=
2:53 UTC+2 u=C5=BCytkownik <a>mateusz...@gmail.com</a> napisa=C5=82:<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">These traits are as usefu=
l as current conjunction and disjunction are - they compute the same result=
, but additionally give user a choice about compilation time and IMO that&#=
39;s a useful addition.<br><br>W dniu =C5=9Broda, 9 sierpnia 2017 14:37:05 =
UTC+2 u=C5=BCytkownik Micha=C5=82 Dominiak napisa=C5=82:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">You can already write your &quot;gr=
eedy&quot; things by just... deriving from bool_constant directly (exactly =
like in your last snippet). You couldn&#39;t do what the two traits are doi=
ng directly, and that&#39;s I believe is the only justification of their ex=
istence. Your thing doesn&#39;t seem to be very useful.</div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr">On Wed, Aug 9, 2017 at 2:31 PM &lt;<a rel=
=3D"nofollow">mateusz...@gmail.com</a>&gt; wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><b><font size=3D"4">Introduction</font=
></b></div><div><br></div><div>C++17 introduced besides the others two new =
structures in `&lt;type_traits&gt;` header: `std::conjuction` and `std::dis=
junction`. They are very useful in metaprogramming, but standard has in som=
e way forced their implementation.=C2=A0</div><div>In <a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0013r1.html" rel=3D"nofollow=
" target=3D"_blank" onmousedown=3D"this.href=3D&#39;http://www.google.com/u=
rl?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%=
2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHrhD3oGJRVXph=
YJvzGExp6I3jexQ&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.g=
oogle.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdoc=
s%2Fpapers%2F2015%2Fp0013r1.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHr=
hD3oGJRVXphYJvzGExp6I3jexQ&#39;;return true;">p0013r1</a>=C2=A0we can read:=
</div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Ro=
man&quot;;font-size:medium;text-align:justify">The BaseCharacteristic of a =
specialization=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:jus=
tify">conjunction&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(0,160,0=
);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justi=
fy">=C2=A0is the first type=C2=A0</span><code style=3D"color:rgb(0,160,0);t=
ext-align:justify">Bi</code><span style=3D"color:rgb(0,160,0);font-family:&=
quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0in th=
e list=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">tr=
ue_type, B1, ..., BN</code><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0for wh=
ich=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi::v=
alue =3D=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&quot=
;Times New Roman&quot;;font-size:medium;text-align:justify">, or if every=
=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi::valu=
e !=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Time=
s New Roman&quot;;font-size:medium;text-align:justify">=C2=A0the BaseCharac=
teristic is=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justif=
y">BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New R=
oman&quot;;font-size:medium;text-align:justify">. [</span><em style=3D"colo=
r:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;tex=
t-align:justify">Note:</em><span style=3D"color:rgb(0,160,0);font-family:&q=
uot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0This m=
eans a specialization of=C2=A0</span><code style=3D"color:rgb(0,160,0);text=
-align:justify">conjunction</code><span style=3D"color:rgb(0,160,0);font-fa=
mily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0does not necessarily have a BaseCharacteristic of either=C2=A0</span><co=
de style=3D"color:rgb(0,160,0);text-align:justify">true_type</code><span st=
yle=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size=
:medium;text-align:justify">=C2=A0or=C2=A0</span><code style=3D"color:rgb(0=
,160,0);text-align:justify">false_type</code><span style=3D"color:rgb(0,160=
,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:jus=
tify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"color:rgb(0,160,0);font-fam=
ily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">end no=
te</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&=
quot;;font-size:medium;text-align:justify">]</span><br></div><div><span sty=
le=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:=
medium;text-align:justify"><br></span></div><div>Similar in the disjunction=
:=C2=A0</div><div><span style=3D"color:rgb(0,160,0);font-family:&quot;Times=
 New Roman&quot;;font-size:medium;text-align:justify">The BaseCharacteristi=
c of a specialization=C2=A0</span><code style=3D"color:rgb(0,160,0);text-al=
ign:justify">disjunction&lt;B1, ..., BN&gt;</code><span style=3D"color:rgb(=
0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-alig=
n:justify">=C2=A0is the first type=C2=A0</span><code style=3D"color:rgb(0,1=
60,0);text-align:justify">Bi</code><span style=3D"color:rgb(0,160,0);font-f=
amily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0in the list=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:jus=
tify">false_type, B1, ..., BN</code><span style=3D"color:rgb(0,160,0);font-=
family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0for which=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justi=
fy">Bi::value !=3D false</code><span style=3D"color:rgb(0,160,0);font-famil=
y:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">, or if =
every=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align:justify">Bi:=
:value =3D=3D false</code><span style=3D"color:rgb(0,160,0);font-family:&qu=
ot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=A0the Bas=
eCharacteristic is=C2=A0</span><code style=3D"color:rgb(0,160,0);text-align=
:justify">BN</code><span style=3D"color:rgb(0,160,0);font-family:&quot;Time=
s New Roman&quot;;font-size:medium;text-align:justify">. [</span><em style=
=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:me=
dium;text-align:justify">Note:</em><span style=3D"color:rgb(0,160,0);font-f=
amily:&quot;Times New Roman&quot;;font-size:medium;text-align:justify">=C2=
=A0This means a specialization of=C2=A0</span><code style=3D"color:rgb(0,16=
0,0);text-align:justify">disjunction</code><span style=3D"color:rgb(0,160,0=
);font-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justi=
fy">=C2=A0does not necessarily have a BaseCharacteristic of either=C2=A0</s=
pan><code style=3D"color:rgb(0,160,0);text-align:justify">true_type</code><=
span style=3D"color:rgb(0,160,0);font-family:&quot;Times New Roman&quot;;fo=
nt-size:medium;text-align:justify">=C2=A0or=C2=A0</span><code style=3D"colo=
r:rgb(0,160,0);text-align:justify">false_type</code><span style=3D"color:rg=
b(0,160,0);font-family:&quot;Times New Roman&quot;;font-size:medium;text-al=
ign:justify"><wbr>. =E2=80=94=C2=A0</span><em style=3D"color:rgb(0,160,0);f=
ont-family:&quot;Times New Roman&quot;;font-size:medium;text-align:justify"=
>end note</em><span style=3D"color:rgb(0,160,0);font-family:&quot;Times New=
 Roman&quot;;font-size:medium;text-align:justify">]</span><br></div><div><b=
r></div><div>I&#39;d like to propose a two new structures in `&lt;type_trai=
ts&gt;`: `std::greedy_conjunction` and `std::greedy_disjunction`. Their res=
ults would very similar to the ones from `std::conjunciton` and `std::disju=
nction`, but their specification would give more flexibility to the standar=
d library creators.</div><div><br></div><div><br></div><div><b><font size=
=3D"4">Motivation and Scope</font></b></div><div><br></div><div>With `std::=
conjuction` and `std::disjunction` restrictions in the standard, library cr=
eators are forced to make them in such (or similar) way:</div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"c=
olor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#660">...&gt;</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><span =
style=3D"color:#000"> conjunction </span><span style=3D"color:#660">:</span=
><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">true_type </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">template</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct=
</span><span style=3D"color:#000"> conjunction</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#6=
60">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> B1 </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">c=
lass</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">class=
</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> conjunction</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Bn=
</span><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000">=
 <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">:</span><span style=3D=
"color:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"=
color:#000">conditional_t</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">B1</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">va<wbr>lue</span><span style=3D"color:#660">),</span><span=
 style=3D"color:#000"> conjunction</span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;,=
</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{};</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 <br></span><span style=3D"=
color:#008">template</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#008">class</span><span style=3D"color:#660">...&gt;</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><span=
 style=3D"color:#000"> disjunction </span><span style=3D"color:#660">:</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">false_type </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">template=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">stru=
ct</span><span style=3D"color:#000"> disjunction</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:=
#660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">:</span><span style=3D"color:#000"> B1 </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></span><span style=3D"color:#008">temp=
late</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008"=
>class</span><span style=3D"color:#000"> B1</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">cla=
ss</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#008">struc=
t</span><span style=3D"color:#000"> disjunction</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#000">B1</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#606">=
Bn</span><span style=3D"color:#660">...&gt;</span><span style=3D"color:#000=
"> <br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">conditional_t</span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">bool</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">B1</span><span style=3D"color:#660">::</span><span =
style=3D"color:#000">va<wbr>lue</span><span style=3D"color:#660">),</span><=
span style=3D"color:#000"> B1</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> disjunction</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#606">Bn</span><span style=3D"color:#660">...&gt;=
&gt;</span><span style=3D"color:#000"> =C2=A0</span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}=
;</span><span style=3D"color:#000"><br><br></span></div></code></div><div><=
br>=C2=A0 =C2=A0=C2=A0</div><div>There are strong grounds to keep these imp=
lementations, e.g. short-circuiting, getting information on what type, recu=
rsion stopped etc. Although, because of these restrictions compilation time=
 suffers in some cases.</div><div><br></div><div><b><font size=3D"4">Why ne=
w,=C2=A0<u>very similar</u> traits?</font></b></div><div><b>Abstract</b></d=
iv><div>During my pull request to folly (<a href=3D"https://github.com/face=
book/folly/pull/643" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this=
..href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffac=
ebook%2Ffolly%2Fpull%2F643\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzRzYU=
aerIKsE3rogxWBbtocbw&#39;;return true;" onclick=3D"this.href=3D&#39;https:/=
/www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Ffacebook%2Ffolly%2Fpull=
%2F643\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFmOzRzYUaerIKsE3rogxWBbtocbw=
&#39;;return true;">https://github.com/facebook/<wbr>folly/pull/643</a>) Ja=
y Feldblum posted there a small benchmark script: <a href=3D"https://gist.g=
ithub.com/yfeldblum/ffae5374aaaa11b03f08919d25b1555b" rel=3D"nofollow" targ=
et=3D"_blank" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1=
555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#=
39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgist.github.com%2Fyfeldblum%2Fffae5374aaaa11b03f08919d25b1=
555b\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHi3xrC-eDaheXnAHTmJ5rTlEJgRA&#=
39;;return true;">https://gist.github.com/<wbr>yfeldblum/<wbr>ffae5374aaaa1=
1b03f08919d25b155<wbr>5b</a>=C2=A0(big credits for poking my brain with the=
 idea). I was surprised that, let&#39;s say, the naive implementation compi=
les faster that the standard one.=C2=A0</div><div><br></div><div>I decided =
to benchmark this idea deeper:</div><div>-problem was to find in a types se=
quence if there is a type which T::value is equal to 0</div><div>-for every=
 benchmark sequence has 1024 types inside</div><div>-tested sequences with =
two kinds of types: light and heavy to instantiate</div><div>-tested best a=
nd worse cases</div><div>-tested two new implementations: fold expression a=
nd bool-pack</div><div>-core benchmark was to measure the compilation time =
with given compiler (clang++-4.0/g++-6), case (best/worse), type (light/hea=
vy), implementation (proposed/standard). Every compilation case was ran 500=
 times and average result was calculated.</div><div><br></div><div>Whole be=
nchmarks code you can find in the gh repo:=C2=A0<a href=3D"https://github.c=
om/stryku/boolpack_vs_recursion" rel=3D"nofollow" target=3D"_blank" onmouse=
down=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgith=
ub.com%2Fstryku%2Fboolpack_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNHICyJnr6jjlrCVLCKQErJdqh0rLg&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fstryku%2=
Fboolpack_vs_recursion\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHICyJnr6jjlr=
CVLCKQErJdqh0rLg&#39;;return true;">https://github.com/<wbr>stryku/boolpack=
_vs_recursion</a></div><div><br></div><div>And here are the results (sorry =
for not posting it here, but table was too big and it was formatted in unre=
adable way):</div><div><a href=3D"https://raw.githubusercontent.com/stryku/=
boolpack_vs_recursion/master/output" rel=3D"nofollow" target=3D"_blank" onm=
ousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2F=
raw.githubusercontent.com%2Fstryku%2Fboolpack_vs_recursion%2Fmaster%2Foutpu=
t\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08KY4FDz5dQ&#39;=
;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3d=
https%3A%2F%2Fraw.githubusercontent.com%2Fstryku%2Fboolpack_vs_recursion%2F=
master%2Foutput\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFy33FwRHZtVQg2amM08=
KY4FDz5dQ&#39;;return true;">https://raw.githubusercontent.<wbr>com/stryku/=
boolpack_vs_<wbr>recursion/master/output</a></div><div><br></div><div>As yo=
u can see, standard implementation is way better when we deal with the best=
 case. It can compile 80x(!) faster than the proposed ones. Problem starts =
when the worse cases occurs.=C2=A0</div><div>Standard library creators woul=
d be able to implement `greedy_conjunction` and `greedy_disjunction` in a w=
ay that they compiles up to around 6x faster than the standard one. Users w=
ould be able choose implementation which will suit best, based on what case=
s they are mostly expecting.</div><div><br></div><div><font size=3D"4"><b>S=
pecification</b></font></div><div>Since it&#39;s a pre-proposal I don&#39;t=
 want to post fully described specification. I&#39;m thinking about it in t=
his way:</div><div><br></div><div>`std::greedy_conjunction` would be an ali=
as or would derive from a type, which has a constexpr member `value` which =
can be converted to bool and is equal to:</div><div>-false if any bool(Tn::=
value0 =3D=3D false</div><div>-true otherwise</div><div><br></div><div><div=
>`std::greedy_disjunction` would be an alias or would derive from a type, w=
hich has a constexpr member `value` which can be converted to bool and is e=
qual to:</div><div>-false if all bool(Tn::value) =3D=3D false</div><div>-tr=
ue otherwise</div></div><div><br></div><div><font size=3D"4"><b>Example imp=
lementations</b></font></div><div>bool-pack (this one seems to compile fast=
er than fold expression):</div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px;word-=
wrap:break-word"><code><div><span style=3D"color:#008">template</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#008">bool</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#606">Bn</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">struct</span><span style=3D"color:#000"> __bools </span><s=
pan style=3D"color:#660">{};</span><span style=3D"color:#000"><br><br></spa=
n><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typena=
me</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">&gt;</=
span><span style=3D"color:#000"> <br></span><span style=3D"color:#008">stru=
ct</span><span style=3D"color:#000"> greedy_disjunction</span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">negation</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#000">std</span><span st=
yle=3D"color:#660">::</span><span style=3D"color:#000">is_same</span><span =
style=3D"color:#660">&lt;</span><span style=3D"color:#000">__<wbr>bools</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">bool</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">value</span>=
<span style=3D"color:#660">)...&gt;,</span><span style=3D"color:#000"> __bo=
ols</span><span style=3D"color:#660">&lt;(</span><span style=3D"color:#606"=
>Tn</span><span style=3D"color:#660">::</span><span style=3D"color:#000">va=
lue </span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">false</span><span style=3D"color:=
#660">)...&gt;&gt;&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{};</span><span style=3D"color:#000"><br><br></span><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span>=
<span style=3D"color:#660">...</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#606">Tn</span><span style=3D"color:#660">&gt;</span><spa=
n style=3D"color:#000"> <br></span><span style=3D"color:#008">struct</span>=
<span style=3D"color:#000"> greedy_conjunction</span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">is_same</span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#000">__bools</span><span style=3D"col=
or:#660">&lt;</span><span style=3D"color:#008">bool</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#606">Tn</span><span style=3D"color:=
#660">::</span><span style=3D"color:#000"><wbr>value</span><span style=3D"c=
olor:#660">)...&gt;,</span><span style=3D"color:#000"> __bools</span><span =
style=3D"color:#660">&lt;(</span><span style=3D"color:#606">Tn</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">value </span><span=
 style=3D"color:#660">||</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">true</span><span style=3D"color:#660">)...&gt;&gt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{};</span><sp=
an style=3D"color:#000"><br></span></div></code></div><div><br><br></div><d=
iv>fold expression:</div><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:b=
reak-word"><code><div><span style=3D"color:#008">template</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#660">...</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#606">Tn</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> <br></span><span sty=
le=3D"color:#008">struct</span><span style=3D"color:#000"> greedy_disjuncti=
on </span><span style=3D"color:#660">:</span><span style=3D"color:#000"> st=
d</span><span style=3D"color:#660">::</span><span style=3D"color:#000">bool=
_constant</span><span style=3D"color:#660">&lt;(</span><span style=3D"color=
:#008">false</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">||</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">...</span><span style=3D"color:#000"> </span><span style=3D"color:#660">|=
|</span><span style=3D"color:#000"> </span><span style=3D"color:#008">bool<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">value</spa=
n><span style=3D"color:#660">))&gt;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">{};</span><span style=3D"color:#000"><br><br><=
/span><span style=3D"color:#008">template</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#660">...</span><span style=3D"color:#000=
"> </span><span style=3D"color:#606">Tn</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> <br></span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> greedy_conjunction </span><span st=
yle=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">bool_constant</span><s=
pan style=3D"color:#660">&lt;(</span><span style=3D"color:#008">true</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">...</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">bool</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#606">Tn</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">value</span><=
span style=3D"color:#660">))&gt;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{};</span><span style=3D"color:#000"><br></span><=
/div></code></div><div><br><br></div><div><font size=3D"4"><b>Wordings:</b>=
</font></div><div><b>There is couple of questions</b></div><div>I asked the=
m to myself a lot, during this pre-proposal.</div><div>-Is it in the C++ st=
andard scope to care about how things will be implemented in standard libra=
ry, even if the implementations will be not efficient on compile-time level=
?</div><div>-Should the standard be changed because of standard library com=
pilation time?</div><div><br></div><div>And here&#39;s my conclusion (and r=
eason why I&#39;m writing this post).</div><div>C++ standard purpose is not=
 to specify a theoretical language. It&#39;s created to be used by a lot of=
 people in the real world. Giving a choice to user between implementations =
which differs in a compile-time efficiency is same thing as to give a choic=
e between containers e.g. `std::vector` and `std::list`. In some cases one =
implementation is better, in others the other one.</div><div><br></div><div=
><b>And of course the name</b></div><div>I thought about `strict_*` (like i=
t&#39;s in Facebook/folly lib) instead of `greedy_*`, but I&#39;m sure that=
 if this proposal is a thing community will propose better names.</div><div=
><br></div><div><br></div><div>What do you think?</div><div><br></div><div>=
Mateusz (stryku) Janek</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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</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/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/a79ce0b4-ca2d-4c37-b49e-cb707689a0e2%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/a79ce0b4-ca2d-4c37-<wbr>b49e-=
cb707689a0e2%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></div></blockquote></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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</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/81a6a1fa-a331-483e-8f4d-4184c661b106%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofollow" t=
arget=3D"_blank" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/81a6a1fa-a331-483e-8f4d-4184c661b106%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/81a6a1fa-a331-483e-8f4d-4184c661b106%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/81a6a1fa-a331-483e-<wbr>8f4d-=
4184c661b106%40isocpp.org</a><wbr>.<br>
</blockquote></div>
</blockquote></div></blockquote></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/7c36554f-ee04-4818-a56d-583681ab1bde%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7c36554f-ee04-4818-a56d-583681ab1bde=
%40isocpp.org</a>.<br />

------=_Part_1333_1665635495.1503177923295--

------=_Part_1332_1167394811.1503177923293--

.