220 6896 <CAPBZbvyrf_VCwRG-ywbLWyQyYFoppCL2Z5Bz=FFucVqe6GkaKw@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: "Billy O'Neal" <billy.oneal@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Compressing Optional
Date: Wed, 2 Oct 2013 12:08:20 -0700
Lines: 409
Approved: news@gmane.org
Message-ID: <CAPBZbvyrf_VCwRG-ywbLWyQyYFoppCL2Z5Bz=FFucVqe6GkaKw@mail.gmail.com>
References: <9a40a660-b48b-49b7-9d39-85810a55ebcf@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=90e6ba614a764b786c04e7c6cdf0
X-Trace: ger.gmane.org 1380740944 30618 80.91.229.3 (2 Oct 2013 19:09:04 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 2 Oct 2013 19:09:04 +0000 (UTC)
To: std-proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDKLBLVE6ADBBTW6WGJAKGQEATE7CYQ@isocpp.org Wed Oct 02 21:09:07 2013
Return-path: <std-proposals+bncBDKLBLVE6ADBBTW6WGJAKGQEATE7CYQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ie0-f200.google.com ([209.85.223.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDKLBLVE6ADBBTW6WGJAKGQEATE7CYQ@isocpp.org>)
	id 1VRRnF-0007Fi-8r
	for gclcip-std-proposals@m.gmane.org; Wed, 02 Oct 2013 21:09:05 +0200
Original-Received: by mail-ie0-f200.google.com with SMTP id tp5sf4305875ieb.11
        for <gclcip-std-proposals@m.gmane.org>; Wed, 02 Oct 2013 12:09:04 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=QfeqSx4owK5/GsdzfJlpdP7GR37MwgSBdH5KI6utvjg=;
        b=RLVfXUnWGSyThwZbL7cnTNVN5tbYeTLRUQeDoMJD/oGL4UiBEPHgaCkBIwm4FUZwRo
         Rjy0tZZWBBbjubHxIvqpavbJpXdPQJEQfYSXMZ8vpq+ooX1fwf/WIDrL6aIM4PCSx/tb
         zcYlElNkROH3gkemPfDyt/ZmY0AdZvokk+iP4V7UkV503aGfEQcrzDxS+6WKmX+tphFS
         gZObni0hXilZV3c2uMswzt/DWUTWpsCXG+cklotvev7bO4LiXsrhN7qpytaUfq5c0H3v
         Pc7vghbEVMcNBCZTkS3yzW7rdwly7o832T615rI3WdjkCnRTWMUqQvuwvrzv7E4joolL
         EzDg==
X-Received: by 10.42.118.194 with SMTP id y2mr1604772icq.19.1380740944277;
        Wed, 02 Oct 2013 12:09:04 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.128.169 with SMTP id np9ls1149835igb.27.gmail; Wed, 02 Oct
 2013 12:09:01 -0700 (PDT)
X-Received: by 10.60.134.230 with SMTP id pn6mr2968292oeb.52.1380740941318;
        Wed, 02 Oct 2013 12:09:01 -0700 (PDT)
Original-Received: from mail-ie0-x22b.google.com (mail-ie0-x22b.google.com [2607:f8b0:4001:c03::22b])
        by mx.google.com with ESMTPS id sp4si3247857oeb.46.1969.12.31.16.00.00
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Wed, 02 Oct 2013 12:09:01 -0700 (PDT)
Received-SPF: pass (google.com: domain of billy.oneal@gmail.com designates 2607:f8b0:4001:c03::22b as permitted sender) client-ip=2607:f8b0:4001:c03::22b;
Original-Received: by mail-ie0-f171.google.com with SMTP id at1so2984168iec.30
        for <std-proposals@isocpp.org>; Wed, 02 Oct 2013 12:09:00 -0700 (PDT)
X-Received: by 10.42.62.196 with SMTP id z4mr2276616ich.49.1380740940657; Wed,
 02 Oct 2013 12:09:00 -0700 (PDT)
Original-Received: by 10.43.166.67 with HTTP; Wed, 2 Oct 2013 12:08:20 -0700 (PDT)
In-Reply-To: <9a40a660-b48b-49b7-9d39-85810a55ebcf@isocpp.org>
X-Original-Sender: billy.oneal@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of billy.oneal@gmail.com designates 2607:f8b0:4001:c03::22b as
 permitted sender) smtp.mail=billy.oneal@gmail.com;       dkim=pass
 header.i=@gmail.com;       dmarc=pass (p=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:6896
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/6896>

--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--

.
