Topic: std::degenerate<> class template : primitive/enum
Author: the.ultimate.koala@gmail.com
Date: Sun, 1 Sep 2013 01:43:07 -0700 (PDT)
Raw View
------=_Part_2112_30201635.1378024987752
Content-Type: text/plain; charset=ISO-8859-1
Hello,
I am sending this idea for feedback from the community. I don't know if any
prior work has been down on this, or if this can be done with
std::optional. If so please let me know.
Let's say that you want to implement the Tic-Tac-Toe game, and you want to
store the state of the board into an array of 9 values. The C way to do it
would be:
enum SquareState { EMPTY, CROSS, NOUGHT };
SquareState board[9];
The C++98 way to do it would be:
enum SquareState { EMPTY, CROSS, NOUGHT };
std::vector<SquareState> board(9);
The C++11 way would add:
enum class SquareState { EMPTY, CROSS, NOUGHT };
std::array<SquareState, 9> board;
Now, you're happy. Your code is a lot cleaner, but then, you have to store
the player-to-play. What type will you use? Since you have to associate
either CROSS or NOUGHT to each player, you would use the same constant.
enum class SquareState { EMPTY, CROSS, NOUGHT };
std::array<SquareState, 9> board;
SquareState player_to_play;
Now, your spider sense tells you that player_to_play should not be a
"SquareState". That should be the other way around.
enum class Player { EMPTY, CROSS, NOUGHT };
std::array<Player, 9> board;
Player player_to_play;
But now: who is this Player::EMPTY person? And then, you remember that you
really like the work of the C++ community, and upgrade to experimental
C++14 :
enum class Player { CROSS, NOUGHT };
std::array<std::optional<Player>, 9> board;
Player player_to_play;
You like it better. But you realize that this may have substantially
increased demand in memory. Indeed, optional effectively adds "undefined"
to the set of values already encodable by its template parameter. Indeed,
if you compare sizeof's of Player and std::optional<Player>, you get :
Size of Player:4
Size of optional<Player>:8
Even setting the enum storage type to char gives:
Size of Player:1
Size of optional<Player>:2
And this makes you the laughing stock of the C programmers, even with the
semantic improvement, because you're using two bytes to encode a set of 3
values.
The proposal would be of a class template which:
- Would be a drop-in replacement for optional, i.e. have the same
interface and close enough semantics,
- Would set apart a value from the encodable set, and treat it as
undefined.
For example :
template<class T, T uninitialized_value>
class degenerate {
T value;
public:
degenerate(T v = uninitialized_value)
: value(v) {}
T& operator* () {
if(value == uninitialized_value) {
throw std::logic_error();
}
return value;
}
// ...
};
Which gives effectively :
Size of Player:1
Size of optional<Player>:2
Size of degenerate<Player, Player(-1)>:1
I find lots of uses for this. What do you think?
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2112_30201635.1378024987752
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hello,<br><br>I am sending this idea for feedback from the=
community. I don't know if any prior work has been down on this, or if thi=
s can be done with std::optional. If so please let me know.<br><br>Let's sa=
y that you want to implement the Tic-Tac-Toe game, and you want to store th=
e state of the board into an array of 9 values. The C way to do it would be=
:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>enum</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">SquareState</s=
pan><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"> EMPTY</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> CROSS</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> NOUGHT </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">SquareState</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> board</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">9</span><span style=3D"color: #660;" class=3D"styled-by-prettify">];</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br>The C++98 way to do it would be:<br><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">enum</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">SquareState</span><span style=3D"colo=
r: #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"> EMPTY</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> CROSS</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> NOUG=
HT </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &nbs=
p; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">vector</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span=
style=3D"color: #606;" class=3D"styled-by-prettify">SquareState</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> board</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
066;" class=3D"styled-by-prettify">9</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><br>The C++11 way would add=
:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>enum</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">SquareState</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> EMPTY</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> CROSS</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> NOUGHT </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">arr=
ay</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</sp=
an><span style=3D"color: #606;" class=3D"styled-by-prettify">SquareState</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">9</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> board</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div><br>Now, you're happy. Your c=
ode is a lot cleaner, but then, you have to store the player-to-play. What =
type will you use? Since you have to associate either CROSS or NOUGHT to ea=
ch player, you would use the same constant.<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">SquareState</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> E=
MPTY</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> CROSS</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> NOUGHT </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">array</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">SquareState</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: #066;" class=3D"style=
d-by-prettify">9</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
board</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &n=
bsp; </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Squar=
eState</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pla=
yer_to_play</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div><br>Now, your spider sense tells you that player_to_p=
lay should not be a "SquareState". That should be the other way around.<br>=
<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250=
); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px=
; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><span style=3D"color: #000;" class=3D"styled-by-prettify"> &=
nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">enum=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Player</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"> EMPTY</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> CROSS</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> NOUGH=
T </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>  =
; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">array</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Player</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: #066;" =
class=3D"styled-by-prettify">9</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">></span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> board</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: #606;" class=3D"styled-by-p=
rettify">Player</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> player_to_play</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span></div></code></div><br>But now: who is this Player::EMPTY perso=
n? And then, you remember that you really like the work of the C++ communit=
y, and upgrade to experimental C++14 :<br><br><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Player</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> CROSS</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> NOUGHT </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br> std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">array</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;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">optional</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Player</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">9</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> board</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: #606;" class=3D"styled-by-prettify">Player</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> player_to_play</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Yo=
u like it better. But you realize that this may have substantially increase=
d demand in memory. Indeed, optional effectively adds "undefined" to the se=
t of values already encodable by its template parameter. Indeed, if you com=
pare sizeof's of Player and std::optional<Player>, you get :<br><br><=
span style=3D"font-family: courier new,monospace;">Size of Player:4<br>Size=
of optional<Player>:8</span><br><br>Even setting the enum storage ty=
pe to char gives:<br><br><span style=3D"font-family: courier new,monospace;=
">Size of Player:1<br>Size of optional<Player>:2<br></span><br>And th=
is makes you the laughing stock of the C programmers, even with the semanti=
c improvement, because you're using two bytes to encode a set of 3 values.<=
br><br>The proposal would be of a class template which:<br><ul><li>Would be=
a drop-in replacement for optional, i.e. have the same interface and close=
enough semantics,</li><li>Would set apart a value from the encodable set, =
and treat it as undefined.</li></ul><p>For example :</p><p></p><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> T uninitialized_value</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;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> degenerate </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> T value</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">public</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
degenerate</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T =
v </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> uninitialized_=
value</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br> &n=
bsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> value</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">v</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: #660;" class=3D=
"styled-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br> T</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">operator</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><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 style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">value </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> uninitialized_value</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">throw</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">logi=
c_error</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: #660;" class=3D"styled-by-prettify">}<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> va=
lue</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br> </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">// ...</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Wh=
ich gives effectively :<p></p><p><span style=3D"font-family: courier new,mo=
nospace;">Size of Player:1<br>Size of optional<Player>:2<br>Size of d=
egenerate<Player, Player(-1)>:1</span><br></p><p>I find lots of uses =
for this. What do you think?<br></p></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2112_30201635.1378024987752--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sun, 1 Sep 2013 18:06:05 +0200
Raw View
--001a11c342ec380b2804e554a38c
Content-Type: text/plain; charset=ISO-8859-1
A similar situation occurs when combining optional<T> and variant<T...>:
optional<variant<int, float, string>>. The variant probably keeps some
integer (e.g. 0,1, or 2) to keep track of whether it contains a int, float
or a string. The optional could, instead of adding a boolean, somehow store
a value that has no meaning for the variant (e.g. -1 or 3) in that integer
when the variant is not set.
However, the degenerate<typename T, T> solution would not be a solution in
this case. (Maybe optional<> should be specialzed for varaiants, or
optional_variant should exist, or variant<void, int, float, string> shoud
be used instead, but I'm wondering if there might exist a solution for both
this situation and the situations degenerate<template T, T> solves, since
they are similar.)
-Maurice-
2013/9/1 <the.ultimate.koala@gmail.com>
> Hello,
>
> I am sending this idea for feedback from the community. I don't know if
> any prior work has been down on this, or if this can be done with
> std::optional. If so please let me know.
>
> Let's say that you want to implement the Tic-Tac-Toe game, and you want to
> store the state of the board into an array of 9 values. The C way to do it
> would be:
>
> enum SquareState { EMPTY, CROSS, NOUGHT };
> SquareState board[9];
>
> The C++98 way to do it would be:
>
> enum SquareState { EMPTY, CROSS, NOUGHT };
> std::vector<SquareState> board(9);
>
> The C++11 way would add:
>
> enum class SquareState { EMPTY, CROSS, NOUGHT };
> std::array<SquareState, 9> board;
>
> Now, you're happy. Your code is a lot cleaner, but then, you have to store
> the player-to-play. What type will you use? Since you have to associate
> either CROSS or NOUGHT to each player, you would use the same constant.
>
> enum class SquareState { EMPTY, CROSS, NOUGHT };
> std::array<SquareState, 9> board;
> SquareState player_to_play;
>
> Now, your spider sense tells you that player_to_play should not be a
> "SquareState". That should be the other way around.
>
> enum class Player { EMPTY, CROSS, NOUGHT };
> std::array<Player, 9> board;
> Player player_to_play;
>
> But now: who is this Player::EMPTY person? And then, you remember that you
> really like the work of the C++ community, and upgrade to experimental
> C++14 :
>
> enum class Player { CROSS, NOUGHT };
> std::array<std::optional<Player>, 9> board;
> Player player_to_play;
>
> You like it better. But you realize that this may have substantially
> increased demand in memory. Indeed, optional effectively adds "undefined"
> to the set of values already encodable by its template parameter. Indeed,
> if you compare sizeof's of Player and std::optional<Player>, you get :
>
> Size of Player:4
> Size of optional<Player>:8
>
> Even setting the enum storage type to char gives:
>
> Size of Player:1
> Size of optional<Player>:2
>
> And this makes you the laughing stock of the C programmers, even with the
> semantic improvement, because you're using two bytes to encode a set of 3
> values.
>
> The proposal would be of a class template which:
>
> - Would be a drop-in replacement for optional, i.e. have the same
> interface and close enough semantics,
> - Would set apart a value from the encodable set, and treat it as
> undefined.
>
> For example :
>
> template<class T, T uninitialized_value>
> class degenerate {
> T value;
> public:
> degenerate(T v = uninitialized_value)
> : value(v) {}
>
> T& operator* () {
> if(value == uninitialized_value) {
> throw std::logic_error();
> }
>
> return value;
> }
>
> // ...
> };
>
> Which gives effectively :
>
> Size of Player:1
> Size of optional<Player>:2
> Size of degenerate<Player, Player(-1)>:1
>
> I find lots of uses for this. What do you think?
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c342ec380b2804e554a38c
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">A similar situation occurs when combining optional<T>=
; and variant<T...>: optional<variant<int, float, string>>=
;. The variant probably keeps some integer (e.g. 0,1, or 2) to keep track o=
f whether it contains a int, float or a string. The optional could, instead=
of adding a boolean, somehow store a value that has no meaning for the var=
iant (e.g. -1 or 3) in that integer when the variant is not set.<br>
<br>However, the degenerate<typename T, T> solution would not be a so=
lution in this case. (Maybe optional<> should be specialzed for varai=
ants, or optional_variant should exist, or variant<void, int, float, str=
ing> shoud be used instead, but I'm wondering if there might exist a=
solution for both this situation and the situations degenerate<template=
T, T> solves, since they are similar.)<br>
<br>-Maurice-<br><br></div><div class=3D"gmail_extra"><br><br><div class=3D=
"gmail_quote">2013/9/1 <span dir=3D"ltr"><<a href=3D"mailto:the.ultimat=
e.koala@gmail.com" target=3D"_blank">the.ultimate.koala@gmail.com</a>></=
span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hello,<br><br>I am sending =
this idea for feedback from the community. I don't know if any prior wo=
rk has been down on this, or if this can be done with std::optional. If so =
please let me know.<br>
<br>Let's say that you want to implement the Tic-Tac-Toe game, and you =
want to store the state of the board into an array of 9 values. The C way t=
o do it would be:<br><br><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>=A0 =A0 </span><span style=3D"color:#008">enum</span=
><span style> </span><span style=3D"color:#606">SquareState</span><span sty=
le> </span><span style=3D"color:#660">{</span><span style> EMPTY</span><spa=
n style=3D"color:#660">,</span><span style> CROSS</span><span style=3D"colo=
r:#660">,</span><span style> NOUGHT </span><span style=3D"color:#660">};</s=
pan><span style><br>
=A0 =A0 </span><span style=3D"color:#606">SquareState</span><span style> bo=
ard</span><span style=3D"color:#660">[</span><span style=3D"color:#066">9</=
span><span style=3D"color:#660">];</span><span style><br></span></div></cod=
e></div>
<br>The C++98 way to do it would be:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style>=A0 =A0 </span><span s=
tyle=3D"color:#008">enum</span><span style> </span><span style=3D"color:#60=
6">SquareState</span><span style> </span><span style=3D"color:#660">{</span=
><span style> EMPTY</span><span style=3D"color:#660">,</span><span style> C=
ROSS</span><span style=3D"color:#660">,</span><span style> NOUGHT </span><s=
pan style=3D"color:#660">};</span><span style><br>
=A0 =A0 std</span><span style=3D"color:#660">::</span><span style>vector</s=
pan><span style=3D"color:#660"><</span><span style=3D"color:#606">Square=
State</span><span style=3D"color:#660">></span><span style> board</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#066">9</span><span=
style=3D"color:#660">);</span><span style><br>
</span></div></code></div><br>The C++11 way would add:<br><br><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>=A0 =
=A0 </span><span style=3D"color:#008">enum</span><span style> </span><span =
style=3D"color:#008">class</span><span style> </span><span style=3D"color:#=
606">SquareState</span><span style> </span><span style=3D"color:#660">{</sp=
an><span style> EMPTY</span><span style=3D"color:#660">,</span><span style>=
CROSS</span><span style=3D"color:#660">,</span><span style> NOUGHT </span>=
<span style=3D"color:#660">};</span><span style><br>
=A0 =A0 std</span><span style=3D"color:#660">::</span><span style>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">SquareS=
tate</span><span style=3D"color:#660">,</span><span style> </span><span sty=
le=3D"color:#066">9</span><span style=3D"color:#660">></span><span style=
> board</span><span style=3D"color:#660">;</span><span style><br>
</span></div></code></div><br>Now, you're happy. Your code is a lot cle=
aner, but then, you have to store the player-to-play. What type will you us=
e? Since you have to associate either CROSS or NOUGHT to each player, you w=
ould use the same constant.<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style>=A0 =A0 </span><span style=3D"color:#008">enum</span><span sty=
le> </span><span style=3D"color:#008">class</span><span style> </span><span=
style=3D"color:#606">SquareState</span><span style> </span><span style=3D"=
color:#660">{</span><span style> EMPTY</span><span style=3D"color:#660">,</=
span><span style> CROSS</span><span style=3D"color:#660">,</span><span styl=
e> NOUGHT </span><span style=3D"color:#660">};</span><span style><br>
=A0 =A0 std</span><span style=3D"color:#660">::</span><span style>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">SquareS=
tate</span><span style=3D"color:#660">,</span><span style> </span><span sty=
le=3D"color:#066">9</span><span style=3D"color:#660">></span><span style=
> board</span><span style=3D"color:#660">;</span><span style><br>
=A0 =A0 </span><span style=3D"color:#606">SquareState</span><span style> pl=
ayer_to_play</span><span style=3D"color:#660">;</span><span style><br></spa=
n></div></code></div><br>Now, your spider sense tells you that player_to_pl=
ay should not be a "SquareState". That should be the other way ar=
ound.<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style>=A0 =A0 </span><span style=3D"color:#008">enum</span><span sty=
le> </span><span style=3D"color:#008">class</span><span style> </span><span=
style=3D"color:#606">Player</span><span style> </span><span style=3D"color=
:#660">{</span><span style> EMPTY</span><span style=3D"color:#660">,</span>=
<span style> CROSS</span><span style=3D"color:#660">,</span><span style> NO=
UGHT </span><span style=3D"color:#660">};</span><span style><br>
=A0 =A0 std</span><span style=3D"color:#660">::</span><span style>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">Player<=
/span><span style=3D"color:#660">,</span><span style> </span><span style=3D=
"color:#066">9</span><span style=3D"color:#660">></span><span style> boa=
rd</span><span style=3D"color:#660">;</span><span style><br>
=A0 =A0 </span><span style=3D"color:#606">Player</span><span style> player_=
to_play</span><span style=3D"color:#660">;</span><span style><br></span></d=
iv></code></div><br>But now: who is this Player::EMPTY person? And then, yo=
u remember that you really like the work of the C++ community, and upgrade =
to experimental C++14 :<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style>=A0 =A0 </span><span style=3D"color:#008">enum</span><span sty=
le> </span><span style=3D"color:#008">class</span><span style> </span><span=
style=3D"color:#606">Player</span><span style> </span><span style=3D"color=
:#660">{</span><span style> CROSS</span><span style=3D"color:#660">,</span>=
<span style> NOUGHT </span><span style=3D"color:#660">};</span><span style>=
<br>
=A0 =A0 std</span><span style=3D"color:#660">::</span><span style>array</sp=
an><span style=3D"color:#660"><</span><span style>std</span><span style=
=3D"color:#660">::</span><span style>optional</span><span style=3D"color:#6=
60"><</span><span style=3D"color:#606">Player</span><span style=3D"color=
:#660">>,</span><span style> </span><span style=3D"color:#066">9</span><=
span style=3D"color:#660">></span><span style> board</span><span style=
=3D"color:#660">;</span><span style><br>
=A0 =A0 </span><span style=3D"color:#606">Player</span><span style> player_=
to_play</span><span style=3D"color:#660">;</span><span style><br></span></d=
iv></code></div><br>You like it better. But you realize that this may have =
substantially increased demand in memory. Indeed, optional effectively adds=
"undefined" to the set of values already encodable by its templa=
te parameter. Indeed, if you compare sizeof's of Player and std::option=
al<Player>, you get :<br>
<br><span style=3D"font-family:courier new,monospace">Size of Player:4<br>S=
ize of optional<Player>:8</span><br><br>Even setting the enum storage=
type to char gives:<br><br><span style=3D"font-family:courier new,monospac=
e">Size of Player:1<br>
Size of optional<Player>:2<br></span><br>And this makes you the laugh=
ing stock of the C programmers, even with the semantic improvement, because=
you're using two bytes to encode a set of 3 values.<br><br>The proposa=
l would be of a class template which:<br>
<ul><li>Would be a drop-in replacement for optional, i.e. have the same int=
erface and close enough semantics,</li><li>Would set apart a value from the=
encodable set, and treat it as undefined.</li></ul><p>For example :</p>
<p></p><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">&l=
t;</span><span style=3D"color:#008">class</span><span style> T</span><span =
style=3D"color:#660">,</span><span style> T uninitialized_value</span><span=
style=3D"color:#660">></span><span style><br>
</span><span style=3D"color:#008">class</span><span style> degenerate </spa=
n><span style=3D"color:#660">{</span><span style><br>=A0 T value</span><spa=
n style=3D"color:#660">;</span><span style><br></span><span style=3D"color:=
#008">public</span><span style=3D"color:#660">:</span><span style><br>
=A0 degenerate</span><span style=3D"color:#660">(</span><span style>T v </s=
pan><span style=3D"color:#660">=3D</span><span style> uninitialized_value</=
span><span style=3D"color:#660">)</span><span style> <br>=A0 =A0 </span><sp=
an style=3D"color:#660">:</span><span style> value</span><span style=3D"col=
or:#660">(</span><span style>v</span><span style=3D"color:#660">)</span><sp=
an style> </span><span style=3D"color:#660">{}</span><span style><br>
<br>=A0 T</span><span style=3D"color:#660">&</span><span style> </span>=
<span style=3D"color:#008">operator</span><span style=3D"color:#660">*</spa=
n><span style> </span><span style=3D"color:#660">()</span><span style> </sp=
an><span style=3D"color:#660">{</span><span style><br>
=A0 =A0 </span><span style=3D"color:#008">if</span><span style=3D"color:#66=
0">(</span><span style>value </span><span style=3D"color:#660">=3D=3D</span=
><span style> uninitialized_value</span><span style=3D"color:#660">)</span>=
<span style> </span><span style=3D"color:#660">{</span><span style><br>
=A0 =A0 =A0 </span><span style=3D"color:#008">throw</span><span style> std<=
/span><span style=3D"color:#660">::</span><span style>logic_error</span><sp=
an style=3D"color:#660">();</span><span style><br>=A0 =A0 </span><span styl=
e=3D"color:#660">}</span><span style><br>
<br>=A0 =A0 </span><span style=3D"color:#008">return</span><span style> val=
ue</span><span style=3D"color:#660">;</span><span style><br>=A0 </span><spa=
n style=3D"color:#660">}</span><span style><br><br>=A0 </span><span style=
=3D"color:#800">// ...</span><span style><br>
</span><span style=3D"color:#660">};</span><span style><br></span></div></c=
ode></div><br>Which gives effectively :<p></p><p><span style=3D"font-family=
:courier new,monospace">Size of Player:1<br>Size of optional<Player>:=
2<br>
Size of degenerate<Player, Player(-1)>:1</span><br></p><p>I find lots=
of uses for this. What do you think?<span class=3D"HOEnZb"><font color=3D"=
#888888"><br></font></span></p></div><span class=3D"HOEnZb"><font color=3D"=
#888888">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@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>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c342ec380b2804e554a38c--
.
Author: the.ultimate.koala@gmail.com
Date: Sun, 1 Sep 2013 11:35:46 -0700 (PDT)
Raw View
------=_Part_2407_27352654.1378060546649
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Indeed. The type T would be effectively constrained to whatever types are=
=20
permitted for non-type, non-template template parameters. (Standard =A714.1=
/4)
These are :
- integral or enumeration type,
- pointer to object or pointer to function,
- lvalue reference to object or lvalue reference to function,
- pointer to member,
- std::nullptr_t
Among these, I think that only lvalue reference to object would have=20
EXTREMELY WEIRD behaviour, and would have to be explicitly excluded.
I think that the main uses of std::degenerate would be on integral and enum=
=20
types, where the default value should be other than the zero of the type.
On Sunday, September 1, 2013 6:06:05 PM UTC+2, Maurice Bos wrote:
>
> A similar situation occurs when combining optional<T> and variant<T...>:=
=20
> optional<variant<int, float, string>>. The variant probably keeps some=20
> integer (e.g. 0,1, or 2) to keep track of whether it contains a int, floa=
t=20
> or a string. The optional could, instead of adding a boolean, somehow sto=
re=20
> a value that has no meaning for the variant (e.g. -1 or 3) in that intege=
r=20
> when the variant is not set.
>
> However, the degenerate<typename T, T> solution would not be a solution i=
n=20
> this case. (Maybe optional<> should be specialzed for varaiants, or=20
> optional_variant should exist, or variant<void, int, float, string> shoud=
=20
> be used instead, but I'm wondering if there might exist a solution for bo=
th=20
> this situation and the situations degenerate<template T, T> solves, since=
=20
> they are similar.)
>
> -Maurice-
>
>
>
> 2013/9/1 <the.ultim...@gmail.com <javascript:>>
>
>> Hello,
>>
>> I am sending this idea for feedback from the community. I don't know if=
=20
>> any prior work has been down on this, or if this can be done with=20
>> std::optional. If so please let me know.
>>
>> Let's say that you want to implement the Tic-Tac-Toe game, and you want=
=20
>> to store the state of the board into an array of 9 values. The C way to =
do=20
>> it would be:
>>
>> enum SquareState { EMPTY, CROSS, NOUGHT };
>> SquareState board[9];
>>
>> The C++98 way to do it would be:
>>
>> enum SquareState { EMPTY, CROSS, NOUGHT };
>> std::vector<SquareState> board(9);
>>
>> The C++11 way would add:
>>
>> enum class SquareState { EMPTY, CROSS, NOUGHT };
>> std::array<SquareState, 9> board;
>>
>> Now, you're happy. Your code is a lot cleaner, but then, you have to=20
>> store the player-to-play. What type will you use? Since you have to=20
>> associate either CROSS or NOUGHT to each player, you would use the same=
=20
>> constant.
>>
>> enum class SquareState { EMPTY, CROSS, NOUGHT };
>> std::array<SquareState, 9> board;
>> SquareState player_to_play;
>>
>> Now, your spider sense tells you that player_to_play should not be a=20
>> "SquareState". That should be the other way around.
>>
>> enum class Player { EMPTY, CROSS, NOUGHT };
>> std::array<Player, 9> board;
>> Player player_to_play;
>>
>> But now: who is this Player::EMPTY person? And then, you remember that=
=20
>> you really like the work of the C++ community, and upgrade to experiment=
al=20
>> C++14 :
>>
>> enum class Player { CROSS, NOUGHT };
>> std::array<std::optional<Player>, 9> board;
>> Player player_to_play;
>>
>> You like it better. But you realize that this may have substantially=20
>> increased demand in memory. Indeed, optional effectively adds "undefined=
"=20
>> to the set of values already encodable by its template parameter. Indeed=
,=20
>> if you compare sizeof's of Player and std::optional<Player>, you get :
>>
>> Size of Player:4
>> Size of optional<Player>:8
>>
>> Even setting the enum storage type to char gives:
>>
>> Size of Player:1
>> Size of optional<Player>:2
>>
>> And this makes you the laughing stock of the C programmers, even with th=
e=20
>> semantic improvement, because you're using two bytes to encode a set of =
3=20
>> values.
>>
>> The proposal would be of a class template which:
>>
>> - Would be a drop-in replacement for optional, i.e. have the same=20
>> interface and close enough semantics,
>> - Would set apart a value from the encodable set, and treat it as=20
>> undefined.
>>
>> For example :
>>
>> template<class T, T uninitialized_value>
>> class degenerate {
>> T value;
>> public:
>> degenerate(T v =3D uninitialized_value)=20
>> : value(v) {}
>>
>> T& operator* () {
>> if(value =3D=3D uninitialized_value) {
>> throw std::logic_error();
>> }
>>
>> return value;
>> }
>>
>> // ...
>> };
>>
>> Which gives effectively :
>>
>> Size of Player:1
>> Size of optional<Player>:2
>> Size of degenerate<Player, Player(-1)>:1
>>
>> I find lots of uses for this. What do you think?
>>
>> --=20
>> =20
>> ---=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:>.
>> Visit this group at=20
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2407_27352654.1378060546649
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Indeed. The type T would be effectively constrained to wha=
tever types are permitted for non-type, non-template template parameters. (=
Standard =A714.1/4)<br><br>These are :<br><ul><li> integral or enumeration =
type,</li><li> pointer to object or pointer to function,</li><li> lvalue re=
ference to object or lvalue reference to function,</li><li> pointer to memb=
er,</li><li>std::nullptr_t</li></ul>Among these, I think that only lvalue r=
eference to object would have EXTREMELY WEIRD behaviour, and would have to =
be explicitly excluded.<br><br>I think that the main uses of std::degenerat=
e would be on integral and enum types, where the default value should be ot=
her than the zero of the type.<br><br>On Sunday, September 1, 2013 6:06:05 =
PM UTC+2, Maurice Bos wrote:<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">A similar situation occurs when combining optional<T> =
and variant<T...>: optional<variant<int, float, string>>.=
The variant probably keeps some integer (e.g. 0,1, or 2) to keep track of =
whether it contains a int, float or a string. The optional could, instead o=
f adding a boolean, somehow store a value that has no meaning for the varia=
nt (e.g. -1 or 3) in that integer when the variant is not set.<br>
<br>However, the degenerate<typename T, T> solution would not be a so=
lution in this case. (Maybe optional<> should be specialzed for varai=
ants, or optional_variant should exist, or variant<void, int, float, str=
ing> shoud be used instead, but I'm wondering if there might exist a sol=
ution for both this situation and the situations degenerate<template T, =
T> solves, since they are similar.)<br>
<br>-Maurice-<br><br></div><div><br><br><div class=3D"gmail_quote">2013/9/1=
<span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"DXVnEjjWwwcJ">the.ultim...@gmail.com</a>></span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hello,<br><br>I am sending =
this idea for feedback from the community. I don't know if any prior work h=
as been down on this, or if this can be done with std::optional. If so plea=
se let me know.<br>
<br>Let's say that you want to implement the Tic-Tac-Toe game, and you want=
to store the state of the board into an array of 9 values. The C way to do=
it would be:<br><br><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break=
-word">
<code><div><span> </span><span style=3D"color:#008">enum</span=
><span> </span><span style=3D"color:#606">SquareState</span><span> </span><=
span style=3D"color:#660">{</span><span> EMPTY</span><span style=3D"color:#=
660">,</span><span> CROSS</span><span style=3D"color:#660">,</span><span> N=
OUGHT </span><span style=3D"color:#660">};</span><span><br>
</span><span style=3D"color:#606">SquareState</span><span> bo=
ard</span><span style=3D"color:#660">[</span><span style=3D"color:#066">9</=
span><span style=3D"color:#660">];</span><span><br></span></div></code></di=
v>
<br>The C++98 way to do it would be:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span> </span><span s=
tyle=3D"color:#008">enum</span><span> </span><span style=3D"color:#606">Squ=
areState</span><span> </span><span style=3D"color:#660">{</span><span> EMPT=
Y</span><span style=3D"color:#660">,</span><span> CROSS</span><span style=
=3D"color:#660">,</span><span> NOUGHT </span><span style=3D"color:#660">};<=
/span><span><br>
std</span><span style=3D"color:#660">::</span><span>vector</s=
pan><span style=3D"color:#660"><</span><span style=3D"color:#606">Square=
State</span><span style=3D"color:#660">></span><span> board</span><span =
style=3D"color:#660">(</span><span style=3D"color:#066">9</span><span style=
=3D"color:#660">);</span><span><br>
</span></div></code></div><br>The C++11 way would add:<br><br><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> &nb=
sp; </span><span style=3D"color:#008">enum</span><span> </span><span style=
=3D"color:#008">class</span><span> </span><span style=3D"color:#606">Square=
State</span><span> </span><span style=3D"color:#660">{</span><span> EMPTY</=
span><span style=3D"color:#660">,</span><span> CROSS</span><span style=3D"c=
olor:#660">,</span><span> NOUGHT </span><span style=3D"color:#660">};</span=
><span><br>
std</span><span style=3D"color:#660">::</span><span>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">SquareS=
tate</span><span style=3D"color:#660">,</span><span> </span><span style=3D"=
color:#066">9</span><span style=3D"color:#660">></span><span> board</spa=
n><span style=3D"color:#660">;</span><span><br>
</span></div></code></div><br>Now, you're happy. Your code is a lot cleaner=
, but then, you have to store the player-to-play. What type will you use? S=
ince you have to associate either CROSS or NOUGHT to each player, you would=
use the same constant.<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span> </span><span style=3D"color:#008">enum</span><span> </=
span><span style=3D"color:#008">class</span><span> </span><span style=3D"co=
lor:#606">SquareState</span><span> </span><span style=3D"color:#660">{</spa=
n><span> EMPTY</span><span style=3D"color:#660">,</span><span> CROSS</span>=
<span style=3D"color:#660">,</span><span> NOUGHT </span><span style=3D"colo=
r:#660">};</span><span><br>
std</span><span style=3D"color:#660">::</span><span>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">SquareS=
tate</span><span style=3D"color:#660">,</span><span> </span><span style=3D"=
color:#066">9</span><span style=3D"color:#660">></span><span> board</spa=
n><span style=3D"color:#660">;</span><span><br>
</span><span style=3D"color:#606">SquareState</span><span> pl=
ayer_to_play</span><span style=3D"color:#660">;</span><span><br></span></di=
v></code></div><br>Now, your spider sense tells you that player_to_play sho=
uld not be a "SquareState". That should be the other way around.<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span> </span><span style=3D"color:#008">enum</span><span> </=
span><span style=3D"color:#008">class</span><span> </span><span style=3D"co=
lor:#606">Player</span><span> </span><span style=3D"color:#660">{</span><sp=
an> EMPTY</span><span style=3D"color:#660">,</span><span> CROSS</span><span=
style=3D"color:#660">,</span><span> NOUGHT </span><span style=3D"color:#66=
0">};</span><span><br>
std</span><span style=3D"color:#660">::</span><span>array</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#606">Player<=
/span><span style=3D"color:#660">,</span><span> </span><span style=3D"color=
:#066">9</span><span style=3D"color:#660">></span><span> board</span><sp=
an style=3D"color:#660">;</span><span><br>
</span><span style=3D"color:#606">Player</span><span> player_=
to_play</span><span style=3D"color:#660">;</span><span><br></span></div></c=
ode></div><br>But now: who is this Player::EMPTY person? And then, you reme=
mber that you really like the work of the C++ community, and upgrade to exp=
erimental C++14 :<br>
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span> </span><span style=3D"color:#008">enum</span><span> </=
span><span style=3D"color:#008">class</span><span> </span><span style=3D"co=
lor:#606">Player</span><span> </span><span style=3D"color:#660">{</span><sp=
an> CROSS</span><span style=3D"color:#660">,</span><span> NOUGHT </span><sp=
an style=3D"color:#660">};</span><span><br>
std</span><span style=3D"color:#660">::</span><span>array</sp=
an><span style=3D"color:#660"><</span><span>std</span><span style=3D"col=
or:#660">::</span><span>optional</span><span style=3D"color:#660"><</spa=
n><span style=3D"color:#606">Playe<wbr>r</span><span style=3D"color:#660">&=
gt;,</span><span> </span><span style=3D"color:#066">9</span><span style=3D"=
color:#660">></span><span> board</span><span style=3D"color:#660">;</spa=
n><span><br>
</span><span style=3D"color:#606">Player</span><span> player_=
to_play</span><span style=3D"color:#660">;</span><span><br></span></div></c=
ode></div><br>You like it better. But you realize that this may have substa=
ntially increased demand in memory. Indeed, optional effectively adds "unde=
fined" to the set of values already encodable by its template parameter. In=
deed, if you compare sizeof's of Player and std::optional<Player>, yo=
u get :<br>
<br><span style=3D"font-family:courier new,monospace">Size of Player:4<br>S=
ize of optional<Player>:8</span><br><br>Even setting the enum storage=
type to char gives:<br><br><span style=3D"font-family:courier new,monospac=
e">Size of Player:1<br>
Size of optional<Player>:2<br></span><br>And this makes you the laugh=
ing stock of the C programmers, even with the semantic improvement, because=
you're using two bytes to encode a set of 3 values.<br><br>The proposal wo=
uld be of a class template which:<br>
<ul><li>Would be a drop-in replacement for optional, i.e. have the same int=
erface and close enough semantics,</li><li>Would set apart a value from the=
encodable set, and treat it as undefined.</li></ul><p>For example :</p>
<p></p><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">&l=
t;</span><span style=3D"color:#008">class</span><span> T</span><span style=
=3D"color:#660">,</span><span> T uninitialized_value</span><span style=3D"c=
olor:#660">></span><span><br>
</span><span style=3D"color:#008">class</span><span> degenerate </span><spa=
n style=3D"color:#660">{</span><span><br> T value</span><span style=
=3D"color:#660">;</span><span><br></span><span style=3D"color:#008">public<=
/span><span style=3D"color:#660">:</span><span><br>
degenerate</span><span style=3D"color:#660">(</span><span>T v </span=
><span style=3D"color:#660">=3D</span><span> uninitialized_value</span><spa=
n style=3D"color:#660">)</span><span> <br> </span><span style=
=3D"color:#660">:</span><span> value</span><span style=3D"color:#660">(</sp=
an><span>v</span><span style=3D"color:#660">)</span><span> </span><span sty=
le=3D"color:#660">{}</span><span><br>
<br> T</span><span style=3D"color:#660">&</span><span> </span><sp=
an style=3D"color:#008">operator</span><span style=3D"color:#660">*</span><=
span> </span><span style=3D"color:#660">()</span><span> </span><span style=
=3D"color:#660">{</span><span><br>
</span><span style=3D"color:#008">if</span><span style=3D"col=
or:#660">(</span><span>value </span><span style=3D"color:#660">=3D=3D</span=
><span> uninitialized_value</span><span style=3D"color:#660">)</span><span>=
</span><span style=3D"color:#660">{</span><span><br>
</span><span style=3D"color:#008">throw</span><span> s=
td</span><span style=3D"color:#660">::</span><span>logic_error</span><span =
style=3D"color:#660">();</span><span><br> </span><span style=
=3D"color:#660">}</span><span><br>
<br> </span><span style=3D"color:#008">return</span><span> val=
ue</span><span style=3D"color:#660">;</span><span><br> </span><span s=
tyle=3D"color:#660">}</span><span><br><br> </span><span style=3D"colo=
r:#800">// ...</span><span><br>
</span><span style=3D"color:#660">};</span><span><br></span></div></code></=
div><br>Which gives effectively :<p></p><p><span style=3D"font-family:couri=
er new,monospace">Size of Player:1<br>Size of optional<Player>:2<br>
Size of degenerate<Player, Player(-1)>:1</span><br></p><p>I find lots=
of uses for this. What do you think?<span><font color=3D"#888888"><br></fo=
nt></span></p></div><span><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" 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"=
DXVnEjjWwwcJ">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"DXVnEjjWwwcJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</font></span></blockquote></div><br></div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2407_27352654.1378060546649--
.
Author: the.ultimate.koala@gmail.com
Date: Sun, 1 Sep 2013 11:47:24 -0700 (PDT)
Raw View
------=_Part_1420_11061537.1378061244986
Content-Type: text/plain; charset=ISO-8859-1
>
> A similar situation occurs when combining optional<T> and variant<T...>:
> optional<variant<int, float, string>>. The variant probably keeps some
> integer (e.g. 0,1, or 2) to keep track of whether it contains a int, float
> or a string. The optional could, instead of adding a boolean, somehow store
> a value that has no meaning for the variant (e.g. -1 or 3) in that integer
> when the variant is not set.
>
> However, the degenerate<typename T, T> solution would not be a solution in
> this case. (Maybe optional<> should be specialzed for varaiants, or
> optional_variant should exist, or variant<void, int, float, string> shoud
> be used instead, but I'm wondering if there might exist a solution for both
> this situation and the situations degenerate<template T, T> solves, since
> they are similar.)
>
If an optional_variant<> should exist, maybe degenerate<> could be a
building block for the selector. I'm not sure. The uses I see for
degenerate<> are :
- for all the cases of integral or enum types where the programmer
defines an extra symbolic constant to represent the undefined-ness,
- to store a pointer value, and give the undefinedness semantic to
nullptr.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1420_11061537.1378061244986
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">=
A similar situation occurs when combining optional<T> and variant<=
T...>: optional<variant<int, float, string>>. The variant pr=
obably keeps some integer (e.g. 0,1, or 2) to keep track of whether it cont=
ains a int, float or a string. The optional could, instead of adding a bool=
ean, somehow store a value that has no meaning for the variant (e.g. -1 or =
3) in that integer when the variant is not set.<br><br>However, the degener=
ate<typename T, T> solution would not be a solution in this case. (Ma=
ybe optional<> should be specialzed for varaiants, or optional_varian=
t should exist, or variant<void, int, float, string> shoud be used in=
stead, but I'm wondering if there might exist a solution for both this situ=
ation and the situations degenerate<template T, T> solves, since they=
are similar.)<br></blockquote>
<br>If an optional_variant<> should exist, maybe degenerate<> c=
ould be a building block for the selector. I'm not sure. The uses I see for=
degenerate<> are :<br><ul><li>for all the cases of integral or enum =
types where the programmer defines an extra symbolic constant to represent =
the undefined-ness,</li><li>to store a pointer value, and give the undefine=
dness semantic to nullptr.<br></li></ul></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1420_11061537.1378061244986--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 01 Sep 2013 23:58:54 +0200
Raw View
This is a multi-part message in MIME format.
--------------000807010908000103030201
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 01/09/13 10:43, the.ultimate.koala@gmail.com a =E9crit :
>
>
> The proposal would be of a class template which:
>
> * Would be a drop-in replacement for optional, i.e. have the same
> interface and close enough semantics,
> * Would set apart a value from the encodable set, and treat it as
> undefined.
>
> For example :
>
> |
> template<classT,T uninitialized_value>
> classdegenerate {
> T value;
> public:
> degenerate(T v =3Duninitialized_value)
> :value(v){}
>
> T&operator*(){
> if(value =3D=3Duninitialized_value){
> throwstd::logic_error();
> }
>
> returnvalue;
> }
>
> // ...
> };
> |
>
> Which gives effectively :
>
> Size of Player:1
> Size of optional<Player>:2
> Size of degenerate<Player, Player(-1)>:1
>
> I find lots of uses for this. What do you think?
>
>
Hi,
I think that this class could be used as an excellent building block for=20
an optimized optional implementation, when e.g. a given trait=20
is_degenerated<T> is true_type. In this case the optional<t>=20
implementation coul dbe based on degenerate<T, degenerate_value<T>::value>.
In, your example, if the following was declared
template <>
struct is_degenerate<Player> : true_type {};
template <>
struct degenerate_value<Player> : integral_constant<Player, Player(-1)> {};
sizeof (optional<Player>) could be equal to sizeof(Player).
The standard would not need to include the class degenerate, but only=20
the traits is_degenerate and degenerate_value and some constraints on=20
the sizeof optional<T> when is_degenerate<T> is true_type.
Best,
Vicente
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--------------000807010908000103030201
Content-Type: text/html; charset=ISO-8859-1
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Le 01/09/13 10:43,
<a class="moz-txt-link-abbreviated" href="mailto:the.ultimate.koala@gmail.com">the.ultimate.koala@gmail.com</a> a écrit :<br>
</div>
<blockquote
cite="mid:18ab4801-260a-4228-8a7b-a71248b624e2@isocpp.org"
type="cite">
<div dir="ltr"><br>
<br>
The proposal would be of a class template which:<br>
<ul>
<li>Would be a drop-in replacement for optional, i.e. have the
same interface and close enough semantics,</li>
<li>Would set apart a value from the encodable set, and treat
it as undefined.</li>
</ul>
<p>For example :</p>
<div class="prettyprint" style="background-color: rgb(250, 250,
250); border-color: rgb(187, 187, 187); border-style: solid;
border-width: 1px; word-wrap: break-word;"><code
class="prettyprint">
<div class="subprettyprint"><span style="color: #008;"
class="styled-by-prettify">template</span><span
style="color: #660;" class="styled-by-prettify"><</span><span
style="color: #008;" class="styled-by-prettify">class</span><span
style="color: #000;" class="styled-by-prettify"> T</span><span
style="color: #660;" class="styled-by-prettify">,</span><span
style="color: #000;" class="styled-by-prettify"> T
uninitialized_value</span><span style="color: #660;"
class="styled-by-prettify">></span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #008;"
class="styled-by-prettify">class</span><span
style="color: #000;" class="styled-by-prettify">
degenerate </span><span style="color: #660;"
class="styled-by-prettify">{</span><span style="color:
#000;" class="styled-by-prettify"><br>
T value</span><span style="color: #660;"
class="styled-by-prettify">;</span><span style="color:
#000;" class="styled-by-prettify"><br>
</span><span style="color: #008;"
class="styled-by-prettify">public</span><span
style="color: #660;" class="styled-by-prettify">:</span><span
style="color: #000;" class="styled-by-prettify"><br>
degenerate</span><span style="color: #660;"
class="styled-by-prettify">(</span><span style="color:
#000;" class="styled-by-prettify">T v </span><span
style="color: #660;" class="styled-by-prettify">=</span><span
style="color: #000;" class="styled-by-prettify">
uninitialized_value</span><span style="color: #660;"
class="styled-by-prettify">)</span><span style="color:
#000;" class="styled-by-prettify"> <br>
</span><span style="color: #660;"
class="styled-by-prettify">:</span><span style="color:
#000;" class="styled-by-prettify"> value</span><span
style="color: #660;" class="styled-by-prettify">(</span><span
style="color: #000;" class="styled-by-prettify">v</span><span
style="color: #660;" class="styled-by-prettify">)</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{}</span><span
style="color: #000;" class="styled-by-prettify"><br>
<br>
T</span><span style="color: #660;"
class="styled-by-prettify">&</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #008;" class="styled-by-prettify">operator</span><span
style="color: #660;" class="styled-by-prettify">*</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">()</span><span
style="color: #000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #008;"
class="styled-by-prettify">if</span><span style="color:
#660;" class="styled-by-prettify">(</span><span
style="color: #000;" class="styled-by-prettify">value </span><span
style="color: #660;" class="styled-by-prettify">==</span><span
style="color: #000;" class="styled-by-prettify">
uninitialized_value</span><span style="color: #660;"
class="styled-by-prettify">)</span><span style="color:
#000;" class="styled-by-prettify"> </span><span
style="color: #660;" class="styled-by-prettify">{</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #008;"
class="styled-by-prettify">throw</span><span
style="color: #000;" class="styled-by-prettify"> std</span><span
style="color: #660;" class="styled-by-prettify">::</span><span
style="color: #000;" class="styled-by-prettify">logic_error</span><span
style="color: #660;" class="styled-by-prettify">();</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #660;"
class="styled-by-prettify">}</span><span style="color:
#000;" class="styled-by-prettify"><br>
<br>
</span><span style="color: #008;"
class="styled-by-prettify">return</span><span
style="color: #000;" class="styled-by-prettify"> value</span><span
style="color: #660;" class="styled-by-prettify">;</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #660;"
class="styled-by-prettify">}</span><span style="color:
#000;" class="styled-by-prettify"><br>
<br>
</span><span style="color: #800;"
class="styled-by-prettify">// ...</span><span
style="color: #000;" class="styled-by-prettify"><br>
</span><span style="color: #660;"
class="styled-by-prettify">};</span><span style="color:
#000;" class="styled-by-prettify"><br>
</span></div>
</code></div>
<br>
Which gives effectively :
<p><span style="font-family: courier new,monospace;">Size of
Player:1<br>
Size of optional<Player>:2<br>
Size of degenerate<Player, Player(-1)>:1</span><br>
</p>
<p>I find lots of uses for this. What do you think?<br>
</p>
</div>
<br>
</blockquote>
Hi,<br>
<br>
I think that this class could be used as an excellent building block
for an optimized optional implementation, when e.g. a given trait
is_degenerated<T> is true_type. In this case the
optional<t> implementation coul dbe based on degenerate<T,
degenerate_value<T>::value>.<br>
<br>
In, your example, if the following was declared<br>
<br>
template <><br>
struct is_degenerate<Player> : true_type {};<br>
template <><br>
struct degenerate_value<Player> : integral_constant<Player,
Player(-1)> {};<br>
<br>
sizeof (optional<Player>) could be equal to sizeof(Player).<br>
<br>
The standard would not need to include the class degenerate, but
only the traits is_degenerate and degenerate_value and some
constraints on the sizeof optional<T> when
is_degenerate<T> is true_type.<br>
<br>
Best,<br>
Vicente<br>
<br>
<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--------------000807010908000103030201--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 1 Sep 2013 21:05:31 -0700 (PDT)
Raw View
------=_Part_2258_20170373.1378094732015
Content-Type: text/plain; charset=ISO-8859-1
On Sunday, September 1, 2013 4:43:07 PM UTC+8, the.ultim...@gmail.com wrote:
>
> Would set apart a value from the encodable set, and treat it as undefined.
>
What value?
> Size of degenerate<Player, Player(-1)>:1
>
Ohh -1. Of course. And I'm supposed to specify that it's -1. Wonderful.
> I find lots of uses for this. What do you think?
>
I think that degenerate is nothing like the enumeration it is supposed to
adapt. It's a class type, for starters.
I think that enumerations should be able to inherit from other enumerations
as an underlying type, such as to be able to represent supersets. This is
an extremely common use case and isn't limited in general to just one extra
"none" enumerator.
Following the degenerate pattern, the user could keep adding ever-more
degenerate cases. What if we want to represent graphical tiles outside the
playing area, now we have X, O, "no player," and "not on the board," with
the latter two not having proper names at all, but relying on the reader's
inference about what exact set the enumeration (or non-enumeration) is
supposed to cover.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2258_20170373.1378094732015
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, September 1, 2013 4:43:07 PM UTC+8, the=
..ultim...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
dir=3D"ltr">Would set apart a value from the encodable set, and treat it a=
s undefined.<span style=3D"font-family:courier new,monospace"></span></div>=
</blockquote><div><br>What value?<br> </div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><span style=3D"font-family:courier new,=
monospace">Size of degenerate<Player, Player(-1)>:1</span><br></div><=
/blockquote><div><br>Ohh -1. Of course. And I'm supposed to specify that it=
's -1. Wonderful.<br> <br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><p>I find lots of uses for this. What do you think?=
<br></p></div></blockquote><div>I think that <span style=3D"font-family: co=
urier new,monospace;">degenerate</span> is nothing like the enumeration it =
is supposed to adapt. It's a class type, for starters.<br><br>I think that =
enumerations should be able to inherit from other enumerations as an underl=
ying type, such as to be able to represent supersets. This is an extremely =
common use case and isn't limited in general to just one extra "none" enume=
rator.<br><br>Following the <span style=3D"font-family: courier new,monospa=
ce;">degenerate</span> pattern, the user could keep adding ever-more degene=
rate cases. What if we want to represent graphical tiles outside the playin=
g area, now we have X, O, "no player," and "not on the board," with the lat=
ter two not having proper names at all, but relying on the reader's inferen=
ce about what exact set the enumeration (or non-enumeration) is supposed to=
cover.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2258_20170373.1378094732015--
.
Author: the.ultimate.koala@gmail.com
Date: Sun, 1 Sep 2013 21:44:47 -0700 (PDT)
Raw View
------=_Part_1545_13802824.1378097087567
Content-Type: text/plain; charset=ISO-8859-1
Vicente,
I think that this class could be used as an excellent building block for an
> optimized optional implementation, when e.g. a given trait
> is_degenerated<T> is true_type. In this case the optional<t> implementation
> coul dbe based on degenerate<T, degenerate_value<T>::value>.
>
I thought about this. But degenerate does not have the exact same
semantics as optional. Indeed:
- given a type T containing n values, the type optional<T> effectively
contains n + 1 values.
- given a type T containing n values, the type degenerate <T, v> still
contains n values, and actually implements optional<T - {n}>
In, your example, if the following was declared
>
> template <>
> struct is_degenerate<Player> : true_type {};
> template <>
> struct degenerate_value<Player> : integral_constant<Player, Player(-1)> {};
>
> sizeof (optional<Player>) could be equal to sizeof(Player).
>
> The standard would not need to include the class degenerate, but only the
> traits is_degenerate and degenerate_value and some constraints on the
> sizeof optional<T> when is_degenerate<T> is true_type.
>
I think specifying the degenerate_value as part of the variable type is
useful. You may be implementing a protocol which, at two places, uses two
different values for indicating absence of a specific data, e.g. "coffee
type" being REGULAR = 1, DECAF = 2, ESPRESSO = 3, and at some place the
"undefined" value is 0, and at another place the undefined value is -1.
By the way, I did not know about integral_constant. Thank you.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1545_13802824.1378097087567
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Vicente,<br><br><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
I think that this class could be used as an excellent building block
for an optimized optional implementation, when e.g. a given trait
is_degenerated<T> is true_type. In this case the
optional<t> implementation coul dbe based on degenerate<T,
degenerate_value<T>::value>.<br>
</div></blockquote><div><br> I thought about this. But degenerate =
does not have the exact same semantics as optional. Indeed:<br><ul><li>give=
n a type T containing n values, the type optional<T> effectively cont=
ains n + 1 values.</li><li>given a type T containing n values, the type deg=
enerate <T, v> still contains n values, and actually implements optio=
nal<T - {n}><br></li></ul></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div bgcolor=3D"#FFFFFF" text=3D"#000000">
In, your example, if the following was declared<br>
<br>
template <><br>
struct is_degenerate<Player> : true_type {};<br>
template <><br>
struct degenerate_value<Player> : integral_constant<Player,
Player(-1)> {};<br>
<br>
sizeof (optional<Player>) could be equal to sizeof(Player).<br>
<br>
The standard would not need to include the class degenerate, but
only the traits is_degenerate and degenerate_value and some
constraints on the sizeof optional<T> when
is_degenerate<T> is true_type.<br></div></blockquote><div> <=
br>I think specifying the degenerate_value as part of the variable type is =
useful. You may be implementing a protocol which, at two places, uses two d=
ifferent values for indicating absence of a specific data, e.g. "coffee typ=
e" being REGULAR =3D 1, DECAF =3D 2, ESPRESSO =3D 3, and at some place the =
"undefined" value is 0, and at another place the undefined value is -1.<br>=
<br>By the way, I did not know about integral_constant. Thank you.<br></div=
></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1545_13802824.1378097087567--
.
Author: the.ultimate.koala@gmail.com
Date: Sun, 1 Sep 2013 22:13:08 -0700 (PDT)
Raw View
------=_Part_1741_14670893.1378098788777
Content-Type: text/plain; charset=ISO-8859-1
David,
What value?
>
Ohh -1. Of course. And I'm supposed to specify that it's -1. Wonderful.
>
>
Of course I'm supposed to specify it. With current state of art, in C++,
you can only encode values within sets whose cardinality is a power of 2.
You can't specify a type like { REGULAR, DECAF, ESPRESSO } and store it to
a 3-state location. The bare minimum is two bits, which can encode 4 values.
In my example, the enum class Player (let's assume I specified "char"
storage) takes its values from a set whose cardinality is 256. I specified
only two symbolic constants for values 0 and 1. (resp. CROSS and NOUGHT).
Player(-1) is a perfectly valid Player value, just like Player(124). These
do not get symbolic constant support in my program, that's it.
> I think that degenerate is nothing like the enumeration it is supposed to
> adapt.
>
So do I. optional<int> is nothing like int. It not supposed to "adapt" the
enumeration. It is supposed to give optional semantics to my enum, for
which I will not use all 256 values.
It's a class type, for starters.
>
degenerate<T> is POD. "class" means "user-defined type"
>
> I think that enumerations should be able to inherit from other
> enumerations as an underlying type, such as to be able to represent
> supersets. This is an extremely common use case and isn't limited in
> general to just one extra "none" enumerator.
>
Indeed. MAX_VALUE, NB_FLAGS, etc. I too would wish for better compiler
support for enums. I would wish to have some type traits that give me the
number of defined symbolic constants, what is the min, max constant, .
Following the degenerate pattern, the user could keep adding ever-more
> degenerate cases. What if we want to represent graphical tiles outside the
> playing area, now we have X, O, "no player," and "not on the board," with
> the latter two not having proper names at all, but relying on the reader's
> inference about what exact set the enumeration (or non-enumeration) is
> supposed to cover.
>
Indeed. It is supposed to mimic optional<T> semantics, which has only one
"degenerate" case.
Laurent
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1741_14670893.1378098788777
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">David,<br><br><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div>What value? <br></div></div></blockquote><blockquote=
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"><div>Ohh -1. Of course. =
And I'm supposed to specify that it's -1. Wonderful.<br> <br></div></d=
iv></blockquote><div><br>Of course I'm supposed to specify it. With current=
state of art, in C++, you can only encode values within sets whose cardina=
lity is a power of 2. You can't specify a type like { REGULAR, DECAF, ESPRE=
SSO } and store it to a 3-state location. The bare minimum is two bits, whi=
ch can encode 4 values.<br><br>In my example, the enum class Player (let's =
assume I specified "char" storage) takes its values from a set whose cardin=
ality is 256. I specified only two symbolic constants for values 0 and 1. (=
resp. CROSS and NOUGHT). Player(-1) is a perfectly valid Player value, just=
like Player(124). These do not get symbolic constant support in my program=
, that's it.<br> </div><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"><div></div>I think that <span style=3D"font-family:courier n=
ew,monospace">degenerate</span> is nothing like the enumeration it is suppo=
sed to adapt. </div></blockquote><div> </div><div>So do I. optional<=
;int> is nothing like int. It not supposed to "adapt" the enumeration. I=
t is supposed to give optional semantics to my enum, for which I will not u=
se all 256 values.<br><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div dir=3D"ltr">It's a class type, for starters.<br></div></blockquote><=
div><br>degenerate<T> is POD. "class" means "user-defined type"<br></=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>=
I think that enumerations should be able to inherit from other enumerations=
as an underlying type, such as to be able to represent supersets. This is =
an extremely common use case and isn't limited in general to just one extra=
"none" enumerator.<br></div></div></blockquote><div><br>Indeed. MAX_VALUE,=
NB_FLAGS, etc. I too would wish for better compiler support for enums. I w=
ould wish to have some type traits that give me the number of defined symbo=
lic constants, what is the min, max constant, .<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Following the <span st=
yle=3D"font-family:courier new,monospace">degenerate</span> pattern, the us=
er could keep adding ever-more degenerate cases. What if we want to represe=
nt graphical tiles outside the playing area, now we have X, O, "no player,"=
and "not on the board," with the latter two not having proper names at all=
, but relying on the reader's inference about what exact set the enumeratio=
n (or non-enumeration) is supposed to cover.<br></div></div></blockquote><d=
iv><br>Indeed. It is supposed to mimic optional<T> semantics, which h=
as only one "degenerate" case.<br><br>Laurent<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1741_14670893.1378098788777--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 1 Sep 2013 22:42:44 -0700 (PDT)
Raw View
------=_Part_2319_6567170.1378100564826
Content-Type: text/plain; charset=ISO-8859-1
On Monday, September 2, 2013 1:13:08 PM UTC+8, the.ultim...@gmail.com wrote:
>
> David,
>
> What value?
>>
> Ohh -1. Of course. And I'm supposed to specify that it's -1. Wonderful.
>>
>>
>
> Of course I'm supposed to specify it. With current state of art, in C++,
> you can only encode values within sets whose cardinality is a power of 2.
> You can't specify a type like { REGULAR, DECAF, ESPRESSO } and store it to
> a 3-state location. The bare minimum is two bits, which can encode 4 values.
>
So it turns out that it's not "not part of the encodable set" after all.
> In my example, the enum class Player (let's assume I specified "char"
> storage) takes its values from a set whose cardinality is 256. I specified
> only two symbolic constants for values 0 and 1. (resp. CROSS and NOUGHT).
> Player(-1) is a perfectly valid Player value, just like Player(124). These
> do not get symbolic constant support in my program, that's it.
>
Now you have to be concerned with encoding, both in selection of the
underlying type and the extra state-value, which violates separation of
concerns.
Not only don't you have symbolic support for one value (or N values,
however many times this concept is applied), you don't have access to any
interface designed for the underlying enumeration, except by implicit
conversion.
I think that degenerate is nothing like the enumeration it is supposed to
>> adapt.
>>
>
> So do I. optional<int> is nothing like int. It not supposed to "adapt" the
> enumeration. It is supposed to give optional semantics to my enum, for
> which I will not use all 256 values.
>
Adding a state machine construct to an int is different from adding a state
to a state machine.
> It's a class type, for starters.
>>
>
> degenerate<T> is POD. "class" means "user-defined type"
>
Enumerations are user-defined types which are not classes.
> I think that enumerations should be able to inherit from other
>> enumerations as an underlying type, such as to be able to represent
>> supersets. This is an extremely common use case and isn't limited in
>> general to just one extra "none" enumerator.
>>
>
> Indeed. MAX_VALUE, NB_FLAGS, etc. I too would wish for better compiler
> support for enums. I would wish to have some type traits that give me the
> number of defined symbolic constants, what is the min, max constant, .
>
Language support, not compiler support. You can do already plenty by
defining traits on your own enumeration types, and following conventions,
but some conventions and traits would need formalization before the
language can move forward.
> Following the degenerate pattern, the user could keep adding ever-more
>> degenerate cases. What if we want to represent graphical tiles outside the
>> playing area, now we have X, O, "no player," and "not on the board," with
>> the latter two not having proper names at all, but relying on the reader's
>> inference about what exact set the enumeration (or non-enumeration) is
>> supposed to cover.
>>
>
> Indeed. It is supposed to mimic optional<T> semantics, which has only one
> "degenerate" case.
>
I'm a bit skeptical about use of optional for persistent state
representation. It's a good placeholder for an object that might be
temporarily unavailable, but it's not a good idiom for a real state machine.
Your use case describes a state machine, which should have a coherent
representation, not patched together piecemeal. State machines invite
spaghetti code. Consistent use of degenerate will surely lead ultimately to
uncertain ownership of "outside" values, overloading them and producing
semantic collisions where different notions of "outside" have exactly the
same compile-time and runtime representation.
>
> Laurent
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2319_6567170.1378100564826
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, September 2, 2013 1:13:08 PM UTC+8, the=
..ultim...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
dir=3D"ltr">David,<br><br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>What value? <br></div></div></blockquote><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>Ohh -1. Of course. And I'm suppos=
ed to specify that it's -1. Wonderful.<br> <br></div></div></blockquot=
e><div><br>Of course I'm supposed to specify it. With current state of art,=
in C++, you can only encode values within sets whose cardinality is a powe=
r of 2. You can't specify a type like { REGULAR, DECAF, ESPRESSO } and stor=
e it to a 3-state location. The bare minimum is two bits, which can encode =
4 values.<br></div></div></blockquote><div><br>So it turns out that it's no=
t "not part of the encodable set" after all.<br> </div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>In my example, the enum=
class Player (let's assume I specified "char" storage) takes its values fr=
om a set whose cardinality is 256. I specified only two symbolic constants =
for values 0 and 1. (resp. CROSS and NOUGHT). Player(-1) is a perfectly val=
id Player value, just like Player(124). These do not get symbolic constant =
support in my program, that's it.<br></div></div></blockquote><div><br>Now =
you have to be concerned with encoding, both in selection of the underlying=
type and the extra state-value, which violates separation of concerns.<br>=
<br>Not only don't you have symbolic support for one value (or N values, ho=
wever many times this concept is applied), you don't have access to any int=
erface designed for the underlying enumeration, except by implicit conversi=
on.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><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"><div></div>I t=
hink that <span style=3D"font-family:courier new,monospace">degenerate</spa=
n> is nothing like the enumeration it is supposed to adapt. </div></blockqu=
ote><div> </div><div>So do I. optional<int> is nothing like int.=
It not supposed to "adapt" the enumeration. It is supposed to give optiona=
l semantics to my enum, for which I will not use all 256 values.<br></div><=
/div></blockquote><div><br>Adding a state machine construct to an int is di=
fferent from adding a state to a state machine.<br> </div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">It's a class type, for starters.<br></div><=
/blockquote><div><br>degenerate<T> is POD. "class" means "user-define=
d type"<br></div></div></blockquote><div><br>Enumerations are user-defined =
types which are not classes.<br> </div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>I think that enumerations should be able to in=
herit from other enumerations as an underlying type, such as to be able to =
represent supersets. This is an extremely common use case and isn't limited=
in general to just one extra "none" enumerator.<br></div></div></blockquot=
e><div><br>Indeed. MAX_VALUE, NB_FLAGS, etc. I too would wish for better co=
mpiler support for enums. I would wish to have some type traits that give m=
e the number of defined symbolic constants, what is the min, max constant, =
..<br></div></div></blockquote><div><br>Language support, not compiler suppo=
rt. You can do already plenty by defining traits on your own enumeration ty=
pes, and following conventions, but some conventions and traits would need =
formalization before the language can move forward.<br> </div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div>Following the <span style=3D"font-=
family:courier new,monospace">degenerate</span> pattern, the user could kee=
p adding ever-more degenerate cases. What if we want to represent graphical=
tiles outside the playing area, now we have X, O, "no player," and "not on=
the board," with the latter two not having proper names at all, but relyin=
g on the reader's inference about what exact set the enumeration (or non-en=
umeration) is supposed to cover.<br></div></div></blockquote><div><br>Indee=
d. It is supposed to mimic optional<T> semantics, which has only one =
"degenerate" case.<br></div></div></blockquote><div><br>I'm a bit skeptical=
about use of optional for persistent state representation. It's a good pla=
ceholder for an object that might be temporarily unavailable, but it's not =
a good idiom for a real state machine.<br><br>Your use case describes a sta=
te machine, which should have a coherent representation, not patched togeth=
er piecemeal. State machines invite spaghetti code. Consistent use of <span=
style=3D"font-family: courier new,monospace;">degenerate</span> will surel=
y lead ultimately to uncertain ownership of "outside" values, overloading t=
hem and producing semantic collisions where different notions of "outside" =
have exactly the same compile-time and runtime representation.<br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>Laurent=
<br></div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2319_6567170.1378100564826--
.
Author: the.ultimate.koala@gmail.com
Date: Mon, 2 Sep 2013 22:17:52 -0700 (PDT)
Raw View
------=_Part_3853_16465257.1378185472629
Content-Type: text/plain; charset=ISO-8859-1
David,
I think we may not understand each other. I did not talk about state
machine, and I did say that the value WAS part of the encodable set.
So that we can have a common ground of discussion, here is a complete
implementation of the template:
template<class T, T uninitialized_value>
class degenerate {
T value_;
constexpr bool initialized() const {
return value_ != uninitialized_value;
}
void clear() {
value_ = uninitialized_value;
}
void assert_initialized() {
_assert(initialized(), "Access to uninitialized degenerate.");
}
public:
typedef T value_type;
// 1 Constructors
constexpr degenerate(const T& v = uninitialized_value) noexcept
: value_(v) {}
constexpr degenerate(nullopt_t) noexcept
: degenerate() {}
constexpr degenerate(const degenerate& ) noexcept = default;
// 3 Assignment
degenerate& operator=(nullopt_t) noexcept
{
clear();
return *this;
}
degenerate& operator=(const degenerate&) noexcept = default;
// 4 Swap
void swap(degenerate& rhs) noexcept
{
using std::swap;
swap(value_, rhs.value_);
}
// 5 Observers
constexpr T const operator ->() const {
assert_initialized();
return value_;
}
T operator ->() {
assert_initialized();
return value_;
}
constexpr T const& operator *() const {
assert_initialized();
return value_;
}
T& operator *() {
assert_initialized();
return value_;
}
constexpr T const& value() const {
return initialized() ? value_ : (throw std::logic_error("bad optional
access"), value_);
}
T& value() {
return initialized() ? value : (throw std::logic_error("bad optional
access"), value);
}
constexpr explicit operator bool() const noexcept { return initialized();
}
};
Let me know if this was what you were thinking about.
Laurent
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3853_16465257.1378185472629
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">David,<br><br>I think we may not understand each other. I =
did not talk about state machine, and I did say that the value WAS part of =
the encodable set.<br><br>So that we can have a common ground of discussion=
, here is a complete implementation of the template:<br><br><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> T uninitialized_value</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> degenerate </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br> T value_</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">constexpr</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ini=
tialized</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> value_ </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">!=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> uninitialized_value</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> clear</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; value_ </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> uninitialized_value</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> asser=
t_initialized</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</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> _asse=
rt</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">initialized</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: #080;" class=3D"styled-by-prettify">"Access to uninitialized degener=
ate."</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">public</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"styled-by-prettify">typedef</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> T value_type</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// 1 Constructors</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">constexpr</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> degenerate</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> v </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
uninitialized_value</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
noexcept<br> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> value_</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">v</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #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"styled-by-prettify">constexpr</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> degenerate</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">nullopt_t</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> noexcept<br> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> degenerate</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">()</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-prettify=
"><br><br> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">constexpr</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> degenerate</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nst</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> degene=
rate</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: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> noexcept </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br> </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// 3 Assignment</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br> degenerate</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">operator</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">nullopt_t</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> noexcept<br> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br> clear</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">*</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">this</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: #660;" class=3D"styled-by-prettify">}</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br> <br> =
; degenerate</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">operator</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D(</span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> degenerate</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> noexcept </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">default</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br> <br> </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">// 4 Swap</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> swap</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">degenerate</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> rhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> noexcept=
<br> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
using</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">swap</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> swap</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"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">value_</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// 5 Observers</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> T </span><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nst</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=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">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> assert_initialized</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><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> value_</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br> <br> T </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">operator</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"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br> assert_initialized</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br> </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> value_</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br> </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br> <br> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> T </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">const</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</s=
pan><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=
: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> assert_initialized</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><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> value_</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br> <br> T</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">operator</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"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br> a=
ssert_initialized</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> value_</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> <br>&=
nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
texpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</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 sty=
le=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> initialized</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"> value_ </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">throw</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">logic_error</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">"bad optional access"</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> value_</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; <br> T</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
value</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> initialized</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 style=3D"color: #000;" =
class=3D"styled-by-prettify"> value </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
hrow</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">logic_error</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">"bad optional access"</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> value</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"col=
or: #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">constexpr</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">explicit</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">operator</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: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> noexcept </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> initialized</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></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></div></code></div><br>Let me know if this was what you w=
ere thinking about.<br><br>Laurent<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3853_16465257.1378185472629--
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 2 Sep 2013 23:40:16 -0700 (PDT)
Raw View
------=_Part_3230_31967805.1378190416573
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Tuesday, September 3, 2013 1:17:52 PM UTC+8, the.ultim...@gmail.com=20
wrote:
>
> David,
>
> I think we may not understand each other. I did not talk about state=20
> machine, and I did say that the value WAS part of the encodable set.
>
=20
Sorry, I initially misunderstood "set apart a value from the encodable set"=
=20
as something like "set a value apart from the encodable set."
Let me know if this was what you were thinking about.
>
There is no other misunderstanding here. The premise is that given a closed=
=20
set, you might want to add a member of the set to represent "other," thus=
=20
producing a new set. That's a poor programming paradigm because it excludes=
=20
conceptual precision and fails to anticipate that the same concept can=20
still apply to the new set. (That is the nature of set arithmetic.)=20
Enumerations are unfortunately not extensible, so it's best to define the=
=20
largest superset all at once. When that's impossible, ugly conversions are=
=20
necessary, but it's still important to use care in enumerating members of=
=20
supersets. Giving two completely separate software components an=20
opportunity to define the same value (of the same, somewhat verbose type)=
=20
to mean different things is the opposite of what we want.
What does all the above code actually *gain* over just casting to char and=
=20
assigning some crazy value through the cast? All the brackets and=20
conversions are just creating a false sense of legitimacy.
I can understand the value of an optimized optional. I've personally abused=
=20
floating-point infinity for such semantics (very carefully!). But that=20
should be approached as a question of how to let the user specify to=20
std::optional that the optimization should apply. Then there is no new=20
interface. (And, IMO, the optimization should apply to floating-point types=
=20
as well, whose values cannot be passed as template non-type parameters.)
Another approach could look like struct without_value< E, T =3D E::type > {=
=20
typedef T type; =85 }; where T is either a numeric type or has a member typ=
ewhich is numeric, and=20
E::value is the excluded value. (Such a definition would support a single=
=20
std::integral_constant argument.) This could assert to a container or=20
algorithm that the given value will not be used, and the given type should=
=20
be allocated. It would be a template flag rather than a proxy with tricky=
=20
conversion semantics =97 without_value would not be ODR-used, but ODR-use=
=20
would be the inevitable result of passing it somewhere it's not supported.=
=20
It would support floating-point types and NaN. And it would actually be a=
=20
numeric invariant; the concept could extend to other hints such as that an=
=20
argument must be in a numeric range. A generic way to pass numeric hints to=
=20
algorithms and containers is something currently lacking, but probably=20
helpful to scientific applications.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3230_31967805.1378190416573
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Tuesday, September 3, 2013 1:17:52 PM UTC+8, the.ul=
tim...@gmail.com wrote:<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">David,<br><br>I think we may not understand each other. I did not=
talk about state machine, and I did say that the value WAS part of the enc=
odable set.<br></div></blockquote><div> <br>Sorry, I initially misunde=
rstood "set apart a value from the encodable set" as something like "set a =
value apart from the encodable set."<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr">Let me know if this was what you were =
thinking about.<br></div></blockquote><div><br>There is no other misunderst=
anding here. The premise is that given a closed set, you might want to add =
a member of the set to represent "other," thus producing a new set. That's =
a poor programming paradigm because it excludes conceptual precision and fa=
ils to anticipate that the same concept can still apply to the new set. (Th=
at is the nature of set arithmetic.) Enumerations are unfortunately not ext=
ensible, so it's best to define the largest superset all at once. When that=
's impossible, ugly conversions are necessary, but it's still important to =
use care in enumerating members of supersets. Giving two completely separat=
e software components an opportunity to define the same value (of the same,=
somewhat verbose type) to mean different things is the opposite of what we=
want.<br><br>What does all the above code actually <i>gain</i> over just c=
asting to <span style=3D"font-family: courier new,monospace;">char</span> a=
nd assigning some crazy value through the cast? All the brackets and conver=
sions are just creating a false sense of legitimacy.<br><br>I can understan=
d the value of an optimized <span style=3D"font-family: courier new,monospa=
ce;">optional</span>. I've personally abused floating-point infinity for su=
ch semantics (very carefully!). But that should be approached as a question=
of how to let the user specify to <span style=3D"font-family: courier new,=
monospace;">std::optional</span> that the optimization should apply. Then t=
here is no new interface. (And, IMO, the optimization should apply to float=
ing-point types as well, whose values cannot be passed as template non-type=
parameters.)<br><br>Another approach could look like <span style=3D"font-f=
amily: courier new,monospace;">struct without_value< E, T =3D E::type &g=
t; { typedef T type; =85 };</span><font face=3D"arial,sans-serif"> where T =
is either </font>a numeric type or has a member <span style=3D"font-family:=
courier new,monospace;">type</span> which is numeric, and <span style=3D"f=
ont-family: courier new,monospace;">E::value</span> is the excluded value. =
(Such a definition would support a single <span style=3D"font-family: couri=
er new,monospace;">std::integral_constant</span> argument.) This could asse=
rt to a container or algorithm that the given value will not be used, and t=
he given type should be allocated. It would be a template flag rather than =
a proxy with tricky conversion semantics =97 <span style=3D"font-family: co=
urier new,monospace;">without_value</span> would not be ODR-used, but ODR-u=
se would be the inevitable result of passing it somewhere it's not supporte=
d. It would support floating-point types and <span style=3D"font-family: co=
urier new,monospace;">NaN</span>. And it would actually be a numeric invari=
ant; the concept could extend to other hints such as that an argument must =
be in a numeric range. A generic way to pass numeric hints to algorithms an=
d containers is something currently lacking, but probably helpful to scient=
ific applications.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3230_31967805.1378190416573--
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 2 Sep 2013 23:45:49 -0700 (PDT)
Raw View
------=_Part_278_19127362.1378190749852
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, September 3, 2013 2:40:16 PM UTC+8, David Krauss wrote:
>
> without_value would not be ODR-used, but ODR-use would be the inevitable
> result of passing it somewhere it's not supported.
>
ODR-use is not what I meant. Appearing in a nested-name-specifier is
ODR-use. It could not be constructed. The point is that if used
incorrectly, the user should get a static_assert or other diagnostic saying
that it's not applicable there.
I haven't contemplated correct usage, aside from std::optional.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_278_19127362.1378190749852
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, September 3, 2013 2:40:16 PM UTC+8, Da=
vid Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><span style=3D"font-family:courier new,monospace">without_value</span> =
would not be ODR-used, but ODR-use would be the inevitable result of passin=
g it somewhere it's not supported.<br></div></blockquote><div> <br>ODR=
-use is not what I meant. Appearing in a nested-name-specifier is ODR-use. =
It could not be constructed. The point is that if used incorrectly, the use=
r should get a static_assert or other diagnostic saying that it's not appli=
cable there.<br><br>I haven't contemplated correct usage, aside from <span =
style=3D"font-family: courier new,monospace;">std::optional</span>.<br></di=
v></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_278_19127362.1378190749852--
.
Author: the.ultimate.koala@gmail.com
Date: Tue, 3 Sep 2013 05:18:04 -0700 (PDT)
Raw View
------=_Part_951_29067391.1378210684416
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
> Enumerations are unfortunately not extensible
>
I think the problem is not in what you're saying here, but in the cause=20
thereof. A variable of a C++ enumeration can have any encodable value, not=
=20
just the ones you list in the enum [class] definition. Therefore, they=20
cannot be extensible. And the set of their values is already taking all the=
=20
space available in the storage type.
In C++, except bool, there is no built-in type whose set of values is=20
strictly smaller than its storage capacity, and enums make no exception.=20
The only current way to go is a class.
What does all the above code actually *gain* over just casting to char and=
=20
> assigning some crazy value through the cast? All the brackets and=20
> conversions are just creating a false sense of legitimacy.
>
>
Here are the actual gains :
1. There is a semantic gain to saying that "the board is a thing with 9=20
distinguishable squares that MAY bear a token, CROSS or NOUGHT".
enum class Token { CROSS, NOUGHT };
std::vector<std::optional<Token>> board(9);
Instead of:
enum class Token { NONE, CROSS, NOUGHT };
std::vector<Token> board(9);
=20
Too bad it takes so much memory.
2. Zero-initialisation : There is a difference between :
enum class Token { NONE, CROSS, NOUGHT };
std::vector<Token> board(9);
And
enum class Token { CROSS, NOUGHT, NONE };
std::vector<Token> board(9);
Only the first one does the right thing, and the following one also:
enum class Token { CROSS, NOUGHT };
std::vector<std::optional<Token>> board(9);
So does the following :
enum class Token { CROSS, NOUGHT };
std::vector<degenerate<Token, Token(-1)>> board(9);
3. You make it explicit in the type that you are abusing one of the values,=
=20
instead of littering your code with a symbolic constant.
I can understand the value of an optimized optional.
>
So do I, but only Vicente said that it was an optimized optional. I said=20
that it should be a "drop-in replacement" for it. degenerate<T,v> actually=
=20
implements an equivalent of std::optional<T - {v}>, in the case of when=20
you're not using all the values of a type.
=20
> But that should be approached as a question of how to let the user specif=
y=20
> to std::optional that the optimization should apply. Then there is no new=
=20
> interface. (And, IMO, the optimization should apply to floating-point typ=
es=20
> as well, whose values cannot be passed as template non-type parameters.)
>
It is impossible to steal a value from a type whose set of values take up=
=20
all the storage space allocated to the type, and still implement the right=
=20
semantics for optional<T>. Only bool is a "sparse" type, if I may say so.=
=20
Only std::optional<bool> may benefit from such an optimization.
=20
>
> Another approach could look like struct without_value< E, T =3D E::type >=
{=20
> typedef T type; =85 }; where T is either a numeric type or has a member t=
ypewhich is numeric, and=20
> E::value is the excluded value. (Such a definition would support a single=
=20
> std::integral_constant argument.) This could assert to a container or=20
> algorithm that the given value will not be used, and the given type shoul=
d=20
> be allocated. It would be a template flag rather than a proxy with tricky=
=20
> conversion semantics =97 without_value would not be ODR-used, but ODR-use=
=20
> would be the inevitable result of passing it somewhere it's not supported=
..=20
> It would support floating-point types and NaN. And it would actually be a=
=20
> numeric invariant; the concept could extend to other hints such as that a=
n=20
> argument must be in a numeric range. A generic way to pass numeric hints =
to=20
> algorithms and containers is something currently lacking, but probably=20
> helpful to scientific applications.
>
These are too few words for such a lot of thinking :) If I may summarize,=
=20
would you say that C++ lacks the ability to easily create "sparse" types.=
=20
(with the above ad hoc definition of "sparse") and as such cannot reason on=
=20
the "actually used set of values of types"?
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_951_29067391.1378210684416
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0pt=
0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1e=
x;"><div dir=3D"ltr"><div>Enumerations are unfortunately not extensible</di=
v></div></blockquote><div><br>I think the problem is not in what you're say=
ing here, but in the cause thereof. A variable of a C++ enumeration can hav=
e any encodable value, not just the ones you list in the enum [class] defin=
ition. Therefore, they cannot be extensible. And the set of their values is=
already taking all the space available in the storage type.<br><br>In C++,=
except <span style=3D"font-family: courier new,monospace;">bool</span>, th=
ere is no built-in type whose set of values is strictly smaller than its st=
orage capacity, and enums make no exception. The only current way to go is =
a class.<br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padd=
ing-left: 1ex;"><div dir=3D"ltr"><div>What does all the above code actually=
<i>gain</i> over just casting to <span style=3D"font-family:courier new,mo=
nospace">char</span> and assigning some crazy value through the cast? All t=
he brackets and conversions are just creating a false sense of legitimacy.<=
br><br></div></div></blockquote><div><br>Here are the actual gains :<br><br=
>1. There is a semantic gain to saying that "the board is a thing with 9 di=
stinguishable squares that MAY bear a token, CROSS or NOUGHT".<div class=3D=
"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: =
rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: brea=
k-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">enum</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: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Token</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> C=
ROSS</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> NOUGHT </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br>std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">vector</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">optional</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Token</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">>></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> board</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">9</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></d=
iv><p></p>Instead of:<br><br><div class=3D"prettyprint" style=3D"background=
-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style:=
solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">enum</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: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Token</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> NONE</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> CROSS</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> NOUGHT </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br>std</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ve=
ctor</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Token</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> board</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">9</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div>
<br>Too bad it takes so much memory.<br><br>2. Zero-initialisation : There =
is a difference between :<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">enum</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Token</s=
pan><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"> NONE</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> CROSS</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> NOUGHT </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br>std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
vector</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Token</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> board</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">9</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div>
<br>And<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">enum</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: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Token</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;" cla=
ss=3D"styled-by-prettify"> CROSS</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> NOUGHT</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> NONE </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Token</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> board</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">9</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span></div></code></div>
<br>Only the first one does the right thing, and the following one also:<br=
><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">enum</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Token</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"styl=
ed-by-prettify"> CROSS</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> NOUGHT </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br=
>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span s=
tyle=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">optional</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><</span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Token</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">>></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> board</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by=
-prettify">9</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span></div></code></div>
<br>So does the following :<br><br><div class=3D"prettyprint" style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">enum</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Token=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> CROSS</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> NOUGHT </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">vector</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">degenerate</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify"><</span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Token</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #606;" class=3D"styled-by-prettify">Token</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(-</span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)>></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> board</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">9</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span></div></code></div>
<br>3. You make it explicit in the type that you are abusing one of the val=
ues, instead of littering your code with a symbolic constant.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; borde=
r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=3D"ltr">=
<div>I can understand the value of an optimized <span style=3D"font-family:=
courier new,monospace">optional</span>.<br></div></div></blockquote><div><b=
r>So do I, but only Vicente said that it was an optimized optional. I said =
that it should be a "drop-in replacement" for it. <span style=3D"font-famil=
y: courier new,monospace;">degenerate<T,v></span> actually implements=
an equivalent of <span style=3D"font-family: courier new,monospace;">std::=
optional<T - {v}></span>, in the case of when you're not using all th=
e values of a type.<br> </div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); p=
adding-left: 1ex;"><div dir=3D"ltr"><div>But that should be approached as a=
question of how to let the user specify to <span style=3D"font-family:cour=
ier new,monospace">std::optional</span> that the optimization should apply.=
Then there is no new interface. (And, IMO, the optimization should apply t=
o floating-point types as well, whose values cannot be passed as template n=
on-type parameters.)<br></div></div></blockquote><div><br>It is impossible =
to steal a value from a type whose set of values take up all the storage sp=
ace allocated to the type, and still implement the right semantics for opti=
onal<T>. Only bool is a "sparse" type, if I may say so. Only std::opt=
ional<bool> may benefit from such an optimization.<br></div><div>&nbs=
p;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt =
0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div =
dir=3D"ltr"><div><br>Another approach could look like <span style=3D"font-f=
amily:courier new,monospace">struct without_value< E, T =3D E::type >=
{ typedef T type; =85 };</span><font face=3D"arial,sans-serif"> where T is=
either </font>a numeric type or has a member <span style=3D"font-family:co=
urier new,monospace">type</span> which is numeric, and <span style=3D"font-=
family:courier new,monospace">E::value</span> is the excluded value. (Such =
a definition would support a single <span style=3D"font-family:courier new,=
monospace">std::integral_constant</span> argument.) This could assert to a =
container or algorithm that the given value will not be used, and the given=
type should be allocated. It would be a template flag rather than a proxy =
with tricky conversion semantics =97 <span style=3D"font-family:courier new=
,monospace">without_value</span> would not be ODR-used, but ODR-use would b=
e the inevitable result of passing it somewhere it's not supported. It woul=
d support floating-point types and <span style=3D"font-family:courier new,m=
onospace">NaN</span>. And it would actually be a numeric invariant; the con=
cept could extend to other hints such as that an argument must be in a nume=
ric range. A generic way to pass numeric hints to algorithms and containers=
is something currently lacking, but probably helpful to scientific applica=
tions.<br></div></div></blockquote><div><br>These are too few words for suc=
h a lot of thinking :) If I may summarize, would you say that C++ lacks the=
ability to easily create "sparse" types. (with the above ad hoc definition=
of "sparse") and as such cannot reason on the "actually used set of values=
of types"?<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_951_29067391.1378210684416--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Sep 2013 05:47:43 -0700 (PDT)
Raw View
------=_Part_560_29383259.1378212463436
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
On Tuesday, September 3, 2013 5:18:04 AM UTC-7, the.ultim...@gmail.com=20
wrote:
>
>
> Enumerations are unfortunately not extensible
>>
>
> I think the problem is not in what you're saying here, but in the cause=
=20
> thereof. A variable of a C++ enumeration can have any encodable value, no=
t=20
> just the ones you list in the enum [class] definition. Therefore, they=20
> cannot be extensible.
>
I fail to see how those last two sentences have anything to do with one=20
another.
Are you legally allowed to cast an integer to a value of enum type? Yes,=20
assuming it fits into the underlying type. The set of integers that could=
=20
be stored in an enumeration have nothing to do with what the enumerator=20
values are.
So why does the fact that an enum type could take on values outside of the=
=20
enumerators have anything to do with whether or not the list of enumerators=
=20
for an enum type could partially come from another enum type?
3. You make it explicit in the type that you are abusing one of the values,=
=20
> instead of littering your code with a symbolic constant.
>
If that symbolic constant were actually *part* of the enumeration, it=20
wouldn't be "abusing" anything. You're only abusing it because you have no=
=20
other way to achieve what you want.
=20
> I can understand the value of an optimized optional.
>>
>
> So do I, but only Vicente said that it was an optimized optional.
>
Whether you want to admit it or not, it serves the same functional purpose=
=20
as optional. It creates a type which may or may not be considered to have a=
=20
valid value of some specific type. It has a value which is considered to be=
=20
"not a real value". It has value semantics. And so forth.
Indeed, I would go so far as to say that the (unnecessary) differences in=
=20
interface between your class and `optional` are *detriments* of your class,=
=20
not strengths. It's a half-finished optional that lacks many of the traits=
=20
of the real class.
I said that it should be a "drop-in replacement" for it. degenerate<T,v>act=
ually implements an equivalent of std::optional<T=20
> - {v}>, in the case of when you're not using all the values of a type.
> =20
>
>> But that should be approached as a question of how to let the user=20
>> specify to std::optional that the optimization should apply. Then there=
=20
>> is no new interface. (And, IMO, the optimization should apply to=20
>> floating-point types as well, whose values cannot be passed as template=
=20
>> non-type parameters.)
>>
>
> It is impossible to steal a value from a type whose set of values take up=
=20
> all the storage space allocated to the type, and still implement the righ=
t=20
> semantics for optional<T>.
>
How do you figure that?
If you're making a space-optimized `optional` variation, then by definition=
=20
it would *not* be the same type as `optional<T>`. It could use the same=20
name: `optional<T, ...>`, where ... is whatever you do to denote the value=
=20
that represents "not a value". It could be some kind of functor, a type=20
that provides constexpr functions, or whatever.
The point is that `optional<T>` would have no more relation to `optional<T,=
=20
....>` than it would to `optional<U>`. So there would be no problem with=20
stealing a value for `optional<T>` because that's not how an `optional<T>`=
=20
would ever work. Only the optimized form would "steal a value".
Another approach could look like struct without_value< E, T =3D E::type > {=
=20
>> typedef T type; =85 }; where T is either a numeric type or has a member=
=20
>> type which is numeric, and E::value is the excluded value. (Such a=20
>> definition would support a single std::integral_constant argument.) This=
=20
>> could assert to a container or algorithm that the given value will not b=
e=20
>> used, and the given type should be allocated. It would be a template fla=
g=20
>> rather than a proxy with tricky conversion semantics =97 without_valuewo=
uld not be ODR-used, but ODR-use would be the inevitable result of=20
>> passing it somewhere it's not supported. It would support floating-point=
=20
>> types and NaN. And it would actually be a numeric invariant; the concept=
=20
>> could extend to other hints such as that an argument must be in a numeri=
c=20
>> range. A generic way to pass numeric hints to algorithms and containers =
is=20
>> something currently lacking, but probably helpful to scientific=20
>> applications.
>>
>
> These are too few words for such a lot of thinking :) If I may summarize,=
=20
> would you say that C++ lacks the ability to easily create "sparse" types.=
=20
> (with the above ad hoc definition of "sparse") and as such cannot reason =
on=20
> the "actually used set of values of types"?
>
I see no reason why one should lead to the other. A type is whatever you=20
want it to be. If you want to create a type that behaves like an `int`, but=
=20
considers the number -1 to be "not a real value", you can. And you can=20
"reason" about such types just fine.
--=20
---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_560_29383259.1378212463436
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, September 3, 2013 5:18:04 AM UTC-7, th=
e.ultim...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt=
0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div di=
r=3D"ltr"><div>Enumerations are unfortunately not extensible</div></div></b=
lockquote><div><br>I think the problem is not in what you're saying here, b=
ut in the cause thereof. A variable of a C++ enumeration can have any encod=
able value, not just the ones you list in the enum [class] definition. Ther=
efore, they cannot be extensible.</div></div></blockquote><div><br>I fail t=
o see how those last two sentences have anything to do with one another.<br=
><br>Are
you legally allowed to cast an integer to a value of enum type? Yes,=20
assuming it fits into the underlying type. The set of integers that=20
could be stored in an enumeration have nothing to do with what the=20
enumerator values are.<br><br>So why does the fact that=20
an enum type could take on values outside of the enumerators have=20
anything to do with whether or not the list of enumerators for an enum=20
type could partially come from another enum type?<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>3. You ma=
ke it explicit in the type that you are abusing one of the values, instead =
of littering your code with a symbolic constant.<br></div></div></blockquot=
e><div><br>If that symbolic constant were actually <i>part</i> of the enume=
ration, it wouldn't be "abusing" anything. You're only abusing it because y=
ou have no other way to achieve what you want.<br> </div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>I can understand t=
he value of an optimized <span style=3D"font-family:courier new,monospace">=
optional</span>.<br></div></div></blockquote><div><br>So do I, but only Vic=
ente said that it was an optimized optional.</div></div></blockquote><div><=
br>Whether you want to admit it or not, it serves the same functional purpo=
se as optional. It creates a type which may or may not be considered to hav=
e a valid value of some specific type. It has a value which is considered t=
o be "not a real value". It has value semantics. And so forth.<br><br>Indee=
d, I would go so far as to say that the (unnecessary) differences in interf=
ace between your class and `optional` are <i>detriments</i> of your class, =
not strengths. It's a half-finished optional that lacks many of the traits =
of the real class.<br><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
"><div dir=3D"ltr"><div>I said that it should be a "drop-in replacement" fo=
r it. <span style=3D"font-family:courier new,monospace">degenerate<T,v&g=
t;</span> actually implements an equivalent of <span style=3D"font-family:c=
ourier new,monospace">std::optional<T - {v}></span>, in the case of w=
hen you're not using all the values of a type.<br> </div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>But that should =
be approached as a question of how to let the user specify to <span style=
=3D"font-family:courier new,monospace">std::optional</span> that the optimi=
zation should apply. Then there is no new interface. (And, IMO, the optimiz=
ation should apply to floating-point types as well, whose values cannot be =
passed as template non-type parameters.)<br></div></div></blockquote><div><=
br>It is impossible to steal a value from a type whose set of values take u=
p all the storage space allocated to the type, and still implement the righ=
t semantics for optional<T>.</div></div></blockquote><div><br>How do =
you figure that?<br><br>If you're making a space-optimized `optional` varia=
tion, then by definition it would <i>not</i> be the same type as `optional&=
lt;T>`. It could use the same name: `optional<T, ...>`, where ... =
is whatever you do to denote the value that represents "not a value". It co=
uld be some kind of functor, a type that provides constexpr functions, or w=
hatever.<br><br>The point is that `optional<T>` would have no more re=
lation to `optional<T, ...>` than it would to `optional<U>`. So=
there would be no problem with stealing a value for `optional<T>` be=
cause that's not how an `optional<T>` would ever work. Only the optim=
ized form would "steal a value".<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div>Another approach could look like <=
span style=3D"font-family:courier new,monospace">struct without_value< E=
, T =3D E::type > { typedef T type; =85 };</span><font face=3D"arial,san=
s-serif"> where T is either </font>a numeric type or has a member <span sty=
le=3D"font-family:courier new,monospace">type</span> which is numeric, and =
<span style=3D"font-family:courier new,monospace">E::value</span> is the ex=
cluded value. (Such a definition would support a single <span style=3D"font=
-family:courier new,monospace">std::integral_constant</span> argument.) Thi=
s could assert to a container or algorithm that the given value will not be=
used, and the given type should be allocated. It would be a template flag =
rather than a proxy with tricky conversion semantics =97 <span style=3D"fon=
t-family:courier new,monospace">without_value</span> would not be ODR-used,=
but ODR-use would be the inevitable result of passing it somewhere it's no=
t supported. It would support floating-point types and <span style=3D"font-=
family:courier new,monospace">NaN</span>. And it would actually be a numeri=
c invariant; the concept could extend to other hints such as that an argume=
nt must be in a numeric range. A generic way to pass numeric hints to algor=
ithms and containers is something currently lacking, but probably helpful t=
o scientific applications.<br></div></div></blockquote><div><br>These are t=
oo few words for such a lot of thinking :) If I may summarize, would you sa=
y that C++ lacks the ability to easily create "sparse" types. (with the abo=
ve ad hoc definition of "sparse") and as such cannot reason on the "actuall=
y used set of values of types"?<br></div></div></blockquote><div><br>I see =
no reason why one should lead to the other. A type is whatever you want it =
to be. If you want to create a type that behaves like an `int`, but conside=
rs the number -1 to be "not a real value", you can. And you can "reason" ab=
out such types just fine.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_560_29383259.1378212463436--
.
Author: the.ultimate.koala@gmail.com
Date: Tue, 3 Sep 2013 07:02:48 -0700 (PDT)
Raw View
------=_Part_37_22048313.1378216968907
Content-Type: text/plain; charset=ISO-8859-1
Nicol Bolas,
Pleased to meet you.
> I think the problem is not in what you're saying here, but in the cause
>> thereof. A variable of a C++ enumeration can have any encodable value, not
>> just the ones you list in the enum [class] definition. Therefore, they
>> cannot be extensible.
>>
>
> I fail to see how those last two sentences have anything to do with one
> another.
>
> Are you legally allowed to cast an integer to a value of enum type? Yes,
> assuming it fits into the underlying type. The set of integers that could
> be stored in an enumeration have nothing to do with what the enumerator
> values are.
>
Exactly. They are not related at all, that's why I'm saying that the set of
values of an enumerated type has the same cardinality as the set of values
of its underlying type. If it's obvious, sorry for stating it.
> So why does the fact that an enum type could take on values outside of the
> enumerators have anything to do with whether or not the list of enumerators
> for an enum type could partially come from another enum type?
>
>
It depends if "extensible" means "the set of values can be extended" or
"the set of enumerators can be extended". In the context of the discussion
about degenerate<>, I am understanding the former. I agree with you that
assuming the latter definition of "extensible", the enums could be
"extensible" .
3. You make it explicit in the type that you are abusing one of the values,
>> instead of littering your code with a symbolic constant.
>>
>
> If that symbolic constant were actually *part* of the enumeration, it
> wouldn't be "abusing" anything. You're only abusing it because you have no
> other way to achieve what you want.
>
>
No. If the symbolic constant were actually one of the enumerators, the only
thing it would mean is that I would not have to cast from an int. To be
precise, in any case the value denoted by the symbolic constant HAS to be
part of the set of values of the enumeration.
I can write
enum class Token { CROSS, NOUGHT, NONE };
std::vector<std::degenerate<Token, Token::NONE>> board(9);
And it will have the right behaviour.
What bugs me is that NONE is not a token. It's like this old joke about
finding the "Any" key.
>> Indeed, I would go so far as to say that the (unnecessary) differences in
>> interface between your class and `optional` are *detriments* of your
>> class, not strengths. It's a half-finished optional that lacks many of the
>> traits of the real class.
>>
>>
Yes. Were it finished, there would be a proposal, not a discussion. What
traits does it lack exactly? What differences in interface do you detect
and how are they detriments?
I said that it should be a "drop-in replacement" for it. degenerate<T,v>actually implements an equivalent of std::optional<T
>> - {v}>, in the case of when you're not using all the values of a type.
>>
>>
>>> But that should be approached as a question of how to let the user
>>> specify to std::optional that the optimization should apply. Then there
>>> is no new interface. (And, IMO, the optimization should apply to
>>> floating-point types as well, whose values cannot be passed as template
>>> non-type parameters.)
>>>
>>
>> It is impossible to steal a value from a type whose set of values take up
>> all the storage space allocated to the type, and still implement the right
>> semantics for optional<T>.
>>
>
> How do you figure that?
>
Because it would not implement the semantics of optional<T>, but that of optional<T
- {n}>.
>
> If you're making a space-optimized `optional` variation, then by
> definition it would *not* be the same type as `optional<T>`. It could use
> the same name: `optional<T, ...>`, where ... is whatever you do to denote
> the value that represents "not a value". It could be some kind of functor,
> a type that provides constexpr functions, or whatever.
>
>
I thought about functors to accomodate floating-point and class types,
indeed.
>
> Whether you want to admit it or not, it serves the same functional purpose
> as optional. It creates a type which may or may not be considered to have a
> valid value of some specific type. It has a value which is considered to be
> "not a real value". It has value semantics. And so forth.
>
<snip/>
>
The point is that `optional<T>` would have no more relation to `optional<T,
> ...>` than it would to `optional<U>`. So there would be no problem with
> stealing a value for `optional<T>` because that's not how an `optional<T>`
> would ever work. Only the optimized form would "steal a value".
>
>
Nonetheless, this would not be equivalent to an optimized optional<T>, but
to an optimized optional<T - { n }>. They would not be the same type, but
would not even implement the same concept.
> I see no reason why one should lead to the other. A type is whatever you
> want it to be. If you want to create a type that behaves like an `int`, but
> considers the number -1 to be "not a real value", you can. And you can
> "reason" about such types just fine.
>
I can reason about it extremely fine. The compiler can't, and can't decide
on its own to steal a value of any built-in type, enumeration, or class
except bool. (I mean that you won't be able to write a template performing
this)
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_37_22048313.1378216968907
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Nicol Bolas,<br><br>Pleased to meet you.<br><div> </d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; bo=
rder-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=3D"lt=
r"><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; bo=
rder-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=3D"lt=
r"><div>I think the problem is not in what you're saying here, but in the c=
ause thereof. A variable of a C++ enumeration can have any encodable value,=
not just the ones you list in the enum [class] definition. Therefore, they=
cannot be extensible.</div></div></blockquote><div><br>I fail to see how t=
hose last two sentences have anything to do with one another.<br><br>Are
you legally allowed to cast an integer to a value of enum type? Yes,=20
assuming it fits into the underlying type. The set of integers that=20
could be stored in an enumeration have nothing to do with what the=20
enumerator values are.<br></div></div></blockquote><div><br>Exactly. They a=
re not related at all, that's why I'm saying that the set of values of an e=
numerated type has the same cardinality as the set of values of its underly=
ing type. If it's obvious, sorry for stating it.<br> <br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left:=
1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=3D"ltr"><div>So=
why does the fact that=20
an enum type could take on values outside of the enumerators have=20
anything to do with whether or not the list of enumerators for an enum=20
type could partially come from another enum type?<br><br></div></div></bloc=
kquote><div><br>It depends if "extensible" means "the set of values can be =
extended" or "the set of enumerators can be extended". In the context of th=
e discussion about degenerate<>, I am understanding the former. I agr=
ee with you that assuming the latter definition of "extensible", the enums =
could be "extensible" .<br><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); =
padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div></div><div>3. You make it explicit in th=
e type that you are abusing one of the values, instead of littering your co=
de with a symbolic constant.<br></div></div></blockquote><div><br>If that s=
ymbolic constant were actually <i>part</i> of the enumeration, it wouldn't =
be "abusing" anything. You're only abusing it because you have no other way=
to achieve what you want.<br> </div></div></blockquote><div><br>No. I=
f the symbolic constant were actually one of the enumerators, the only thin=
g it would mean is that I would not have to cast from an int. To be precise=
, in any case the value denoted by the symbolic constant HAS to be part of =
the set of values of the enumeration.<br><br>I can write<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">enum</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: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Token</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-prettify"=
> CROSS</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> NOUGHT</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> NONE </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">vector</span><span style=3D"color: #660;" class=
=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-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">degenerate</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"><</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Tok=
en</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Token</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">NONE</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">>></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> board</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">9</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><br></span></div></code></div><br>And it will have the right behaviour.<b=
r>What bugs me is that NONE is not a token. It's like this old joke about f=
inding the "Any" key.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); p=
adding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div><br>Indeed, I would go so far as to say that the (unnecessary) differ=
ences in interface between your class and `optional` are <i>detriments</i> =
of your class, not strengths. It's a half-finished optional that lacks many=
of the traits of the real class.<br><br></div></blockquote></div></blockqu=
ote><div><br>Yes. Were it finished, there would be a proposal, not a discus=
sion. What traits does it lack exactly? What differences in interface do yo=
u detect and how are they detriments?<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(20=
4, 204, 204); padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>I said that it should be a=
"drop-in replacement" for it. <span style=3D"font-family:courier new,monos=
pace">degenerate<T,v></span> actually implements an equivalent of <sp=
an style=3D"font-family:courier new,monospace">std::optional<T - {v}>=
</span>, in the case of when you're not using all the values of a type.<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"l=
tr"><div>But that should be approached as a question of how to let the user=
specify to <span style=3D"font-family:courier new,monospace">std::optional=
</span> that the optimization should apply. Then there is no new interface.=
(And, IMO, the optimization should apply to floating-point types as well, =
whose values cannot be passed as template non-type parameters.)<br></div></=
div></blockquote><div><br>It is impossible to steal a value from a type who=
se set of values take up all the storage space allocated to the type, and s=
till implement the right semantics for optional<T>.</div></div></bloc=
kquote><div><br>How do you figure that?<br></div></div></blockquote><div><b=
r>Because it would not implement the semantics of <span style=3D"font-famil=
y: courier new,monospace;">optional<T></span>, but that of <span styl=
e=3D"font-family: courier new,monospace;">optional<T - {n}></span>.<b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8e=
x; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=
=3D"ltr"><div><br>If you're making a space-optimized `optional` variation, =
then by definition it would <i>not</i> be the same type as `optional<T&g=
t;`. It could use the same name: `optional<T, ...>`, where ... is wha=
tever you do to denote the value that represents "not a value". It could be=
some kind of functor, a type that provides constexpr functions, or whateve=
r.<br><br></div></div></blockquote><div><br>I thought about functors to acc=
omodate floating-point and class types, indeed.<br> <br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: =
1px solid rgb(204, 204, 204); padding-left: 1ex;"><div dir=3D"ltr"><div><br=
>Whether you want to admit it or not, it serves the same functional=20
purpose as optional. It creates a type which may or may not be=20
considered to have a valid value of some specific type. It has a value=20
which is considered to be "not a real value". It has value semantics.=20
And so forth. <br></div></div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, =
204); padding-left: 1ex;"><div dir=3D"ltr"><div><snip/> <br></div></d=
iv></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt =
0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><=
div dir=3D"ltr"><div>The point is that `optional<T>` would have no mo=
re relation to `optional<T, ...>` than it would to `optional<U>=
`. So there would be no problem with stealing a value for `optional<T>=
;` because that's not how an `optional<T>` would ever work. Only the =
optimized form would "steal a value".<br><br></div></div></blockquote><div>=
<br>Nonetheless, this would not be equivalent to an optimized <span style=
=3D"font-family: courier new,monospace;">optional<T></span>, but to a=
n optimized <span style=3D"font-family: courier new,monospace;">optional<=
;T - { n }></span>. They would not be the same type, but would not even =
implement the same concept.<br></div><div> </div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb=
(204, 204, 204); padding-left: 1ex;"><div dir=3D"ltr"><div>I see no reason =
why one should lead to the other. A type is whatever you want it to be. If =
you want to create a type that behaves like an `int`, but considers the num=
ber -1 to be "not a real value", you can. And you can "reason" about such t=
ypes just fine.<br></div></div></blockquote><div><br>I can reason about it =
extremely fine. The compiler can't, and can't decide on its own to steal a =
value of any built-in type, enumeration, or class except bool. (I mean that=
you won't be able to write a template performing this)<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_37_22048313.1378216968907--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Sep 2013 15:49:56 -0700 (PDT)
Raw View
------=_Part_944_11261450.1378248596476
Content-Type: text/plain; charset=ISO-8859-1
On Tuesday, September 3, 2013 7:02:48 AM UTC-7, the.ultim...@gmail.com
wrote:
>
>>> Indeed, I would go so far as to say that the (unnecessary) differences
>>> in interface between your class and `optional` are *detriments* of your
>>> class, not strengths. It's a half-finished optional that lacks many of the
>>> traits of the real class.
>>>
>>>
> Yes. Were it finished, there would be a proposal, not a discussion. What
> traits does it lack exactly? What differences in interface do you detect
> and how are they detriments?
>
Just look at `optional`. All of that.
I said that it should be a "drop-in replacement" for it. degenerate<T,v>actually implements an equivalent of std::optional<T
>>> - {v}>, in the case of when you're not using all the values of a type.
>>>
>>>
>>>> But that should be approached as a question of how to let the user
>>>> specify to std::optional that the optimization should apply. Then
>>>> there is no new interface. (And, IMO, the optimization should apply to
>>>> floating-point types as well, whose values cannot be passed as template
>>>> non-type parameters.)
>>>>
>>>
>>> It is impossible to steal a value from a type whose set of values take
>>> up all the storage space allocated to the type, and still implement the
>>> right semantics for optional<T>.
>>>
>>
>> How do you figure that?
>>
>
> Because it would not implement the semantics of optional<T>, but that of optional<T
> - {n}>.
>
.... yes. That's the point of the space optimized optional type. It's
exactly like `optional<T>`, only certain values are considered "not a real
value".
I see no reason to give it a special name just because of that *minor*difference between them.
> If you're making a space-optimized `optional` variation, then by
>> definition it would *not* be the same type as `optional<T>`. It could
>> use the same name: `optional<T, ...>`, where ... is whatever you do to
>> denote the value that represents "not a value". It could be some kind of
>> functor, a type that provides constexpr functions, or whatever.
>>
>
> I thought about functors to accomodate floating-point and class types,
> indeed.
>
>
>>
>> Whether you want to admit it or not, it serves the same functional
>> purpose as optional. It creates a type which may or may not be considered
>> to have a valid value of some specific type. It has a value which is
>> considered to be "not a real value". It has value semantics. And so forth.
>>
> <snip/>
>>
> The point is that `optional<T>` would have no more relation to
>> `optional<T, ...>` than it would to `optional<U>`. So there would be no
>> problem with stealing a value for `optional<T>` because that's not how an
>> `optional<T>` would ever work. Only the optimized form would "steal a
>> value".
>>
>>
> Nonetheless, this would not be equivalent to an optimized optional<T>,
> but to an optimized optional<T - { n }>.
>
I fail to see the difference. By definition, an "optimized optional<T>" is
stealing a potential value from `T` and calling it "unengaged". That's what
the class means.
> They would not be the same type, but would not even implement the same
> concept.
>
How is it not? As previously stated, it is still conceptually *optional*.
You have a type that may or may not contain a real value. The only
difference is how you determine what is and is not a "real value".
I see no reason why one should lead to the other. A type is whatever you
>> want it to be. If you want to create a type that behaves like an `int`, but
>> considers the number -1 to be "not a real value", you can. And you can
>> "reason" about such types just fine.
>>
>
> I can reason about it extremely fine. The compiler can't, and can't decide
> on its own to steal a value of any built-in type, enumeration, or class
> except bool. (I mean that you won't be able to write a template performing
> this)
>
Sure you can. It's quite simple:
template<typename T, typename NullValueProvider>
class optional
{
public:
constexpr optional() : t(NullValueProvider::getNullValue()) {}
constexpr optional(const T &_t) : t(_t) {}
constexpr optional(const nullopt_T &) :
t(NullValueProvider::getNullValue()) {}
explicit operator bool() {return NullValueProvider::isNullValue(t);}
constexpr T const* operator->() const
{
return &t; //As with the regular optional version, the return value is
undefined if not engaged.
}
constexpr const T &value() const
{
if(*this) return t;
throw bad_optional_access; //Throws when not engaged.
}
private:
T t;
};
You can fill in the rest of the methods similarly.
`NullValueProvider::getNullValue` and `NullValueProvider::isNullValue`
would have to be `constexpr` if T is a literal type. There will have to be
some kind of type determination based on whether T is literal to use
`constexpr` conditionally.
I guess you're going to ask what happens if you construct one with the
"null" value. Well, what happens is exactly what you *expect* to happen:
the optional is not engaged. That is what you wanted; that's half the point
of explicitly specifying one or more values to be not "real" values.
You can also have appropriate copy/move constructors to and from different
"null" values, which will behave reasonably. By "reasonably", I mean if the
optional is considered disengaged before the copy, then no matter *where*it is copied, it will still be disengaged. Copying an engaged optional to a
space-optimized optional of a different type *may* cause the optional to be
disengaged (just like setting a value may disengage it).
The compiler isn't deciding to "steal" any values; the *user* is.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_944_11261450.1378248596476
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, September 3, 2013 7:02:48 AM UTC-7, the.ultim.=
...@gmail.com wrote:<br><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"><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div><br>Indeed, I would go so fa=
r as to say that the (unnecessary) differences in interface between your cl=
ass and `optional` are <i>detriments</i> of your class, not strengths. It's=
a half-finished optional that lacks many of the traits of the real class.<=
br><br></div></blockquote></div></blockquote><div><br>Yes. Were it finished=
, there would be a proposal, not a discussion. What traits does it lack exa=
ctly? What differences in interface do you detect and how are they detrimen=
ts?<br></div></div></blockquote><div><br>Just look at `optional`. All of th=
at.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;bor=
der-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I said=
that it should be a "drop-in replacement" for it. <span style=3D"font-fami=
ly:courier new,monospace">degenerate<T,v></span> actually implements =
an equivalent of <span style=3D"font-family:courier new,monospace">std::opt=
ional<T - {v}></span>, in the case of when you're not using all the v=
alues of a type.<br> </div><blockquote class=3D"gmail_quote" style=3D"=
margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-lef=
t:1ex"><div dir=3D"ltr"><div>But that should be approached as a question of=
how to let the user specify to <span style=3D"font-family:courier new,mono=
space">std::optional</span> that the optimization should apply. Then there =
is no new interface. (And, IMO, the optimization should apply to floating-p=
oint types as well, whose values cannot be passed as template non-type para=
meters.)<br></div></div></blockquote><div><br>It is impossible to steal a v=
alue from a type whose set of values take up all the storage space allocate=
d to the type, and still implement the right semantics for optional<T>=
;.</div></div></blockquote><div><br>How do you figure that?<br></div></div>=
</blockquote><div><br>Because it would not implement the semantics of <span=
style=3D"font-family:courier new,monospace">optional<T></span>, but =
that of <span style=3D"font-family:courier new,monospace">optional<T - {=
n}></span>.<br></div></div></blockquote><div><br>... yes. That's the poi=
nt of the space optimized optional type. It's exactly like `optional<T&g=
t;`, only certain values are considered "not a real value".<br><br>I see no=
reason to give it a special name just because of that <i>minor</i> differe=
nce between them.<br> </div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr"><div>If you're making a space-optimized `optional` v=
ariation, then by definition it would <i>not</i> be the same type as `optio=
nal<T>`. It could use the same name: `optional<T, ...>`, where =
.... is whatever you do to denote the value that represents "not a value". I=
t could be some kind of functor, a type that provides constexpr functions, =
or whatever.<br></div></div></blockquote><div><br>I thought about functors =
to accomodate floating-point and class types, indeed.<br> <br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><br>W=
hether you want to admit it or not, it serves the same functional=20
purpose as optional. It creates a type which may or may not be=20
considered to have a valid value of some specific type. It has a value=20
which is considered to be "not a real value". It has value semantics.=20
And so forth. <br></div></div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);=
padding-left:1ex"><div dir=3D"ltr"><div><snip/> <br></div></div></blo=
ckquote><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">=
<div>The point is that `optional<T>` would have no more relation to `=
optional<T, ...>` than it would to `optional<U>`. So there woul=
d be no problem with stealing a value for `optional<T>` because that'=
s not how an `optional<T>` would ever work. Only the optimized form w=
ould "steal a value".<br><br></div></div></blockquote><div><br>Nonetheless,=
this would not be equivalent to an optimized <span style=3D"font-family:co=
urier new,monospace">optional<T></span>, but to an optimized <span st=
yle=3D"font-family:courier new,monospace">optional<T - { n }></span>.=
</div></div></blockquote><div><br>I fail to see the difference. By definiti=
on, an "optimized optional<T>" is stealing a potential value from `T`=
and calling it "unengaged". That's what the class means.<br> </div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> They woul=
d not be the same type, but would not even implement the same concept.<br><=
/div></div></blockquote><div><br>How is it not? As previously stated, it is=
still conceptually <i>optional</i>. You have a type that may or may not co=
ntain a real value. The only difference is how you determine what is and is=
not a "real value".<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div></div><div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><div>I see no reason why one should le=
ad to the other. A type is whatever you want it to be. If you want to creat=
e a type that behaves like an `int`, but considers the number -1 to be "not=
a real value", you can. And you can "reason" about such types just fine.<b=
r></div></div></blockquote><div><br>I can reason about it extremely fine. T=
he compiler can't, and can't decide on its own to steal a value of any buil=
t-in type, enumeration, or class except bool. (I mean that you won't be abl=
e to write a template performing this)<br></div></div></blockquote><div><br=
>Sure you can. It's quite simple:<br><br>template<typename T, typename N=
ullValueProvider><br>class optional<br>{<br>public:<br> constexpr =
optional() : t(NullValueProvider::getNullValue()) {}<br> constexpr op=
tional(const T &_t) : t(_t) {}<br> constexpr optional(const nullo=
pt_T &) : t(NullValueProvider::getNullValue()) {}<br><br> explici=
t operator bool() {return NullValueProvider::isNullValue(t);}<br><br> =
constexpr T const* operator->() const<br> {<br> =
return &t; //As with the regular optional version, the return value is=
undefined if not engaged.<br> }<br><br> constexpr const T &=
;value() const<br> {<br> if(*this) return t;<br>&nb=
sp; throw bad_optional_access; //Throws when not engaged.<br>&n=
bsp; }<br><br>private:<br> T t;<br>};<br><br>You can fill in the rest=
of the methods similarly. `NullValueProvider::getNullValue` and `NullValue=
Provider::isNullValue` would have to be `constexpr` if T is a literal type.=
There will have to be some kind of type determination based on whether T i=
s literal to use `constexpr` conditionally.<br><br>I guess you're going to =
ask what happens if you construct one with the "null" value. Well, what hap=
pens is exactly what you <i>expect</i> to happen: the optional is not engag=
ed. That is what you wanted; that's half the point of explicitly specifying=
one or more values to be not "real" values.<br><br>You can also have appro=
priate copy/move constructors to and from different "null" values, which wi=
ll behave reasonably. By "reasonably", I mean if the optional is considered=
disengaged before the copy, then no matter <i>where</i> it is copied, it w=
ill still be disengaged. Copying an engaged optional to a space-optimized o=
ptional of a different type <i>may</i> cause the optional to be disengaged =
(just like setting a value may disengage it).<br><br>The compiler isn't dec=
iding to "steal" any values; the <i>user</i> is.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_944_11261450.1378248596476--
.
Author: the.ultimate.koala@gmail.com
Date: Tue, 3 Sep 2013 21:48:13 -0700 (PDT)
Raw View
------=_Part_5403_6132035.1378270093941
Content-Type: text/plain; charset=ISO-8859-1
Nicol Bolas,
Thank you for your latest response, your opinion a lot clearer now.
If I may reword your comments into short constructive suggestions, that
would mean :
- That the class is a worthwhile attempt at building something
standardizable, not a hack altogether.
Just look at `optional`. All of that.
>
- That I should more closely keep the "optional" interface.
> ... yes. That's the point of the space optimized optional type. It's
> exactly like `optional<T>`, only certain values are considered "not a real
> value".
>
> I see no reason to give it a special name just because of that *minor*difference between them.
>
>
- That the difference in behaviour is acceptable, and should be proposed
as another base template of optional<> instead of another getting another
name altogether.
> Sure you can. It's quite simple:
>
> template<typename T, typename NullValueProvider>
> class optional
> {
> public:
> constexpr optional() : t(NullValueProvider::getNullValue()) {}
> constexpr optional(const T &_t) : t(_t) {}
> constexpr optional(const nullopt_T &) :
> t(NullValueProvider::getNullValue()) {}
>
> explicit operator bool() {return NullValueProvider::isNullValue(t);}
>
> constexpr T const* operator->() const
> {
> return &t; //As with the regular optional version, the return value is
> undefined if not engaged.
> }
>
> constexpr const T &value() const
> {
> if(*this) return t;
> throw bad_optional_access; //Throws when not engaged.
> }
>
> private:
> T t;
> };
>
<snip/>
>
- That I should implement another base template using functors, to
accomodate values that are not allowed as non-type tempate arguments.
I guess you're going to ask what happens if you construct one with the
> "null" value. Well, what happens is exactly what you *expect* to happen:
> the optional is not engaged. That is what you wanted; that's half the point
> of explicitly specifying one or more values to be not "real" values.
>
>
You can also have appropriate copy/move constructors to and from different
> "null" values, which will behave reasonably. By "reasonably", I mean if the
> optional is considered disengaged before the copy, then no matter *where*it is copied, it will still be disengaged. Copying an engaged optional to a
> space-optimized optional of a different type *may* cause the optional to
> be disengaged (just like setting a value may disengage it).
>
> The compiler isn't deciding to "steal" any values; the *user* is.
>
Indeed.
My comment about the compiler deciding to steal the value was not about
degenerate<>, but a sidenote. It was actually to be read "What would it
take so that we could write a template that decided to steal a value from
the encoding space, that would not conflict with all other allowable values
of the type?". But that's a subject for another forum topic.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5403_6132035.1378270093941
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Nicol Bolas,<br><br>Thank you for your latest response, yo=
ur opinion a lot clearer now.<br><br>If I may reword your comments into sho=
rt constructive suggestions, that would mean :<br><ul><li>That the class is=
a worthwhile attempt at building something standardizable, not a hack alto=
gether.<br></li></ul><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>Just look at `optional`. All of that.<br></div></div></blockq=
uote><div><ul><li>That I should more closely keep the "optional" interface.=
<br></li></ul></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><br>... yes. That's the point of the space optimized optional=
type. It's exactly like `optional<T>`, only certain values are consi=
dered "not a real value". <br></div></div></blockquote><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"><div><br>I see no reason to give =
it a special name just because of that <i>minor</i> difference between them=
..<br> </div></div></blockquote><div><ul><li>That the difference in beh=
aviour is acceptable, and should be proposed as another base template of op=
tional<> instead of another getting another name altogether.</li></ul=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
br>Sure you can. It's quite simple:<br><br>template<typename T, typename=
NullValueProvider><br>class optional<br>{<br>public:<br> constexp=
r optional() : t(NullValueProvider::<wbr>getNullValue()) {}<br> const=
expr optional(const T &_t) : t(_t) {}<br> constexpr optional(cons=
t nullopt_T &) : t(NullValueProvider::<wbr>getNullValue()) {}<br><br>&n=
bsp; explicit operator bool() {return NullValueProvider::<wbr>isNullValue(t=
);}<br><br> constexpr T const* operator->() const<br> {<br>&=
nbsp; return &t; //As with the regular optional version, th=
e return value is undefined if not engaged.<br> }<br><br> const=
expr const T &value() const<br> {<br> if(*this)=
return t;<br> throw bad_optional_access; //Throws when n=
ot engaged.<br> }<br><br>private:<br> T t;<br>};</div></div></b=
lockquote><div></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><snip/><br></div></div></blockquote><div><ul><li>That I=
should implement another base template using functors, to accomodate value=
s that are not allowed as non-type tempate arguments.<br></li></ul></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> I gu=
ess you're going to ask what happens if you construct one with the "null" v=
alue. Well, what happens is exactly what you <i>expect</i> to happen: the o=
ptional is not engaged. That is what you wanted; that's half the point of e=
xplicitly specifying one or more values to be not "real" values.<br> <=
br></div></div></blockquote><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"><div>You can also have appropriate copy/move constructors to=
and from different "null" values, which will behave reasonably. By "reason=
ably", I mean if the optional is considered disengaged before the copy, the=
n no matter <i>where</i> it is copied, it will still be disengaged. Copying=
an engaged optional to a space-optimized optional of a different type <i>m=
ay</i> cause the optional to be disengaged (just like setting a value may d=
isengage it).<br><br>The compiler isn't deciding to "steal" any values; the=
<i>user</i> is.<br></div></div></blockquote><div><br>Indeed.<br><br>My com=
ment about the compiler deciding to steal the value was not about degenerat=
e<>, but a sidenote. It was actually to be read "What would it take s=
o that we could write a template that decided to steal a value from the enc=
oding space, that would not conflict with all other allowable values of the=
type?". But that's a subject for another forum topic.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5403_6132035.1378270093941--
.