220 18743 <4359ebfb-5e20-42c1-84a0-16ef6201db33@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: vlovich@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Compressing std::optional
Date: Wed, 24 Jun 2015 09:55:49 -0700 (PDT)
Lines: 449
Approved: news@gmane.org
Message-ID: <4359ebfb-5e20-42c1-84a0-16ef6201db33@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1089_1110554904.1435164949798"
X-Trace: ger.gmane.org 1435164956 23839 80.91.229.3 (24 Jun 2015 16:55:56 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 24 Jun 2015 16:55:56 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCFIZX46Q4HRBF6CVOWAKGQE5N7KUZA@isocpp.org Wed Jun 24 18:55:55 2015
Return-path: <std-proposals+bncBCFIZX46Q4HRBF6CVOWAKGQE5N7KUZA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qk0-f198.google.com ([209.85.220.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCFIZX46Q4HRBF6CVOWAKGQE5N7KUZA@isocpp.org>)
	id 1Z7nxp-0003tp-ES
	for gclcip-std-proposals@m.gmane.org; Wed, 24 Jun 2015 18:55:53 +0200
Original-Received: by qkca12 with SMTP id a12sf49203271qkc.1
        for <gclcip-std-proposals@m.gmane.org>; Wed, 24 Jun 2015 09:55:52 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:subject:mime-version:content-type
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=iLaOH5cIrclHB+MRXfVHHCuq7gRVp2MUyWgwgQBHJLc=;
        b=rcN0Oz2ioRoP037BoOzvavmNraF4UJ7qzF8DQrce9+RtAF2AfL+NqnHSZquqrLVkMJ
         UJZbooVQ7GeCS13gueG8dKCF4pVmb4ThIaoXNNvip2wpeYmnCl+N2LxNRqoyvOyj5TfP
         Aj/zNlTJSAWrnGgHpOpwXtLT1cfBuMO4cLtm+cNmJTWk8+ysyHpomm8m01C4CGb/+yIa
         EsNqBrC2zy+dv4h4l2p1KsIFgUy2JDA/ZIafoEaiKfZddxA0B4CUs72zz40BqbEVv52K
         gGDZIMqODdl/9wuhoJNbaeBHaQ+SK1sn/gOwrebMzU+USXtlp/IGyGHlNDvX9fZAJFB4
         CgjQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:subject:mime-version
         :content-type:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=iLaOH5cIrclHB+MRXfVHHCuq7gRVp2MUyWgwgQBHJLc=;
        b=K2GSr5TBdXzDnYT1V1VLxT1DRy/Gcfihe+Nek7+a1egFPBR/Su42fpP0RSveZad/B0
         ug/zuYvIFM73X1/SGCdbLAnNPr5bLJK3wkVr1euZIi8CMyZm1xuJPhF0SuvHGW3UE7xn
         EZd6ZVxUAqof9V0Arun4j/pc47R66OQwoDX2zGqUT7wMHyYdzARVjgO0wEqP1OIhfP1z
         /X5fT3r2/jJdplz33qhrFyUXELjsSQ0rLFN4JGAQcGzU2faPmXcdkeYe45HCFP8aHBM6
         RUvHuOJc7l6Ny0KwOBmHuCDOOCE4i7QBHSWKKYKoKgKpl2xfVbzt8cvGAQQFlQQz6yv/
         ZR6w==
X-Gm-Message-State: ALoCoQneLJYGnZXZgFq5Wvf+OjM7Ho7RmEMq5e7TH89HBjMwOW1OPlgQXu5T7rRz/MZR7eqBimIg
X-Received: by 10.140.151.65 with SMTP id 62mr54022880qhx.1.1435164952452;
        Wed, 24 Jun 2015 09:55:52 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.165.208 with SMTP id o199ls693468ioe.13.gmail; Wed, 24 Jun
 2015 09:55:51 -0700 (PDT)
X-Received: by 10.50.142.39 with SMTP id rt7mr107453igb.17.1435164951755;
        Wed, 24 Jun 2015 09:55:51 -0700 (PDT)
X-Original-Sender: vlovich@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: 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: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:18743
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/18743>

------=_Part_1089_1110554904.1435164949798
Content-Type: multipart/alternative; 
	boundary="----=_Part_1090_1315895451.1435164949798"

------=_Part_1090_1315895451.1435164949798
Content-Type: text/plain; charset=UTF-8

Hi,

I'd like to bring up this topic again.  I know Andrzej brought it up a 
couple of years ago for tr2 but I think I have a different take.
First, I'd like to motivate the discussion with the limitations of the 
current approach.

   - For small types optional can double the size of storage
   - Overhead can add up when stored in arrays (& most of it due to padding 
   if the sizeof(T) > 1).
   - Cannot be used as a drop-in in a memory-mapped structure.  In these 
   scenarios it's not uncommon to have a sentinel value.
   - Cannot be used in as a drop-in in existing code that uses a sentinel 
   (i.e type-safety)
   - Lots of overhead when a struct contains lots of optionals.  For 
   example, protobuf uses bit-packing for this.

The main limitation, at least as I see it, of the Andrzej's traits 
implementation is that it cannot be customized per-instance of optional.  
This is probably fine for user-defined types but makes this optimization 
not possible for built-in types.  It's not uncommon to have only certain 
instances of built-in types have invalid bit-patterns (e.g. NaN for double, 
maximum value for size_t as reported by std::string).


To that end, my proposal to accomplish something like this would require 
adding a secondary template parameter that defines the storage of the 
initialization state.  Here is a straw-man skeleton example of what the 
std::optional class interface might look like. constexpr omitted for 
simplicity but I don't see anything preventing it & optional_storage is the 
hypothetical :


template <typename T, typename S = default_optional_initialization_storage>
class optional {
public:
    optional(std::nullopt_t)
    {
        std::get<0>(_data).set_initialized(reinterpret_cast<T*>(&std::get<1
>(_data)), false);
    }

    optional(const T&)
    {
        std::get<0>(_data).set_initialized(reinterpret_cast<T*>(&std::get<1
>(_data)), true);
    }
    ...
    bool is_initialized() const
    {
        return std::get<0>(_data).is_initialized();
    }
    ...
private:
    std::tuple<S, aligned_storage_t<sizeof(T)>> _data;
};

default_optional_initialization_storage would comply with the interface for 
optional_initialization_storage & look something like:


struct default_optional_initialization_storage {
    template <typename T>
    bool is_initialized(T*) const
    {
        return _initialized;
    }

    template <typename T>
    void set_initialized(T*, bool initialized)
    {
        _initialized = initialized;
    }

    bool _initialized = false;
};


An example for hiding the state as via NaN for double:

struct nan_optional_storage {
    bool is_initialized(double* value) const
    {
        return !std::isnan(*value)
    }

    void set_initialized(double* value, bool initialized)
    {
        if (!initialized) {
            *value = std::numeric_limits<double>::quite_NaN();
        }
    }
};


Some of my thoughts on this sample code:

   - It is by no means an exaustive implementation and I'm sure there's 
   lots of nitpicking to be done over details/naming/etc.  I just want to get 
   a sense of does something like this even make sense.
   - This is purely a mechanism through which optional can be optimized 
   with domain-specific knowledge.  There is no optimization suggested for 
   built-in types (e.g. not even pointer types would optimize the nullptr case 
   by default).
   - The sentinel-value use-case would probably be important enough that a 
   simple API for expressing such a sentinel value would be valuable 
   (something like optional<double, sentinel<double, nan("")>>)
   - This is purely a customization point to apply domain-specific 
   knowledge to optimize optional.  There is no optimization available by 
   default.
   - The careful reader will note that the bit-packing case has not been 
   addressed.  I am not quite certain how to actually achieve this since the 
   storage lives external to the optional<> itself.  Passing through some kind 
   of ctx in all optional APIs?
   - It has been suggested by some that this no longer represents the CS 
   concept of an optional monad and should be a distinct type.  I'm not sure I 
   really see why (purity of mapping C++ to theoretical CS aside).

Thanks for reading,
Vitali

-- 

--- 
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_1090_1315895451.1435164949798
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>I'd like to bring up this topic again.&nbsp; I =
know Andrzej brought it up a couple of years ago for tr2 but I think I have=
 a different take.<br>First, I'd like to motivate the discussion with the l=
imitations of the current approach.<br><ul><li>For small types optional can=
 double the size of storage</li><li>Overhead can add up when stored in arra=
ys (&amp; most of it due to padding if the sizeof(T) &gt; 1).</li><li>Canno=
t be used as a drop-in in a memory-mapped structure.&nbsp; In these scenari=
os it's not uncommon to have a sentinel value.</li><li>Cannot be used in as=
 a drop-in in existing code that uses a sentinel (i.e type-safety)</li><li>=
Lots of overhead when a struct contains lots of optionals.&nbsp; For exampl=
e, protobuf uses bit-packing for this.</li></ul><p>The main limitation, at =
least as I see it, of the Andrzej's traits implementation is that it cannot=
 be customized per-instance of optional.&nbsp; This is probably fine for us=
er-defined types but makes this optimization not possible for built-in type=
s.&nbsp; It's not uncommon to have only certain instances of built-in types=
 have invalid bit-patterns (e.g. NaN for double, maximum value for size_t a=
s reported by std::string).<br></p><p><br></p><p>To that end, my proposal t=
o accomplish something like this would require adding a secondary template =
parameter that defines the storage of the initialization state.&nbsp; Here =
is a straw-man skeleton example of what the std::optional class interface m=
ight look like. constexpr omitted for simplicity but I don't see anything p=
reventing it &amp; optional_storage is the hypothetical :</p><p><br></p><p>=
</p><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250=
); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px=
; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><span style=3D"color: #008;" class=3D"styled-by-prettify">template=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> S </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> default_optional_initialization_storage</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> optional </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">public</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
&nbsp; &nbsp; optional</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">nullopt_t</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; &nbsp; </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp=
; &nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">_data</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">).</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">set_initialized</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span class=3D"kw1"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span></spa=
n><span class=3D"sy1"><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">T</span><span class=3D"sy2"><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">*</span></span><span class=3D"sy1"><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&gt;(</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">&amp;std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #066;" class=3D"styled=
-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
_data</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: #008;" class=3D"styled-by-prettify">false</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; optional</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&amp;)</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">get</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">_data</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">).</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">set_initialized</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><code class=3D"prettyprint"><span class=3D"kw1"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">reinterpret_cast</span></span><span c=
lass=3D"sy1"><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;=
</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</=
span><span class=3D"sy2"><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">*</span></span><span class=3D"sy1"><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;(&amp;</span></span></code>std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">_data</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">)),</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">true</=
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: #660;" class=3D"styled-by-prettify">}</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;&nbsp;&nbsp=
; ...<br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> is_initialized</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;=
 &nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
&nbsp; &nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">_data</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">).</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">is_initialized</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; &nbsp; </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>&nbsp; &nbsp; </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">private</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; &nbsp; std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
S</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> aligned_storage_t=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><sp=
an 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">)&gt;&gt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> _data</span><span style=3D"color: #66=
0;" 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"st=
yled-by-prettify">};</span></div></code></div><br><p></p><p>default_optiona=
l_initialization_storage would comply with the interface for optional_initi=
alization_storage &amp; look something like:<code class=3D"prettyprint"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></code></=
p><p><br><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"=
styled-by-prettify"></span></code></p><p><code class=3D"prettyprint"><span =
style=3D"color: #000;" class=3D"styled-by-prettify"></span></code></p><div =
class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border=
-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wr=
ap: break-word;"><code class=3D"prettyprint"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> default_optional_initialization_storage</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;&nbsp;&nbsp; template &lt;typename T&gt;<br>&n=
bsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> is_=
initialized</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><code cl=
ass=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><code class=3D"prettyprint"><span style=3D"color: #660;" class=3D"styled=
-by-prettify"><code class=3D"prettyprint"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">T*</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify"></span></code></span></code></span></code>)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; return _=
initialized;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>&nbsp; &nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br><br>&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;<br>&nbsp; &nbsp; </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> set_initialized</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><code class=3D"pretty=
print"><code class=3D"prettyprint"><span style=3D"color: #660;" class=3D"st=
yled-by-prettify"></span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><code class=3D"prettyprint"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify"></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><code class=3D"prettyprint"><span style=3D"color: #000;=
" class=3D"styled-by-prettify">T*, </span></code></span></code></span></cod=
e></span></code></code></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><span =
style=3D"color: #660;" class=3D"styled-by-prettify"><code class=3D"prettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify"><code class=
=3D"prettyprint"><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"></span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"></span></code></code> initialized</span><=
/code></span></code></span></code></span></code></code></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">)<br>&nbsp;&nbsp;&nbsp; {<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _initialized =3D </span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"prettypri=
nt"><code class=3D"prettyprint"><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><code class=3D"prettyprint"><code class=3D"prettyprint"><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><code class=3D"pretty=
print"><span style=3D"color: #000;" class=3D"styled-by-prettify"><code clas=
s=3D"prettyprint"><span style=3D"color: #660;" class=3D"styled-by-prettify"=
><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">initialized</span></code></span></code></span></code></span></c=
ode></code></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
></span></code></code>;<br>&nbsp;&nbsp;&nbsp; }</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br><br>&nbsp;&nbsp;&nbsp; </span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"pretty=
print"><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"></span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"></span></code></code> _initialized =3D false;</span><code class=3D"pretty=
print"><span style=3D"color: #000;" class=3D"styled-by-prettify"><code clas=
s=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span></code></span></code><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span></div></code></code></div><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify"></span><p></p><p><br><code class=3D"prettyprint=
"><span style=3D"color: #660;" class=3D"styled-by-prettify"></span></code><=
/p>An example for hiding the state as via NaN for double:<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> nan_optional_storage </sp=
an><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"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> is_initialized</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><code c=
lass=3D"prettyprint"><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy"><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"=
color: #660;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"pretty=
print"><span style=3D"color: #660;" class=3D"styled-by-prettify"><code clas=
s=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>double* value</span></code></span></code></span></code></span></code></cod=
e></span></code></code>) </span><code class=3D"prettyprint"><code class=3D"=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">cons=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp=
;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return !std::=
isnan(*value)<br>&nbsp;&nbsp;&nbsp; }<br></span></code></code><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp;&nbsp;&nbsp; void =
set_initialized(double* value, bool initialized)<br>&nbsp;&nbsp;&nbsp; {<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!initialized) {<br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *value =3D std::=
numeric_limits&lt;double&gt;::quite_NaN();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">;<br><br></span></div></code></div><code class=3D"p=
rettyprint"><span style=3D"color: #660;" class=3D"styled-by-prettify"><br><=
/span></code>Some of my thoughts on this sample code:<br><ul><li>It is by n=
o means an exaustive implementation and I'm sure there's lots of nitpicking=
 to be done over details/naming/etc.&nbsp; I just want to get a sense of do=
es something like this even make sense.<br></li><li>This is purely a mechan=
ism through which optional can be optimized with domain-specific knowledge.=
&nbsp; There is no optimization suggested for built-in types (e.g. not even=
 pointer types would optimize the nullptr case by default).</li><li>The sen=
tinel-value use-case would probably be important enough that a simple API f=
or expressing such a sentinel value would be valuable (something like optio=
nal&lt;double, sentinel&lt;double, nan("")&gt;&gt;)</li><li>This is purely =
a customization point to apply domain-specific knowledge to optimize option=
al.&nbsp; There is no optimization available by default.</li><li>The carefu=
l reader will note that the bit-packing case has not been addressed.&nbsp; =
I am not quite certain how to actually achieve this since the storage lives=
 external to the optional&lt;&gt; itself.&nbsp; Passing through some kind o=
f ctx in all optional APIs?</li><li>It has been suggested by some that this=
 no longer represents the CS concept of an optional monad and should be a d=
istinct type.&nbsp; I'm not sure I really see why (purity of mapping C++ to=
 theoretical CS aside).</li></ul>Thanks for reading,<br>Vitali<br></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_1090_1315895451.1435164949798--
------=_Part_1089_1110554904.1435164949798--

.
