Topic: Compressing Optional


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 2 Oct 2013 11:57:48 -0700 (PDT)
Raw View
------=_Part_461_32152031.1380740268646
Content-Type: text/plain; charset=ISO-8859-1

I can think of two ways to optimize the storage size for tr2::optional for
certain T's -- at the cost of potentially adding run-time overhead when
checking for the disengaged state:

1. For optional<optional<T>>, use one bool-size value for storing two
engaged/disengaged flag
2. For certain T's where not all bit-patterns represent a meaningful value
some special value can be used to indicate a disengaged optional and no
additional disengaged flag is needed.

Re 1.
optional<optional<T>> can be specialized to the following representation:

class optional
{
  uint_of_size<bool> engaged_;
  raw_storage_of_size<T> value_;
};

Assuming that bool is never stored in 1-bit, and that its 'true' value is
stored in the least significant bit. We can use the second least
significant bit to store the information about the engaged state of the
outer optional. "1" indicates a disengaged state. You check it with the
following expression:

explicit optional<optional<T>>::operator bool() const {
  return !(engaged_ & 0x10);
}

The value access retuning a type-punned myself:

optional<T> const& optional<optional<T>>::operator*() const {
  return reinterpret_cast<optional<T> const&>(*this);
}

In the inner optional we check for engaged state without the bit-mask.

Well, type-punning doesn't work with constexpr functions, but I wonder if
the same effect cannot be achieved by deriving optional<optional<T>> from
optional<T>.

This could be generalized to optional<optional<optional<T>>>

Re 2.
Second optimization works for types where there is a value (or bit-pattern
not representing any value) that is guaranteed never to make sense:
a pointer with address 0x1
or a bool with bit pattern 0x10.

For such types optional doesn't need to use a separate flag, but use the
special value to indicate a disengaged state. In order to allow programmers
to easily customize optional for their types, another interface could be
standardized: a type trait:

template <typename T>
struct optional_optimized_disengaged_state_traits
{
  constexpr static bool is_optimized = false;
  constexpr static raw_storage_of_size<T> const& value();
};

If you want, you can specialize this trait to enable the optimization:

template <typename T>
struct optional_optimized_disengaged_state_traits<T*>
{
  constexpr static bool is_optimized = true;
  constexpr static raw_storage_of_size<T> const& value() {
    return cast( (T*)1 );
  }
};

template <>
struct optional_optimized_disengaged_state_traits<bool>
{
  constexpr static bool is_optimized = true;
  constexpr static raw_storage_of_size<bool> const& value() {
    return cast( 0x10 );
  }
};

Now, checking for disengaged state can be implemented by memcmp:

explicit optional<T>::operator bool() const {
  return memcmp (&value_, &optional_optimized_disengaged_state_traits<T>::
value(), sizeof(value_));
}

Again, I am not sure if this could be made to work with constexpr
functions. If not it is worth considering sacrificing the constexpr
requirements in order to enable such optimizations.

Regards,
&rzej

--

---
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_461_32152031.1380740268646
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>I can think of two ways to optimize the storage =
size for=20
tr2::optional for certain T's -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br><br></div><div=
>1. For optional&lt;optional&lt;T&gt;&gt;, use one bool-size value for stor=
ing two engaged/disengaged flag<br></div><div>2.
 For certain T's where not all bit-patterns represent a meaningful value
 some special value can be used to indicate a disengaged optional and no
 additional disengaged flag is needed.<br></div><div><br></div>
<div>Re 1.<br><span style=3D"font-family: courier new,monospace;">optional&=
lt;optional&lt;T&gt;&gt;</span> can be specialized to the following represe=
ntation:<br><br></div><div class=3D"prettyprint" style=3D"background-color:=
 rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid;=
 border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> optional <br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; uint_of_size</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> engaged_</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; raw_storage_of_size</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</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></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span></div=
></code></div><div><br></div><div>Assuming
 that bool is never stored in 1-bit, and that its 'true' value is stored
 in the least significant bit. We can use the second least significant=20
bit to store the information about the engaged state of the outer=20
optional. "1" indicates a disengaged state. You check it with the=20
following expression:<br><br></div><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">explicit</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> optional</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</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">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&gt;&gt;::</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"styled-by-prettify">bool</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </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>&nbsp; </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</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=
ngaged_ </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #066;" class=3D"styled-by-prettify">0x10</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"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br></d=
iv><div>The value access retuning a type-punned myself:<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: #000;" class=3D"styled-by-prettify">optional</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> optional</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">optional</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;&gt;::=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">*()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; </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: #008;" class=3D"styled-b=
y-prettify">reinterpret_cast</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">optional</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&gt;(*</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">this</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"color: #6=
60;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div><br></div><div>In th=
e inner optional we check for engaged state without the bit-mask. <br><br>W=
ell,
 type-punning doesn't work with constexpr functions, but I wonder if the
 same effect cannot be achieved by deriving=20
optional&lt;optional&lt;T&gt;&gt; from optional&lt;T&gt;.<br><br></div><div=
>This could be generalized to<span style=3D"font-family: courier new,monosp=
ace;"> optional&lt;optional&lt;optional&lt;T&gt;&gt;&gt;</span></div><div><=
br></div><div>Re 2.<br></div><div>Second
 optimization works for types where there is a value (or bit-pattern not
 representing any value) that is guaranteed never to make sense:<br></div><=
div>a pointer with address 0x1<br></div><div>or a bool with bit pattern 0x1=
0.<br><br></div><div>For
 such types optional doesn't need to use a separate flag, but use the=20
special value to indicate a disengaged state. In order to allow=20
programmers to easily customize optional for their types, another=20
interface could be standardized: a type trait:<br></div><div><br></div><div=
></div></div><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> optional_optimized_disengaged_state_t=
raits<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">static</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"> is_optimized </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>&nbsp; </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=
">static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> r=
aw_storage_of_size</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> 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;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><div><div><div><br></div><d=
iv>If you want, you can specialize this trait to enable the optimization:<b=
r><br></div><div class=3D"prettyprint" 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 class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> optional_optimized_disengaged_state_traits=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">*&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">static</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-prett=
ify"> is_optimized </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">true</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">static</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> raw_storage_of_size</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> value</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> cast</span><spa=
n 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">T</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">*)</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">1</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </s=
pan><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"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><div><=
br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&gt;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> optional_optimized_=
disengaged_state_traits</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</s=
pan><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"> is_optimized </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">static</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> raw_storage_of_size</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&amp;</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>&nbsp; &nbsp; </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"> cast</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">0x10</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>&nbsp; </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">};</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></di=
v></code></div><div><br></div></div><div>Now, checking for disengaged state=
 can be implemented by memcmp:<br><br></div><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; word-wrap: break-word;"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">explicit</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> optional</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&gt;::</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">operator</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
bool</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">const</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>&nbsp; </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> memcmp </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(&amp;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">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"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">optiona=
l_optimized_disengaged_state_traits</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">value</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><s=
pan 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;" 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></span></div></code></div><div><br></div><div>Aga=
in,
 I am not sure if this could be made to work with constexpr functions.=20
If not it is worth considering sacrificing the constexpr requirements in
 order to enable such optimizations.<br><br>Regards,<br>&amp;rzej<br></div>=
<div><br></div></div></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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_461_32152031.1380740268646--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 2 Oct 2013 14:07:38 -0500
Raw View
--001a11c2ddb8cf3ce404e7c6cadf
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 2 October 2013 13:57, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wrot=
e:

> I can think of two ways to optimize the storage size for tr2::optional fo=
r
> certain T's -- at the cost of potentially adding run-time overhead when
> checking for the disengaged state:
>

Is this anything more than an implementation detail (and therefore not on
topic for this forum)?

For such types optional doesn't need to use a separate flag, but use the
> special value to indicate a disengaged state. In order to allow programme=
rs
> to easily customize optional for their types, another interface could be
> standardized: a type trait:
>

I have yet to see *any* benchmarks of real world programs where adding such
complexity would be a net benefit to anyone, let alone most users.

If people really wish to go down this route, I can't stop them, other than
to say that in all likelihood I will argue and vote strongly against such a
proposal.


> template <typename T>
> struct optional_optimized_disengaged_state_traits<T*>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<T> const& value() {
>     return cast( (T*)1 );
>   }
> };
>
> Are you sure that doesn't invoke undefined behavior?  This stuff is reall=
y
tricky to get right, and users generally have less freedom than compiler
vendors, since vendors can define undefined behavior any way they like to
make things work.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=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/.

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

<div dir=3D"ltr">On 2 October 2013 13:57, Andrzej Krzemie=C5=84ski <span di=
r=3D"ltr">&lt;<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrze=
mi1@gmail.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div clas=
s=3D"gmail_quote">

<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"><div><div>I can think of tw=
o ways to optimize the storage size for=20
tr2::optional for certain T&#39;s -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br></div></div></=
div></blockquote><div><br></div><div>Is this anything more than an implemen=
tation detail (and therefore not on topic for this forum)?=C2=A0</div><div>

<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>For
 such types optional doesn&#39;t need to use a separate flag, but use the=
=20
special value to indicate a disengaged state. In order to allow=20
programmers to easily customize optional for their types, another=20
interface could be standardized: a type trait:<br></div></div></div></block=
quote><div><br></div><div>I have yet to see *any* benchmarks of real world =
programs where adding such complexity would be a net benefit to anyone, let=
 alone most users.</div>

<div><br></div><div>If people really wish to go down this route, I can&#39;=
t stop them, other than to say that in all likelihood I will argue and vote=
 strongly against such a proposal.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex">

<div dir=3D"ltr"><div><div></div></div><div><div><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">te=
mplate</span><span style> </span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#008">typename</span><span style> T</span><span style=3D"c=
olor:#660">&gt;</span><span style><br>

</span><span style=3D"color:#008">struct</span><span style> optional_optimi=
zed_disengaged_state_traits</span><span style=3D"color:#660">&lt;</span><sp=
an style>T</span><span style=3D"color:#660">*&gt;</span><span style><br></s=
pan><span style=3D"color:#660">{</span><span style><br>

=C2=A0 </span><span style=3D"color:#008">constexpr</span><span style> </spa=
n><span style=3D"color:#008">static</span><span style> </span><span style=
=3D"color:#008">bool</span><span style> is_optimized </span><span style=3D"=
color:#660">=3D</span><span style> </span><span style=3D"color:#008">true</=
span><span style=3D"color:#660">;</span><span style><br>

=C2=A0 </span><span style=3D"color:#008">constexpr</span><span style> </spa=
n><span style=3D"color:#008">static</span><span style> raw_storage_of_size<=
/span><span style=3D"color:#660">&lt;</span><span style>T</span><span style=
=3D"color:#660">&gt;</span><span style> </span><span style=3D"color:#008">c=
onst</span><span style=3D"color:#660">&amp;</span><span style> value</span>=
<span style=3D"color:#660">()</span><span style> </span><span style=3D"colo=
r:#660">{</span><span style><br>

=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style> c=
ast</span><span style=3D"color:#660">(</span><span style> </span><span styl=
e=3D"color:#660">(</span><span style>T</span><span style=3D"color:#660">*)<=
/span><span style=3D"color:#066">1</span><span style> </span><span style=3D=
"color:#660">);</span><span style><br>

=C2=A0 </span><span style=3D"color:#660">}</span><span style><br></span><sp=
an style=3D"color:#660">};</span><span style><br></span></div></code></div>=
<div><br></div></div></div></div></blockquote><div>Are you sure that doesn&=
#39;t invoke undefined behavior? =C2=A0This stuff is really tricky to get r=
ight, and users generally have less freedom than compiler vendors, since ve=
ndors can define undefined behavior any way they like to make things work.<=
/div>

</div>-- <br>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"=
mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>=
&gt;=C2=A0 (847) 691-1404
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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 />

--001a11c2ddb8cf3ce404e7c6cadf--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Wed, 2 Oct 2013 12:08:20 -0700
Raw View
--90e6ba614a764b786c04e7c6cdf0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Do we really want to compress this? optional<optional<T>> is certainly an
anti-pattern.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com


On Wed, Oct 2, 2013 at 11:57 AM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om>wrote:

> I can think of two ways to optimize the storage size for tr2::optional fo=
r
> certain T's -- at the cost of potentially adding run-time overhead when
> checking for the disengaged state:
>
> 1. For optional<optional<T>>, use one bool-size value for storing two
> engaged/disengaged flag
> 2. For certain T's where not all bit-patterns represent a meaningful valu=
e
> some special value can be used to indicate a disengaged optional and no
> additional disengaged flag is needed.
>
> Re 1.
> optional<optional<T>> can be specialized to the following representation:
>
> class optional
> {
>   uint_of_size<bool> engaged_;
>   raw_storage_of_size<T> value_;
> };
>
> Assuming that bool is never stored in 1-bit, and that its 'true' value is
> stored in the least significant bit. We can use the second least
> significant bit to store the information about the engaged state of the
> outer optional. "1" indicates a disengaged state. You check it with the
> following expression:
>
> explicit optional<optional<T>>::operator bool() const {
>   return !(engaged_ & 0x10);
> }
>
> The value access retuning a type-punned myself:
>
> optional<T> const& optional<optional<T>>::operator*() const {
>   return reinterpret_cast<optional<T> const&>(*this);
> }
>
> In the inner optional we check for engaged state without the bit-mask.
>
> Well, type-punning doesn't work with constexpr functions, but I wonder if
> the same effect cannot be achieved by deriving optional<optional<T>> from
> optional<T>.
>
> This could be generalized to optional<optional<optional<T>>>
>
> Re 2.
> Second optimization works for types where there is a value (or bit-patter=
n
> not representing any value) that is guaranteed never to make sense:
> a pointer with address 0x1
> or a bool with bit pattern 0x10.
>
> For such types optional doesn't need to use a separate flag, but use the
> special value to indicate a disengaged state. In order to allow programme=
rs
> to easily customize optional for their types, another interface could be
> standardized: a type trait:
>
> template <typename T>
> struct optional_optimized_disengaged_state_traits
> {
>   constexpr static bool is_optimized =3D false;
>   constexpr static raw_storage_of_size<T> const& value();
> };
>
> If you want, you can specialize this trait to enable the optimization:
>
> template <typename T>
> struct optional_optimized_disengaged_state_traits<T*>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<T> const& value() {
>     return cast( (T*)1 );
>   }
> };
>
> template <>
> struct optional_optimized_disengaged_state_traits<bool>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<bool> const& value() {
>     return cast( 0x10 );
>   }
> };
>
> Now, checking for disengaged state can be implemented by memcmp:
>
> explicit optional<T>::operator bool() const {
>   return memcmp (&value_, &optional_optimized_disengaged_state_traits<T>:=
:
> value(), sizeof(value_));
> }
>
> Again, I am not sure if this could be made to work with constexpr
> functions. If not it is worth considering sacrificing the constexpr
> requirements in order to enable such optimizations.
>
> Regards,
> &rzej
>
>  --
>
> ---
> 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/.
>

--=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/.

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

<div dir=3D"ltr">Do we really want to compress this? optional&lt;optional&l=
t;T&gt;&gt; is certainly an anti-pattern.</div><div class=3D"gmail_extra"><=
br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O&#39;Neal</div><div><a h=
ref=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https://github.=
com/BillyONeal/</a></div>

<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Wed, Oct 2, 2013 at 11:57 AM, Andrzej=
 Krzemie=C5=84ski <span dir=3D"ltr">&lt;<a href=3D"mailto:akrzemi1@gmail.co=
m" target=3D"_blank">akrzemi1@gmail.com</a>&gt;</span> wrote:<br><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex">

<div dir=3D"ltr"><div><div>I can think of two ways to optimize the storage =
size for=20
tr2::optional for certain T&#39;s -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br><br></div><div=
>1. For optional&lt;optional&lt;T&gt;&gt;, use one bool-size value for stor=
ing two engaged/disengaged flag<br></div><div>2.
 For certain T&#39;s where not all bit-patterns represent a meaningful valu=
e
 some special value can be used to indicate a disengaged optional and no
 additional disengaged flag is needed.<br></div><div><br></div>
<div>Re 1.<br><span style=3D"font-family:courier new,monospace">optional&lt=
;optional&lt;T&gt;&gt;</span> can be specialized to the following represent=
ation:<br><br></div><div style=3D"border:1px solid rgb(187,187,187);backgro=
und-color:rgb(250,250,250)">

<code><div><span style=3D"color:rgb(0,0,136)">class</span><span> optional <=
br></span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 uin=
t_of_size</span><span style=3D"color:rgb(0,136,0)">&lt;bool&gt;</span><span=
> engaged_</span><span style=3D"color:rgb(102,102,0)">;</span><span><br>

=C2=A0 raw_storage_of_size</span><span style=3D"color:rgb(102,102,0)">&lt;<=
/span><span>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span> =
value_</span><span style=3D"color:rgb(102,102,0)">;</span><span><br></span>=
<span style=3D"color:rgb(102,102,0)">};</span></div>

</code></div><div><br></div><div>Assuming
 that bool is never stored in 1-bit, and that its &#39;true&#39; value is s=
tored
 in the least significant bit. We can use the second least significant=20
bit to store the information about the engaged state of the outer=20
optional. &quot;1&quot; indicates a disengaged state. You check it with the=
=20
following expression:<br><br></div><div style=3D"border:1px solid rgb(187,1=
87,187);background-color:rgb(250,250,250)"><code><div><span style=3D"color:=
rgb(0,0,136)">explicit</span><span> optional</span><span style=3D"color:rgb=
(102,102,0)">&lt;</span><span>optional</span><span style=3D"color:rgb(102,1=
02,0)">&lt;</span><span>T</span><span style=3D"color:rgb(102,102,0)">&gt;&g=
t;::</span><span style=3D"color:rgb(0,0,136)">operator</span><span> </span>=
<span style=3D"color:rgb(0,0,136)">bool</span><span style=3D"color:rgb(102,=
102,0)">()</span><span> </span><span style=3D"color:rgb(0,0,136)">const</sp=
an><span> </span><span style=3D"color:rgb(102,102,0)">{</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span> </span=
><span style=3D"color:rgb(102,102,0)">!(</span><span>engaged_ </span><span =
style=3D"color:rgb(102,102,0)">&amp;</span><span> </span><span style=3D"col=
or:rgb(0,102,102)">0x10</span><span style=3D"color:rgb(102,102,0)">);</span=
><span> <br>

</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><div><br></div><div>The value access retuning a type-punned my=
self:<br><br><div style=3D"border:1px solid rgb(187,187,187);background-col=
or:rgb(250,250,250)">

<code><div><span>optional</span><span style=3D"color:rgb(102,102,0)">&lt;</=
span><span>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span> <=
/span><span style=3D"color:rgb(0,0,136)">const</span><span style=3D"color:r=
gb(102,102,0)">&amp;</span><span> optional</span><span style=3D"color:rgb(1=
02,102,0)">&lt;</span><span>optional</span><span style=3D"color:rgb(102,102=
,0)">&lt;</span><span>T</span><span style=3D"color:rgb(102,102,0)">&gt;&gt;=
::</span><span style=3D"color:rgb(0,0,136)">operator</span><span style=3D"c=
olor:rgb(102,102,0)">*()</span><span> </span><span style=3D"color:rgb(0,0,1=
36)">const</span><span> </span><span style=3D"color:rgb(102,102,0)">{</span=
><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span> </span=
><span style=3D"color:rgb(0,0,136)">reinterpret_cast</span><span style=3D"c=
olor:rgb(102,102,0)">&lt;</span><span>optional</span><span style=3D"color:r=
gb(102,102,0)">&lt;</span><span>T</span><span style=3D"color:rgb(102,102,0)=
">&gt;</span><span> </span><span style=3D"color:rgb(0,0,136)">const</span><=
span style=3D"color:rgb(102,102,0)">&amp;&gt;(*</span><span style=3D"color:=
rgb(0,0,136)">this</span><span style=3D"color:rgb(102,102,0)">);</span><spa=
n> <br>

</span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span></div>=
</code></div><br></div><div>In the inner optional we check for engaged stat=
e without the bit-mask. <br><br>Well,
 type-punning doesn&#39;t work with constexpr functions, but I wonder if th=
e
 same effect cannot be achieved by deriving=20
optional&lt;optional&lt;T&gt;&gt; from optional&lt;T&gt;.<br><br></div><div=
>This could be generalized to<span style=3D"font-family:courier new,monospa=
ce"> optional&lt;optional&lt;optional&lt;T&gt;&gt;&gt;</span></div><div>

<br></div><div>Re 2.<br></div><div>Second
 optimization works for types where there is a value (or bit-pattern not
 representing any value) that is guaranteed never to make sense:<br></div><=
div>a pointer with address 0x1<br></div><div>or a bool with bit pattern 0x1=
0.<br><br></div><div>For
 such types optional doesn&#39;t need to use a separate flag, but use the=
=20
special value to indicate a disengaged state. In order to allow=20
programmers to easily customize optional for their types, another=20
interface could be standardized: a type trait:<br></div><div><br></div><div=
></div></div><div style=3D"border:1px solid rgb(187,187,187);background-col=
or:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">template=
</span><span> </span><span style=3D"color:rgb(102,102,0)">&lt;</span><span =
style=3D"color:rgb(0,0,136)">typename</span><span> T</span><span style=3D"c=
olor:rgb(102,102,0)">&gt;</span><span><br>

</span><span style=3D"color:rgb(0,0,136)">struct</span><span> optional_opti=
mized_disengaged_state_traits<br></span><span style=3D"color:rgb(102,102,0)=
">{</span><span><br>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">conste=
xpr</span><span> </span><span style=3D"color:rgb(0,0,136)">static</span><sp=
an> </span><span style=3D"color:rgb(0,0,136)">bool</span><span> is_optimize=
d </span><span style=3D"color:rgb(102,102,0)">=3D</span><span> </span><span=
 style=3D"color:rgb(0,0,136)">false</span><span style=3D"color:rgb(102,102,=
0)">;</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">constexpr</span><span> </s=
pan><span style=3D"color:rgb(0,0,136)">static</span><span> raw_storage_of_s=
ize</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span>T</span><sp=
an style=3D"color:rgb(102,102,0)">&gt;</span><span> </span><span style=3D"c=
olor:rgb(0,0,136)">const</span><span style=3D"color:rgb(102,102,0)">&amp;</=
span><span> value</span><span style=3D"color:rgb(102,102,0)">();</span><spa=
n><br>

</span><span style=3D"color:rgb(102,102,0)">};</span><span><br></span></div=
></code></div><div><div><div><br></div><div>If you want, you can specialize=
 this trait to enable the optimization:<br><br></div><div style=3D"border:1=
px solid rgb(187,187,187);background-color:rgb(250,250,250)">

<code><div><span style=3D"color:rgb(0,0,136)">template</span><span> </span>=
<span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,=
0,136)">typename</span><span> T</span><span style=3D"color:rgb(102,102,0)">=
&gt;</span><span><br>

</span><span style=3D"color:rgb(0,0,136)">struct</span><span> optional_opti=
mized_disengaged_state_traits</span><span style=3D"color:rgb(102,102,0)">&l=
t;</span><span>T</span><span style=3D"color:rgb(102,102,0)">*&gt;</span><sp=
an><br>

</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 </span=
><span style=3D"color:rgb(0,0,136)">constexpr</span><span> </span><span sty=
le=3D"color:rgb(0,0,136)">static</span><span> </span><span style=3D"color:r=
gb(0,0,136)">bool</span><span> is_optimized </span><span style=3D"color:rgb=
(102,102,0)">=3D</span><span> </span><span style=3D"color:rgb(0,0,136)">tru=
e</span><span style=3D"color:rgb(102,102,0)">;</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">constexpr</span><span> </s=
pan><span style=3D"color:rgb(0,0,136)">static</span><span> raw_storage_of_s=
ize</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span>T</span><sp=
an style=3D"color:rgb(102,102,0)">&gt;</span><span> </span><span style=3D"c=
olor:rgb(0,0,136)">const</span><span style=3D"color:rgb(102,102,0)">&amp;</=
span><span> value</span><span style=3D"color:rgb(102,102,0)">()</span><span=
> </span><span style=3D"color:rgb(102,102,0)">{</span><span><br>

=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 cast</span><span style=3D"color:rgb(102,102,0)">(</span><span> </span><spa=
n style=3D"color:rgb(102,102,0)">(</span><span>T</span><span style=3D"color=
:rgb(102,102,0)">*)</span><span style=3D"color:rgb(0,102,102)">1</span><spa=
n> </span><span style=3D"color:rgb(102,102,0)">);</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span=
><span style=3D"color:rgb(102,102,0)">};</span><span><br></span></div></cod=
e></div><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187)=
;background-color:rgb(250,250,250)">

<code><div><span style=3D"color:rgb(0,0,136)">template</span><span> </span>=
<span style=3D"color:rgb(102,102,0)">&lt;&gt;</span><span><br></span><span =
style=3D"color:rgb(0,0,136)">struct</span><span> optional_optimized_disenga=
ged_state_traits</span><span style=3D"color:rgb(0,136,0)">&lt;bool&gt;</spa=
n><span><br>

</span><span style=3D"color:rgb(102,102,0)">{</span><span><br>=C2=A0 </span=
><span style=3D"color:rgb(0,0,136)">constexpr</span><span> </span><span sty=
le=3D"color:rgb(0,0,136)">static</span><span> </span><span style=3D"color:r=
gb(0,0,136)">bool</span><span> is_optimized </span><span style=3D"color:rgb=
(102,102,0)">=3D</span><span> </span><span style=3D"color:rgb(0,0,136)">tru=
e</span><span style=3D"color:rgb(102,102,0)">;</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">constexpr</span><span> </s=
pan><span style=3D"color:rgb(0,0,136)">static</span><span> raw_storage_of_s=
ize</span><span style=3D"color:rgb(0,136,0)">&lt;bool&gt;</span><span> </sp=
an><span style=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rgb(=
102,102,0)">&amp;</span><span> value</span><span style=3D"color:rgb(102,102=
,0)">()</span><span> </span><span style=3D"color:rgb(102,102,0)">{</span><s=
pan><br>

=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span>=
 cast</span><span style=3D"color:rgb(102,102,0)">(</span><span> </span><spa=
n style=3D"color:rgb(0,102,102)">0x10</span><span> </span><span style=3D"co=
lor:rgb(102,102,0)">);</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(102,102,0)">}</span><span><br></span=
><span style=3D"color:rgb(102,102,0)">};</span><span><br></span></div></cod=
e></div><div><br></div></div><div>Now, checking for disengaged state can be=
 implemented by memcmp:<br>

<br></div><div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">explicit</s=
pan><span> optional</span><span style=3D"color:rgb(102,102,0)">&lt;</span><=
span>T</span><span style=3D"color:rgb(102,102,0)">&gt;::</span><span style=
=3D"color:rgb(0,0,136)">operator</span><span> </span><span style=3D"color:r=
gb(0,0,136)">bool</span><span style=3D"color:rgb(102,102,0)">()</span><span=
> </span><span style=3D"color:rgb(0,0,136)">const</span><span> </span><span=
 style=3D"color:rgb(102,102,0)">{</span><span><br>

=C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span> memcmp=
 </span><span style=3D"color:rgb(102,102,0)">(&amp;</span><span>value_</spa=
n><span style=3D"color:rgb(102,102,0)">,</span><span> </span><span style=3D=
"color:rgb(102,102,0)">&amp;</span><span>optional_optimized_disengaged_stat=
e_traits</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span>T</spa=
n><span style=3D"color:rgb(102,102,0)">&gt;::</span><span>value</span><span=
 style=3D"color:rgb(102,102,0)">(),</span><span> </span><span style=3D"colo=
r:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102,102,0)">(</span><=
span>value_</span><span style=3D"color:rgb(102,102,0)">));</span><span><br>

</span><span style=3D"color:rgb(102,102,0)">}</span><span> <br></span></div=
></code></div><div><br></div><div>Again,
 I am not sure if this could be made to work with constexpr functions.=20
If not it is worth considering sacrificing the constexpr requirements in
 order to enable such optimizations.<br><br>Regards,<br>&amp;rzej<span clas=
s=3D"HOEnZb"><font color=3D"#888888"><br></font></span></div><span class=3D=
"HOEnZb"><font color=3D"#888888"><div><br></div></font></span></div></div><=
/div>

<span class=3D"HOEnZb"><font color=3D"#888888">

<p></p>

-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%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 />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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 />

--90e6ba614a764b786c04e7c6cdf0--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 02 Oct 2013 12:30:03 -0700
Raw View
On quarta-feira, 2 de outubro de 2013 11:57:48, Andrzej Krzemie=F1ski wrote=
:
> template <typename T>
> struct optional_optimized_disengaged_state_traits<T*>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<T> const& value() {
>     return cast( (T*)1 );
>   }
> };

You cannot assume that a pointer of value 1 is invalid. In fact, there's on=
ly=20
one pointer whose value is invalid and that's null (and such a pointer does=
n't=20
have to be stored as a bitwise zero).

You can only assume that if you know the platform's ABI. That's not the cas=
e=20
for this forum, we have to assume all possibilities may exist.

> template <>
> struct optional_optimized_disengaged_state_traits<bool>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<bool> const& value() {
>     return cast( 0x10 );
>   }
> };

And again, this only works if the user isn't abusing the type for storing=
=20
something else. Since optional::operator* returns an lvalue reference to th=
e=20
data, the user could be storing anything there or casting to other values v=
ia=20
type-punning (strict aliasing is only broken if you write one type and read=
=20
another).

No, you must assume that all bits are used by the user, unless the user tel=
ls=20
you that there are certain bit patterns that won't be used. That probably=
=20
means a user-defined specialisation of std::optional.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: Alisdair Meredith <alisdairm@me.com>
Date: Wed, 02 Oct 2013 17:04:20 -0400
Raw View
--Apple-Mail-DA694001-66F6-4362-846A-6681C57303F6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8

I thought about merging the engaged bits, but you must spell out very caref=
ully what our concurrency guarantees are in this case.  Can I read the oute=
r optional's engaged state while changing the engagement of the inner optio=
nal?

Sent from my iPhone

On 2 Oct 2013, at 14:57, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wrot=
e:

> I can think of two ways to optimize the storage size for tr2::optional fo=
r certain T's -- at the cost of potentially adding run-time overhead when c=
hecking for the disengaged state:
>=20
> 1. For optional<optional<T>>, use one bool-size value for storing two eng=
aged/disengaged flag
> 2. For certain T's where not all bit-patterns represent a meaningful valu=
e  some special value can be used to indicate a disengaged optional and no =
 additional disengaged flag is needed.
>=20
> Re 1.
> optional<optional<T>> can be specialized to the following representation:
>=20
> class optional=20
> {
>   uint_of_size<bool> engaged_;
>   raw_storage_of_size<T> value_;
> };
>=20
> Assuming that bool is never stored in 1-bit, and that its 'true' value is=
 stored in the least significant bit. We can use the second least significa=
nt bit to store the information about the engaged state of the outer option=
al. "1" indicates a disengaged state. You check it with the following expre=
ssion:
>=20
> explicit optional<optional<T>>::operator bool() const {
>   return !(engaged_ & 0x10);=20
> }
>=20
> The value access retuning a type-punned myself:
>=20
> optional<T> const& optional<optional<T>>::operator*() const {
>   return reinterpret_cast<optional<T> const&>(*this);=20
> }
>=20
> In the inner optional we check for engaged state without the bit-mask.=20
>=20
> Well, type-punning doesn't work with constexpr functions, but I wonder if=
 the same effect cannot be achieved by deriving optional<optional<T>> from =
optional<T>.
>=20
> This could be generalized to optional<optional<optional<T>>>
>=20
> Re 2.
> Second optimization works for types where there is a value (or bit-patter=
n not representing any value) that is guaranteed never to make sense:
> a pointer with address 0x1
> or a bool with bit pattern 0x10.
>=20
> For such types optional doesn't need to use a separate flag, but use the =
special value to indicate a disengaged state. In order to allow programmers=
 to easily customize optional for their types, another interface could be s=
tandardized: a type trait:
>=20
> template <typename T>
> struct optional_optimized_disengaged_state_traits
> {
>   constexpr static bool is_optimized =3D false;
>   constexpr static raw_storage_of_size<T> const& value();
> };
>=20
> If you want, you can specialize this trait to enable the optimization:
>=20
> template <typename T>
> struct optional_optimized_disengaged_state_traits<T*>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<T> const& value() {
>     return cast( (T*)1 );
>   }
> };
>=20
> template <>
> struct optional_optimized_disengaged_state_traits<bool>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<bool> const& value() {
>     return cast( 0x10 );
>   }
> };
>=20
> Now, checking for disengaged state can be implemented by memcmp:
>=20
> explicit optional<T>::operator bool() const {
>   return memcmp (&value_, &optional_optimized_disengaged_state_traits<T>:=
:value(), sizeof(value_));
> }=20
>=20
> Again, I am not sure if this could be made to work with constexpr functio=
ns. If not it is worth considering sacrificing the constexpr requirements i=
n order to enable such optimizations.
>=20
> Regards,
> &rzej
>=20
> --=20
> =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=
 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-propo=
sals/.

--=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/.

--Apple-Mail-DA694001-66F6-4362-846A-6681C57303F6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head></head><body bgcolor=3D"#FFFFFF"><div>I thought about merging t=
he engaged bits, but you must spell out very carefully what our concurrency=
 guarantees are in this case. &nbsp;Can I read the outer optional's engaged=
 state while changing the engagement of the inner optional?<br><br>Sent fro=
m my iPhone</div><div><br>On 2 Oct 2013, at 14:57, Andrzej Krzemie=C5=84ski=
 &lt;<a href=3D"mailto:akrzemi1@gmail.com">akrzemi1@gmail.com</a>&gt; wrote=
:<br><br></div><div></div><blockquote type=3D"cite"><div><div dir=3D"ltr"><=
div><div>I can think of two ways to optimize the storage size for=20
tr2::optional for certain T's -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br><br></div><div=
>1. For optional&lt;optional&lt;T&gt;&gt;, use one bool-size value for stor=
ing two engaged/disengaged flag<br></div><div>2.
 For certain T's where not all bit-patterns represent a meaningful value
 some special value can be used to indicate a disengaged optional and no
 additional disengaged flag is needed.<br></div><div><br></div>
<div>Re 1.<br><span style=3D"font-family: courier new,monospace;">optional&=
lt;optional&lt;T&gt;&gt;</span> can be specialized to the following represe=
ntation:<br><br></div><div class=3D"prettyprint" style=3D"background-color:=
 rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid;=
 border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> optional <br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; uint_of_size</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> engaged_</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>&nbsp; raw_storage_of_size</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;</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></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span></div=
></code></div><div><br></div><div>Assuming
 that bool is never stored in 1-bit, and that its 'true' value is stored
 in the least significant bit. We can use the second least significant=20
bit to store the information about the engaged state of the outer=20
optional. "1" indicates a disengaged state. You check it with the=20
following expression:<br><br></div><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">explicit</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> optional</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</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">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&gt;&gt;::</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"styled-by-prettify">bool</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </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>&nbsp; </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</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=
ngaged_ </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #066;" class=3D"styled-by-prettify">0x10</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"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br></d=
iv><div>The value access retuning a type-punned myself:<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: #000;" class=3D"styled-by-prettify">optional</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> optional</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">optional</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;&gt;::=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">*()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>&nbsp; </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: #008;" class=3D"styled-b=
y-prettify">reinterpret_cast</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">optional</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&gt;(*</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">this</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"color: #6=
60;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div><br></div><div>In th=
e inner optional we check for engaged state without the bit-mask. <br><br>W=
ell,
 type-punning doesn't work with constexpr functions, but I wonder if the
 same effect cannot be achieved by deriving=20
optional&lt;optional&lt;T&gt;&gt; from optional&lt;T&gt;.<br><br></div><div=
>This could be generalized to<span style=3D"font-family: courier new,monosp=
ace;"> optional&lt;optional&lt;optional&lt;T&gt;&gt;&gt;</span></div><div><=
br></div><div>Re 2.<br></div><div>Second
 optimization works for types where there is a value (or bit-pattern not
 representing any value) that is guaranteed never to make sense:<br></div><=
div>a pointer with address 0x1<br></div><div>or a bool with bit pattern 0x1=
0.<br><br></div><div>For
 such types optional doesn't need to use a separate flag, but use the=20
special value to indicate a disengaged state. In order to allow=20
programmers to easily customize optional for their types, another=20
interface could be standardized: a type trait:<br></div><div><br></div><div=
></div></div><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> optional_optimized_disengaged_state_t=
raits<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">constexpr=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">static</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"> is_optimized </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>&nbsp; </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=
">static</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> r=
aw_storage_of_size</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> 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;" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><div><div><div><br></div><d=
iv>If you want, you can specialize this trait to enable the optimization:<b=
r><br></div><div class=3D"prettyprint" 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 class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> optional_optimized_disengaged_state_traits=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">*&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">static</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-prett=
ify"> is_optimized </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">true</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">static</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> raw_storage_of_size</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> value</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> cast</span><spa=
n 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">T</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">*)</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">1</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </s=
pan><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"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><div><=
br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(250=
, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-=
width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&gt;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> optional_optimized_=
disengaged_state_traits</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</s=
pan><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"> is_optimized </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">static</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> raw_storage_of_size</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&lt;bool&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&amp;</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>&nbsp; &nbsp; </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"> cast</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">0x10</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>&nbsp; </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">};</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></di=
v></code></div><div><br></div></div><div>Now, checking for disengaged state=
 can be implemented by memcmp:<br><br></div><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; word-wrap: break-word;"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">explicit</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> optional</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&gt;::</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">operator</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
bool</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">const</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>&nbsp; </span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> memcmp </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(&amp;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">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"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">optiona=
l_optimized_disengaged_state_traits</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">value</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><s=
pan 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;" 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></span></div></code></div><div><br></div><div>Aga=
in,
 I am not sure if this could be made to work with constexpr functions.=20
If not it is worth considering sacrificing the constexpr requirements in
 order to enable such optimizations.<br><br>Regards,<br>&amp;rzej<br></div>=
<div><br></div></div></div></div>

<p></p>

-- <br>
&nbsp;<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"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br>
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>
</div></blockquote></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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 />

--Apple-Mail-DA694001-66F6-4362-846A-6681C57303F6--

.


Author: David Stone <deusexsophismata@gmail.com>
Date: Wed, 2 Oct 2013 17:03:08 -0700 (PDT)
Raw View
------=_Part_2171_17672787.1380758588649
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, October 2, 2013 1:30:03 PM UTC-6, Thiago Macieira wrote:
>
> On quarta-feira, 2 de outubro de 2013 11:57:48, Andrzej Krzemie=C5=84ski =
wrote:=20
> > template <typename T>=20
> > struct optional_optimized_disengaged_state_traits<T*>=20
> > {=20
> >   constexpr static bool is_optimized =3D true;=20
> >   constexpr static raw_storage_of_size<T> const& value() {=20
> >     return cast( (T*)1 );=20
> >   }=20
> > };=20
>
> You cannot assume that a pointer of value 1 is invalid. In fact, there's=
=20
> only=20
> one pointer whose value is invalid and that's null (and such a pointer=20
> doesn't=20
> have to be stored as a bitwise zero).=20
>

Which is why this is being proposed as a possible class that the user /=20
vendor could specialize, rather than a specialization that should be=20
defined for all pointers in the standard as a guarantee. If my code will=20
only run on such a system (or if I'm the compiler vendor and I know that=20
this compilation of this code is only running on such a system), then this=
=20
could simplify the creation of such a compressed optional.

--=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_2171_17672787.1380758588649
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, October 2, 2013 1:30:03 PM UTC-6, Thiago Mac=
ieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On quarta-feira, 2=
 de outubro de 2013 11:57:48, Andrzej Krzemie=C5=84ski wrote:
<br>&gt; template &lt;typename T&gt;
<br>&gt; struct optional_optimized_disengaged_<wbr>state_traits&lt;T*&gt;
<br>&gt; {
<br>&gt; &nbsp; constexpr static bool is_optimized =3D true;
<br>&gt; &nbsp; constexpr static raw_storage_of_size&lt;T&gt; const&amp; va=
lue() {
<br>&gt; &nbsp; &nbsp; return cast( (T*)1 );
<br>&gt; &nbsp; }
<br>&gt; };
<br>
<br>You cannot assume that a pointer of value 1 is invalid. In fact, there'=
s only=20
<br>one pointer whose value is invalid and that's null (and such a pointer =
doesn't=20
<br>have to be stored as a bitwise zero).
<br></blockquote><div><br>Which is why this is being proposed as a possible=
 class that the user / vendor could specialize, rather than a specializatio=
n that should be defined for all pointers in the standard as a guarantee. I=
f my code will only run on such a system (or if I'm the compiler vendor and=
 I know that this compilation of this code is only running on such a system=
), then this could simplify the creation of such a compressed optional.<br>=
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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_2171_17672787.1380758588649--

.


Author: David Stone <deusexsophismata@gmail.com>
Date: Wed, 2 Oct 2013 18:26:12 -0700 (PDT)
Raw View
------=_Part_4474_4005985.1380763572528
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, October 2, 2013 1:07:38 PM UTC-6, Nevin ":-)" Liber wrote:
>
> On 2 October 2013 13:57, Andrzej Krzemie=C5=84ski <akrz...@gmail.com> wro=
te:
>
>> I can think of two ways to optimize the storage size for tr2::optional=
=20
>> for certain T's -- at the cost of potentially adding run-time overhead w=
hen=20
>> checking for the disengaged state:
>>
>
> Is this anything more than an implementation detail (and therefore not on=
=20
> topic for this forum)?=20
>
>
No more than std::allocator_traits.


I have yet to see *any* benchmarks of real world programs where adding such=
=20
> complexity would be a net benefit to anyone, let alone most users.
>
> If people really wish to go down this route, I can't stop them, other tha=
n=20
> to say that in all likelihood I will argue and vote strongly against such=
 a=20
> proposal.
>

I have a video game playing program that would need such an optimization=20
before I could consider using optional as a data member for some of my=20
classes. I make a large number of copies as I evaluate various game states=
=20
(the copying is so that I can restore to a previous state). Approximately=
=20
60-70% of my time is spent in new and delete due to contained std::vector=
=20
elements, despite my focus on the most compact data representation=20
possible. I can measure the performance of my program primarily by two=20
things: the depth of search and the size of my classes.

In one situation, I had a std::vector that had either one or two elements.=
=20
By replacing this with a std::array<element_type, 2> and using a special=20
sentinel value, I was able to emulate the std::vector approach. It was as=
=20
though I had a vector of capacity 2 that had a size of 1 if the value at 2=
=20
was that sentinel value. This allowed me to avoid the space overhead of=20
sizeof(std::size_t) * 2 by not having to directly store a size and a=20
capacity and removed an extra call to new.

A situation that I am facing right now that I am optimizing is a class that=
=20
can exist up to 48 times in a game state, so an overhead of one byte could=
=20
lead to 48 more bytes. One of the many patterns that many of my classes=20
face (including this one) is that I need to store a counter for how long a=
=20
condition has existed (and this counter has a known upper limit, for=20
instance, 10). My current implementation is to use a magic value of=20
std::numeric_limits<uint8_least_t>::max() to simulate an optional value,=20
but I feel it would improve the clarity of my code to be able to make the=
=20
counter itself just optional (as the counter doesn't conceptually exist at=
=20
all if the effect is not yet in play). I would not use std::optional for=20
this if that had an overhead of one byte per counter I applied this to.

My algorithm can search a specified number of turns ahead in the game. It=
=20
is primarily by reducing the size of my data structures that I was able to=
=20
reduce the run time at a depth of 4 (my current depth) from some unknown=20
amount of time (which I estimate at about 70 days) down to about 20=20
seconds. I don't know exactly how much of this can be attributed to=20
reduction in the size of data structures, but I did perform reductions=20
incrementally and saw significant performance improvements each time. My=20
hope is that the reduction in size I am working on right now will allow me=
=20
to do depth=3D5 in a reasonable time frame (less than a minute rather than=
=20
20-30 minutes).

--=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_4474_4005985.1380763572528
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, October 2, 2013 1:07:38 PM UTC-6, Nevin ":-)=
" Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On 2 October 2013 13:57, Andrzej Krzemie=C5=84ski <span dir=3D"ltr">&lt;<a=
 target=3D"_blank">akrz...@gmail.com</a>&gt;</span> wrote:<br><div><div cla=
ss=3D"gmail_quote">

<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"><div><div>I can think of tw=
o ways to optimize the storage size for=20
tr2::optional for certain T's -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br></div></div></=
div></blockquote><div><br></div><div>Is this anything more than an implemen=
tation detail (and therefore not on topic for this forum)?&nbsp;</div><div>

<br></div></div></div></div></blockquote><div><br>No more than std::allocat=
or_traits.<br></div><br><br><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 class=3D"gmail_quote"><div></div><div>I have yet t=
o see *any* benchmarks of real world programs where adding such complexity =
would be a net benefit to anyone, let alone most users.</div>

<div><br></div><div>If people really wish to go down this route, I can't st=
op them, other than to say that in all likelihood I will argue and vote str=
ongly against such a proposal.</div><div></div></div></div></div></blockquo=
te><div><br>I have a video game playing program that would need such an opt=
imization
 before I could consider using optional as a data member for some of my=20
classes. I make a large number of copies as I evaluate various game=20
states (the copying is so that I can restore to a previous state).=20
Approximately 60-70% of my time is spent in new and delete due to=20
contained std::vector elements, despite my focus on the most compact=20
data representation possible. I can measure the performance of my=20
program primarily by two things: the depth of search and the size of my=20
classes.<br><br>In one situation, I had a std::vector that had either=20
one or two elements. By replacing this with a=20
std::array&lt;element_type, 2&gt; and using a special sentinel value, I=20
was able to emulate the std::vector approach. It was as though I had a=20
vector of capacity 2 that had a size of 1 if the value at 2 was that=20
sentinel value. This allowed me to avoid the space overhead of=20
sizeof(std::size_t) * 2 by not having to directly store a size and a=20
capacity and removed an extra call to new.<br><br>A situation that I am=20
facing right now that I am optimizing is a class that can exist up to 48
 times in a game state, so an overhead of one byte could lead to 48 more
 bytes. One of the many patterns that many of my classes face (including
 this one) is that I need to store a counter for how long a condition=20
has existed (and this counter has a known upper limit, for instance,=20
10). My current implementation is to use a magic value of=20
std::numeric_limits&lt;uint8_least_t&gt;::max() to simulate an optional=20
value, but I feel it would improve the clarity of my code to be able to=20
make the counter itself just optional (as the counter doesn't=20
conceptually exist at all if the effect is not yet in play). I would not
 use std::optional for this if that had an overhead of one byte per=20
counter I applied this to.<br><br>My algorithm can search a specified=20
number of turns ahead in the game. It is primarily by reducing the size=20
of my data structures that I was able to reduce the run time at a depth=20
of 4 (my current depth) from some unknown amount of time (which I=20
estimate at about 70 days) down to about 20 seconds. I don't know exactly h=
ow much of this can be attributed to reduction in the size of data structur=
es, but I did perform reductions incrementally and saw significant performa=
nce improvements each time. My hope is that the
 reduction in size I am working on right now will allow me to do depth=3D5
 in a reasonable time frame (less than a minute rather than 20-30=20
minutes).<br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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_4474_4005985.1380763572528--

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Wed, 2 Oct 2013 19:33:38 -0700
Raw View
--047d7bd76d1ece2b7f04e7cd05b9
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

It seems like you should just define a type that has the semantics you want
for those requirements.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal
Malware Response Instructor - BleepingComputer.com


On Wed, Oct 2, 2013 at 6:26 PM, David Stone <deusexsophismata@gmail.com>wro=
te:

> On Wednesday, October 2, 2013 1:07:38 PM UTC-6, Nevin ":-)" Liber wrote:
>>
>> On 2 October 2013 13:57, Andrzej Krzemie=F1ski <akrz...@gmail.com> wrote=
:
>>
>>> I can think of two ways to optimize the storage size for tr2::optional
>>> for certain T's -- at the cost of potentially adding run-time overhead =
when
>>> checking for the disengaged state:
>>>
>>
>> Is this anything more than an implementation detail (and therefore not o=
n
>> topic for this forum)?
>>
>>
> No more than std::allocator_traits.
>
>
> I have yet to see *any* benchmarks of real world programs where adding
>> such complexity would be a net benefit to anyone, let alone most users.
>>
>> If people really wish to go down this route, I can't stop them, other
>> than to say that in all likelihood I will argue and vote strongly agains=
t
>> such a proposal.
>>
>
> I have a video game playing program that would need such an optimization
> before I could consider using optional as a data member for some of my
> classes. I make a large number of copies as I evaluate various game state=
s
> (the copying is so that I can restore to a previous state). Approximately
> 60-70% of my time is spent in new and delete due to contained std::vector
> elements, despite my focus on the most compact data representation
> possible. I can measure the performance of my program primarily by two
> things: the depth of search and the size of my classes.
>
> In one situation, I had a std::vector that had either one or two elements=
..
> By replacing this with a std::array<element_type, 2> and using a special
> sentinel value, I was able to emulate the std::vector approach. It was as
> though I had a vector of capacity 2 that had a size of 1 if the value at =
2
> was that sentinel value. This allowed me to avoid the space overhead of
> sizeof(std::size_t) * 2 by not having to directly store a size and a
> capacity and removed an extra call to new.
>
> A situation that I am facing right now that I am optimizing is a class
> that can exist up to 48 times in a game state, so an overhead of one byte
> could lead to 48 more bytes. One of the many patterns that many of my
> classes face (including this one) is that I need to store a counter for h=
ow
> long a condition has existed (and this counter has a known upper limit, f=
or
> instance, 10). My current implementation is to use a magic value of
> std::numeric_limits<uint8_least_t>::max() to simulate an optional value,
> but I feel it would improve the clarity of my code to be able to make the
> counter itself just optional (as the counter doesn't conceptually exist a=
t
> all if the effect is not yet in play). I would not use std::optional for
> this if that had an overhead of one byte per counter I applied this to.
>
> My algorithm can search a specified number of turns ahead in the game. It
> is primarily by reducing the size of my data structures that I was able t=
o
> reduce the run time at a depth of 4 (my current depth) from some unknown
> amount of time (which I estimate at about 70 days) down to about 20
> seconds. I don't know exactly how much of this can be attributed to
> reduction in the size of data structures, but I did perform reductions
> incrementally and saw significant performance improvements each time. My
> hope is that the reduction in size I am working on right now will allow m=
e
> to do depth=3D5 in a reasonable time frame (less than a minute rather tha=
n
> 20-30 minutes).
>
> --
>
> ---
> 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/.
>

--=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/.

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

<div dir=3D"ltr">It seems like you should just define a type that has the s=
emantics you want for those requirements.</div><div class=3D"gmail_extra"><=
br clear=3D"all"><div><div dir=3D"ltr"><div>Billy O&#39;Neal</div><div><a h=
ref=3D"https://bitbucket.org/BillyONeal/" target=3D"_blank">https://github.=
com/BillyONeal/</a></div>

<div><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D=
"_blank">http://stackoverflow.com/users/82320/billy-oneal</a></div><div>Mal=
ware Response Instructor - BleepingComputer.com</div></div></div>
<br><br><div class=3D"gmail_quote">On Wed, Oct 2, 2013 at 6:26 PM, David St=
one <span dir=3D"ltr">&lt;<a href=3D"mailto:deusexsophismata@gmail.com" tar=
get=3D"_blank">deusexsophismata@gmail.com</a>&gt;</span> wrote:<br><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex">

<div dir=3D"ltr">On Wednesday, October 2, 2013 1:07:38 PM UTC-6, Nevin &quo=
t;:-)&quot; Liber 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">

On 2 October 2013 13:57, Andrzej Krzemie=C5=84ski <span dir=3D"ltr">&lt;<a>=
akrz...@gmail.com</a>&gt;</span> wrote:<br><div><div class=3D"gmail_quote">

<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"><div><div>I can think of tw=
o ways to optimize the storage size for=20
tr2::optional for certain T&#39;s -- at the cost of potentially adding=20
run-time overhead when checking for the disengaged state:<br></div></div></=
div></blockquote><div><br></div><div>Is this anything more than an implemen=
tation detail (and therefore not on topic for this forum)?=C2=A0</div><div>



<br></div></div></div></div></blockquote><div><br>No more than std::allocat=
or_traits.<br></div><br><br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr">

<div><div class=3D"gmail_quote"><div></div><div>I have yet to see *any* ben=
chmarks of real world programs where adding such complexity would be a net =
benefit to anyone, let alone most users.</div>

<div><br></div><div>If people really wish to go down this route, I can&#39;=
t stop them, other than to say that in all likelihood I will argue and vote=
 strongly against such a proposal.</div><div></div></div></div></div></bloc=
kquote>

<div><br>I have a video game playing program that would need such an optimi=
zation
 before I could consider using optional as a data member for some of my=20
classes. I make a large number of copies as I evaluate various game=20
states (the copying is so that I can restore to a previous state).=20
Approximately 60-70% of my time is spent in new and delete due to=20
contained std::vector elements, despite my focus on the most compact=20
data representation possible. I can measure the performance of my=20
program primarily by two things: the depth of search and the size of my=20
classes.<br><br>In one situation, I had a std::vector that had either=20
one or two elements. By replacing this with a=20
std::array&lt;element_type, 2&gt; and using a special sentinel value, I=20
was able to emulate the std::vector approach. It was as though I had a=20
vector of capacity 2 that had a size of 1 if the value at 2 was that=20
sentinel value. This allowed me to avoid the space overhead of=20
sizeof(std::size_t) * 2 by not having to directly store a size and a=20
capacity and removed an extra call to new.<br><br>A situation that I am=20
facing right now that I am optimizing is a class that can exist up to 48
 times in a game state, so an overhead of one byte could lead to 48 more
 bytes. One of the many patterns that many of my classes face (including
 this one) is that I need to store a counter for how long a condition=20
has existed (and this counter has a known upper limit, for instance,=20
10). My current implementation is to use a magic value of=20
std::numeric_limits&lt;uint8_least_t&gt;::max() to simulate an optional=20
value, but I feel it would improve the clarity of my code to be able to=20
make the counter itself just optional (as the counter doesn&#39;t=20
conceptually exist at all if the effect is not yet in play). I would not
 use std::optional for this if that had an overhead of one byte per=20
counter I applied this to.<br><br>My algorithm can search a specified=20
number of turns ahead in the game. It is primarily by reducing the size=20
of my data structures that I was able to reduce the run time at a depth=20
of 4 (my current depth) from some unknown amount of time (which I=20
estimate at about 70 days) down to about 20 seconds. I don&#39;t know exact=
ly how much of this can be attributed to reduction in the size of data stru=
ctures, but I did perform reductions incrementally and saw significant perf=
ormance improvements each time. My hope is that the
 reduction in size I am working on right now will allow me to do depth=3D5
 in a reasonable time frame (less than a minute rather than 20-30=20
minutes).<span class=3D"HOEnZb"><font color=3D"#888888"><br></font></span><=
/div></div><span class=3D"HOEnZb"><font color=3D"#888888">

<p></p>

-- <br>
=C2=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%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 />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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 />

--047d7bd76d1ece2b7f04e7cd05b9--

.


Author: David Stone <deusexsophismata@gmail.com>
Date: Wed, 2 Oct 2013 20:25:08 -0700 (PDT)
Raw View
------=_Part_4_29634295.1380770708859
Content-Type: text/plain; charset=ISO-8859-1

And I could call that type optional<counter_type>.

--

---
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_4_29634295.1380770708859
Content-Type: text/html; charset=ISO-8859-1

<div dir="ltr">And I could call that type optional&lt;counter_type&gt;.<br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an 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 />

------=_Part_4_29634295.1380770708859--

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Thu, 3 Oct 2013 13:10:56 +0200
Raw View
2013/10/2 Andrzej Krzemie=F1ski <akrzemi1@gmail.com>:
> template <typename T>
> struct optional_optimized_disengaged_state_traits<T*>
> {
>   constexpr static bool is_optimized =3D true;
>   constexpr static raw_storage_of_size<T> const& value() {
>     return cast( (T*)1 );
>   }
> };

Note that this function could not be used in constant expressions,
because the (implied) use of reinterpret_cast is not valid in this
context.

- Daniel

--=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/.

.