220 13001 <CANCwVhcHZBcsNfG7AMF4paok9FhgD8hv+R_gQMLin8SO++sxWw@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: TONGARI J <tongari95@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Compile-time static `std::integral_counter`
Date: Fri, 19 Sep 2014 22:07:16 +0800
Lines: 450
Approved: news@gmane.org
Message-ID: <CANCwVhcHZBcsNfG7AMF4paok9FhgD8hv+R_gQMLin8SO++sxWw@mail.gmail.com>
References: <9a0bde7b-2f0a-4a5b-92a4-88d5e8df7ea9@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=20cf30223fc75cb59f05036b9e02
X-Trace: ger.gmane.org 1411135653 6939 80.91.229.3 (19 Sep 2014 14:07:33 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Fri, 19 Sep 2014 14:07:33 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCC3NA775MLBBHHR6CQAKGQENGDM3SA@isocpp.org Fri Sep 19 16:07:26 2014
Return-path: <std-proposals+bncBCC3NA775MLBBHHR6CQAKGQENGDM3SA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ig0-f200.google.com ([209.85.213.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCC3NA775MLBBHHR6CQAKGQENGDM3SA@isocpp.org>)
	id 1XUyqL-0004d6-Jn
	for gclcip-std-proposals@m.gmane.org; Fri, 19 Sep 2014 16:07:26 +0200
Original-Received: by mail-ig0-f200.google.com with SMTP id hn15sf14250109igb.7
        for <gclcip-std-proposals@m.gmane.org>; Fri, 19 Sep 2014 07:07:24 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:in-reply-to:references:date
         :message-id:subject:from: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=q7QzHCyH06L9+LznRBCjvYkwnXA6yARc4Ujpmtwg9Ok=;
        b=D5J28eT3UB5JXN72haUIqcv+siKlTxSMezPMMdCjlDl5kBTShWLBdGuc2ojXSBeFoD
         N3TmDR6GhPBVSMCcfv13UfywBm7JqfysCAGDxvpgnxlpaeMrlaKn81+qi6Ip2ouKyuy+
         hIvAgfXLy6NUlO+TmG11PTiFHnM7di9SpMqoddTE5Pu6dmeTBRnWSWGqsJM5ADVNvoE6
         lxJHpcY7W/Wb6jTVBzhHgrEXZPm9ivYp3upELEtBTBzS11wMrrxATd0WqzbdJobc28rd
         YvUkWL1Xx6t8NWwkI/tLrBo+Zqz0w0BAPWbupxhBjuNbz2UTeuW3/sscHszAs+33dP2V
         5ZfQ==
X-Gm-Message-State: ALoCoQkCMhFhxG2K0eBvIRQ79Dgc/RfL2r7nUNmB05/MuEvnwxJx08RTp0RSgz/KrY4ypz9Wr6r1
X-Received: by 10.50.47.10 with SMTP id z10mr2790133igm.0.1411135644760;
        Fri, 19 Sep 2014 07:07:24 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.43.135 with SMTP id w7ls479951igl.28.gmail; Fri, 19 Sep
 2014 07:07:23 -0700 (PDT)
X-Received: by 10.42.207.68 with SMTP id fx4mr1260336icb.67.1411135642842;
        Fri, 19 Sep 2014 07:07:22 -0700 (PDT)
Original-Received: from mail-ie0-x235.google.com (mail-ie0-x235.google.com [2607:f8b0:4001:c03::235])
        by mx.google.com with ESMTPS id qo6si1752026igb.23.2014.09.19.07.07.22
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Fri, 19 Sep 2014 07:07:22 -0700 (PDT)
Received-SPF: pass (google.com: domain of tongari95@gmail.com designates 2607:f8b0:4001:c03::235 as permitted sender) client-ip=2607:f8b0:4001:c03::235;
Original-Received: by mail-ie0-f181.google.com with SMTP id tr6so3491513ieb.12
        for <std-proposals@isocpp.org>; Fri, 19 Sep 2014 07:07:22 -0700 (PDT)
X-Received: by 10.42.86.145 with SMTP id u17mr1472837icl.20.1411135636807;
 Fri, 19 Sep 2014 07:07:16 -0700 (PDT)
Original-Received: by 10.42.99.84 with HTTP; Fri, 19 Sep 2014 07:07:16 -0700 (PDT)
In-Reply-To: <9a0bde7b-2f0a-4a5b-92a4-88d5e8df7ea9@isocpp.org>
X-Original-Sender: tongari95@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of tongari95@gmail.com designates 2607:f8b0:4001:c03::235 as permitted
 sender) smtp.mail=tongari95@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: <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:13001
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/13001>

--20cf30223fc75cb59f05036b9e02
Content-Type: text/plain; charset=UTF-8

2014-09-19 21:42 GMT+08:00 Vittorio Romeo <vittorio.romeo.vee@gmail.com>:

> *Introduction*
> There have been many occasions in my games/libraries where I need to
> assign a *`0..n` *compile-time integer to a series of types. Here are two
> examples:
>
>    - In one of my component-based entity management systems, I assign an
>    *`std::bitset`* to every entity, where every bit corresponds to a
>    specific component type.
>    - One of my polymorphic memory management/recycling classes stores
>    several "chunks" of allocated memory for specific types that are part of
>    the same hierarchy.
>    To quickly retrieve the chunks, they're stored in a contiguous array.
>    Every index of the array corresponds to a chunk of a specific type.
>
> The problem here is assigning an unique integer, starting from zero, to a
> specific type, and maintaining it throughout the whole program. This
> requires keeping track of the last used integer.
>
>
>
> *Current solution/workaround*
> Sacrificing performance, it is currently possible to achieve what I
> described above. Not at compile-time, but at run-time instead.
>
> // Statically store the last used global unique id.
> inline int getLastId() noexcept
> {
>    static int lastId{0};
>    return lastId++;
> }
>
> // Statically store an unique id for a specific type `T`.
> template<typename T> int getIdForType() noexcept
> {
>     static int id{getLastId()};
>     return id;
> }
>
> struct TypeA { };
> struct TypeB { };
> struct TypeC { };
>
> int main()
> {
>     // Whenever `getIdForType<T>()` gets instantiated,
>     // an unique id is "bound" to `T` for the rest of the program.
>
>     std::cout << getIdForType<TypeA>() << std::endl; // Prints '0'
>     std::cout << getIdForType<TypeB>() << std::endl; // Prints '1'
>     std::cout << getIdForType<TypeC>() << std::endl; // Prints '2'
>
>     return 0;
> }
>
> The workaround allows me to implement the aforementioned examples.
> However, it requires *`static`* storage for something that could be
> determined at compile-time.
> It also requires overhead to access this storage every time we need to get
> a type's unique id.
>
>
>
> *Possible proposal*
> Implement a stateful compile-time *`std::integral_counter` *class that
> somehow *(compiler magic?) *remembers its value.
>
> // We need to "store" a counter during compile-time.
> // A new keyword/contextual keyword combination is probably required for
> this.
>
> // We basically "allocate" memory for this counter during compilation and
> // use the counter during compilation. The counter should not exist anymore
> // at run-time (or be accessible at run-time).
>
> static template std::integral_counter<int, 0> lastIdCounter;
> // ____________ _____________________ ___  _  _____________
> // |            |                     |    |  L name
> // L contextual keyword combination   |    |
> //              |                     |    L counter starting value
> //              L type                L counter value type
>
> // Everything is done at compile-time. Constexpr should work, but also
> using
> // `std::integral_constant` with a template struct.
> template<typename T> constexpr int getIdForType() noexcept
> {
>     constexpr int id{lastIdCounter::value}; // Get the compile-time
> counter's current value
>     lastIdCounter::increment(); // Increment the compile-time counter -
> it will remember its last value
>     return id;
> }
>
> int main()
> {
>     // Whenever `getIdForType<T>()` gets called with a certain `T`, a
> value from
>     // the compile-time counter is "bound" to that `T` for the rest of
> the program.
>     // Since it is `constexpr` and evaluated at compile-time, there's no
> need to store
>     // the id anywhere in memory - calling the `getIdForType<T>()`
> function can
>     // basically be thought of as replacing `getIdForType<T>()` with a
> constant
>     // at compile time.
>
>     std::cout << getIdForType<TypeA>() << std::endl; // Prints '0'
>     std::cout << getIdForType<TypeB>() << std::endl; // Prints '1'
>     std::cout << getIdForType<TypeC>() << std::endl; // Prints '2'
>
>     return 0;
> }
>
>
>
> Thoughts?
> What motivated me to write this post is the fact that we have all
> necessary information at compile-time to assign an unique constant id to a
> specific type - but there (apparently) is no way of doing so.
>

Q: What happens if used in different TUs?

    // in file a.cpp
    std::cout << getIdForType<TypeA>() << std::endl; // Prints '0'
    std::cout << getIdForType<TypeB>() << std::endl; // Prints '1'
    std::cout << getIdForType<TypeC>() << std::endl; // Prints '2'

    // in file b.cpp
    std::cout << getIdForType<TypeC>() << std::endl; // Prints '0'
    std::cout << getIdForType<TypeB>() << std::endl; // Prints '1'
    std::cout << getIdForType<TypeA>() << std::endl; // Prints '2'

Is that the expected result?

-- 

--- 
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/.

--20cf30223fc75cb59f05036b9e02
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2014=
-09-19 21:42 GMT+08:00 Vittorio Romeo <span dir=3D"ltr">&lt;<a href=3D"mail=
to:vittorio.romeo.vee@gmail.com" target=3D"_blank">vittorio.romeo.vee@gmail=
..com</a>&gt;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);b=
order-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><font size=3D"4">=
<b>Introduction</b></font><div><font>There have been many occasions in my g=
ames/libraries where I need to assign a </font><b style=3D"font-size:small"=
>`0..n` </b><font>compile-time integer to a series of types. Here are two e=
xamples:</font><br><ul style=3D"font-size:small"><li><span style=3D"line-he=
ight:normal">In one of my component-based entity management systems, I assi=
gn an <b>`std::bitset`</b>=C2=A0to every entity, where every bit correspond=
s to a specific component type.</span></li><li><span style=3D"line-height:n=
ormal">One of my polymorphic memory management/recycling classes stores sev=
eral &quot;chunks&quot; of allocated memory for specific types that are par=
t of the same hierarchy. <br>To quickly retrieve the chunks, they&#39;re st=
ored in a contiguous array. Every index of the array corresponds to a chunk=
 of a specific type.</span></li></ul><div style=3D"font-size:small">The pro=
blem here is assigning an unique integer, starting from zero, to a specific=
 type, and maintaining it throughout the whole program. This requires keepi=
ng track of the last used integer.</div><div style=3D"font-size:small"><br>=
</div><div style=3D"font-size:small"><br></div><div style=3D"font-size:smal=
l"><br></div><div style=3D"font-size:small"><b style=3D"font-size:large">Cu=
rrent solution/workaround</b><br></div><div style=3D"font-size:small">Sacri=
ficing performance, it is currently possible to achieve what I described ab=
ove. Not at compile-time, but at run-time instead.</div><div style=3D"font-=
size:small"><br></div><div style=3D"font-size:small"><div style=3D"border:1=
px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250=
,250)"><code><div><span style=3D"color:rgb(136,0,0)">// Statically store th=
e last used global unique id.</span><span style=3D"color:rgb(0,0,0)"><br></=
span><span style=3D"color:rgb(0,0,136)">inline</span><span style=3D"color:r=
gb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">int</span><span style=
=3D"color:rgb(0,0,0)"> getLastId</span><span style=3D"color:rgb(102,102,0)"=
>()</span><span style=3D"color:rgb(0,0,0)"> noexcept<br></span><span style=
=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0</span><span style=3D"color:rgb(0,0,136)">static</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">int</span=
><span style=3D"color:rgb(0,0,0)"> lastId</span><span style=3D"color:rgb(10=
2,102,0)">{</span><span style=3D"color:rgb(0,102,102)">0</span><span style=
=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0</span><span style=3D"color:rgb(0,0,136)">return</span><span styl=
e=3D"color:rgb(0,0,0)"> lastId</span><span style=3D"color:rgb(102,102,0)">+=
+;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:r=
gb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"><br><br></span><spa=
n style=3D"color:rgb(136,0,0)">// Statically store an unique id for a speci=
fic type `T`.</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)"=
>&lt;</span><span style=3D"color:rgb(0,0,136)">typename</span><span style=
=3D"color:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,1=
36)">int</span><span style=3D"color:rgb(0,0,0)"> getIdForType</span><span s=
tyle=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> no=
except<br></span><span style=3D"color:rgb(102,102,0)">{</span><span style=
=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0=
,136)">static</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D=
"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> id</span><=
span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)=
">getLastId</span><span style=3D"color:rgb(102,102,0)">()};</span><span sty=
le=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0=
,0,136)">return</span><span style=3D"color:rgb(0,0,0)"> id</span><span styl=
e=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></s=
pan><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0=
,0,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">struct</span><span=
 style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Ty=
peA</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br></s=
pan><span style=3D"color:rgb(0,0,136)">struct</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">TypeB</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><font color=3D"#666600"><span style=3D"col=
or:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span s=
tyle=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"><br=
></span></font><span style=3D"color:rgb(0,0,136)">struct</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">TypeC</s=
pan><span style=3D"color:rgb(0,0,0)"> </span><font color=3D"#666600"><span =
style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb=
(0,0,0)"><br></span></font><font color=3D"#666600"><span style=3D"color:rgb=
(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)">int</span><span styl=
e=3D"color:rgb(0,0,0)"> main</span><span style=3D"color:rgb(102,102,0)">()<=
/span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(=
102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color:rgb(136,0,0)">// Whenever `getIdForType&lt;T&gt;()`=
 gets instantiated, </span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:rgb(136,0,0)">// an unique id is &quot;boun=
d&quot; to `T` for the rest of the program.</span><span style=3D"color:rgb(=
0,0,0)"><br><br>=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0)=
">::</span><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"colo=
r:rgb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> getIdFor=
Type</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"c=
olor:rgb(102,0,102)">TypeA</span><span style=3D"color:rgb(102,102,0)">&gt;(=
)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> std</span><span=
 style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">e=
ndl</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color=
:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">// Prints &#39;0&#3=
9;</span><span style=3D"color:rgb(0,0,0)"><br></span></font><span style=3D"=
color:rgb(0,0,0)">=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,=
0)">::</span><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"co=
lor:rgb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> getIdF=
orType</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D=
"color:rgb(102,0,102)">TypeB</span><span style=3D"color:rgb(102,102,0)">&gt=
;()</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> std</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)"=
>endl</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">// Prints &#39;1&=
#39;</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 std</span><sp=
an style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)"=
>cout </span><span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span styl=
e=3D"color:rgb(0,0,0)"> getIdForType</span><span style=3D"color:rgb(102,102=
,0)">&lt;</span><span style=3D"color:rgb(102,0,102)">TypeC</span><span styl=
e=3D"color:rgb(102,102,0)">&gt;()</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"co=
lor:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><s=
pan style=3D"color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(102,102,=
0)">;</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(136,0,0)">// Prints &#39;2&#39;</span><span style=3D"color:rgb(0,0,0)"><=
br></span><font color=3D"#666600"><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">return</span><span sty=
le=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)">0</spa=
n><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0=
,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span></font></div><=
/code></div><br>The workaround allows me to implement the aforementioned ex=
amples. However, it requires <b>`static`</b> storage for something that cou=
ld be determined at compile-time.=C2=A0</div><div style=3D"font-size:small"=
>It also requires overhead to access this storage every time we need to get=
 a type&#39;s unique id.</div><div style=3D"font-size:small"><br></div><div=
 style=3D"font-size:small"><br></div><div style=3D"font-size:small"><br></d=
iv><div><font size=3D"4"><b>Possible proposal</b></font></div><div>Implemen=
t a stateful compile-time=C2=A0<b>`std::integral_counter` </b>class that so=
mehow <i>(compiler magic?) </i>remembers its value.</div><div><br></div><di=
v><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;back=
ground-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(136,0,0)=
">// We need to &quot;store&quot; a counter during compile-time.</span><spa=
n style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">=
// A new keyword/contextual keyword combination is probably required for th=
is.</span><span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"co=
lor:rgb(136,0,0)">// We basically &quot;allocate&quot; memory for this coun=
ter during compilation and</span><span style=3D"color:rgb(0,0,0)"><br></spa=
n><span style=3D"color:rgb(136,0,0)">// use the counter during compilation.=
 The counter should not exist anymore</span><span style=3D"color:rgb(0,0,0)=
"><br></span><span style=3D"color:rgb(136,0,0)">// at run-time (or be acces=
sible at run-time).</span><span style=3D"color:rgb(0,0,0)"><br><br></span><=
span style=3D"color:rgb(0,0,136)">static</span><span style=3D"color:rgb(0,0=
,0)"> </span><span style=3D"color:rgb(0,0,136)">template</span><span style=
=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,0)">integral_counter</span><span style=3D"=
color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)">int</sp=
an><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,=
0,0)"> </span><span style=3D"color:rgb(0,102,102)">0</span><span style=3D"c=
olor:rgb(102,102,0)">&gt;</span><span style=3D"color:rgb(0,0,0)"> lastIdCou=
nter</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"colo=
r:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">// ____________=
 _____________________ ___ =C2=A0_ =C2=A0_____________</span><span style=3D=
"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">// | =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A0| =C2=A0L name</span><spa=
n style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">=
// L contextual keyword combination =C2=A0 | =C2=A0 =C2=A0|</span><span sty=
le=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(136,0,0)">// =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A0L counter star=
ting value</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D=
"color:rgb(136,0,0)">// =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0L t=
ype =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0L counter value =
type</span><span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"c=
olor:rgb(136,0,0)">// Everything is done at compile-time. Constexpr should =
work, but also using</span><span style=3D"color:rgb(0,0,0)"><br></span><spa=
n style=3D"color:rgb(136,0,0)">// `std::integral_constant` with a template =
struct.</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"co=
lor:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;<=
/span><span style=3D"color:rgb(0,0,136)">typename</span><span style=3D"colo=
r:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><spa=
n style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">con=
stexpr</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> getIdForType</spa=
n><span style=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,=
0,0)"> noexcept<br></span><span style=3D"color:rgb(102,102,0)">{</span><spa=
n style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
rgb(0,0,136)">constexpr</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> =
id</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:=
rgb(0,0,0)">lastIdCounter</span><font color=3D"#666600"><span style=3D"colo=
r:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">value</span><sp=
an style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(136,0,0)">// Get the compile-time counter=
&#39;s current value</span><span style=3D"color:rgb(0,0,0)"><br></span></fo=
nt><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0 lastIdCounter</span><span=
 style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">i=
ncrement</span><span style=3D"color:rgb(102,102,0)">();</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">// Increme=
nt the compile-time counter - it will remember its last value</span><span s=
tyle=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb=
(0,0,136)">return</span><span style=3D"color:rgb(0,0,0)"> id</span><span st=
yle=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br><=
/span><span style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb=
(0,0,0)"><br></span><font color=3D"#666600" style=3D"font-size:small"><span=
 style=3D"color:rgb(0,0,0)"><br></span></font><font color=3D"#666600" style=
=3D"font-size:small"><span style=3D"color:rgb(0,0,136)">int</span><span sty=
le=3D"color:rgb(0,0,0)"> main</span><span style=3D"color:rgb(102,102,0)">()=
</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb=
(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:rgb(136,0,0)">// Whenever `getIdForType&lt;T&gt;()=
` gets called with a certain `T`, a value from</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(136,0,0)">// t=
he compile-time counter is &quot;bound&quot; to that `T` for the rest of th=
e program.</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span>=
<span style=3D"color:rgb(136,0,0)">// Since it is `constexpr` and evaluated=
 at compile-time, there&#39;s no need to store</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(136,0,0)">// t=
he id anywhere in memory - calling the `getIdForType&lt;T&gt;()` function c=
an </span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color:rgb(136,0,0)">// basically be thought of as replacing </span>=
</font><span style=3D"color:rgb(136,0,0)">`getIdForType&lt;T&gt;()` with a =
constant</span><span style=3D"color:rgb(0,0,0)"><br></span><font color=3D"#=
666600" style=3D"font-size:small"><span style=3D"color:rgb(0,0,0)">=C2=A0 =
=C2=A0 </span><span style=3D"color:rgb(136,0,0)">// at compile time.</span>=
<span style=3D"color:rgb(0,0,0)"><br><br>=C2=A0 =C2=A0 std</span><span styl=
e=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">cout <=
/span><span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"co=
lor:rgb(0,0,0)"> getIdForType</span><span style=3D"color:rgb(102,102,0)">&l=
t;</span><span style=3D"color:rgb(102,0,102)">TypeA</span><span style=3D"co=
lor:rgb(102,102,0)">&gt;()</span><span style=3D"color:rgb(0,0,0)"> </span><=
span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"color:rgb=
(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span sty=
le=3D"color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(102,102,0)">;</=
span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,=
0,0)">// Prints &#39;0&#39;</span><span style=3D"color:rgb(0,0,0)"><br></sp=
an></font><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0 std</span><span st=
yle=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">cout=
 </span><span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"=
color:rgb(0,0,0)"> getIdForType</span><span style=3D"color:rgb(102,102,0)">=
&lt;</span><span style=3D"color:rgb(102,0,102)">TypeB</span><span style=3D"=
color:rgb(102,102,0)">&gt;()</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(102,102,0)">&lt;&lt;</span><span style=3D"color:r=
gb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</span><span s=
tyle=3D"color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(102,102,0)">;=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(13=
6,0,0)">// Prints &#39;1&#39;</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span=
 style=3D"color:rgb(0,0,0)">cout </span><span style=3D"color:rgb(102,102,0)=
">&lt;&lt;</span><span style=3D"color:rgb(0,0,0)"> getIdForType</span><span=
 style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(102,0,1=
02)">TypeC</span><span style=3D"color:rgb(102,102,0)">&gt;()</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">&lt;&=
lt;</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:=
rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">endl</span><span =
style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(136,0,0)">// Prints &#39;2&#39;</span><span s=
tyle=3D"color:rgb(0,0,0)"><br></span><font color=3D"#666600" style=3D"font-=
size:small"><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span=
 style=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(0,102,102)">0</span><span style=3D"color:=
rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span s=
tyle=3D"color:rgb(102,102,0)">}</span></font><font color=3D"#666600" style=
=3D"font-size:small"><span style=3D"color:rgb(0,0,0)"><br></span></font></d=
iv></code></div><br></div><div><br></div><div><br></div><div>Thoughts?=C2=
=A0</div><div>What motivated me to write this post is the fact that we have=
 all necessary information at compile-time to assign an unique constant id =
to a specific type - but there (apparently) is no way of doing so.=C2=A0</d=
iv></div></div></blockquote><div><br></div><div>Q: What happens if used in =
different TUs?</div><div><br></div><div class=3D"gmail_quote">=C2=A0 =C2=A0=
 // in file a.cpp</div><div class=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &=
lt;&lt; getIdForType&lt;TypeA&gt;() &lt;&lt; std::endl; // Prints &#39;0&#3=
9;</div><div class=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &lt;&lt; getIdFo=
rType&lt;TypeB&gt;() &lt;&lt; std::endl; // Prints &#39;1&#39;</div><div cl=
ass=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &lt;&lt; getIdForType&lt;TypeC&=
gt;() &lt;&lt; std::endl; // Prints &#39;2&#39;</div><div class=3D"gmail_qu=
ote">=C2=A0 =C2=A0=C2=A0</div><div class=3D"gmail_quote">=C2=A0 =C2=A0 // i=
n file b.cpp</div><div class=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &lt;&l=
t; getIdForType&lt;TypeC&gt;() &lt;&lt; std::endl; // Prints &#39;0&#39;</d=
iv><div class=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &lt;&lt; getIdForType=
&lt;TypeB&gt;() &lt;&lt; std::endl; // Prints &#39;1&#39;</div><div class=
=3D"gmail_quote">=C2=A0 =C2=A0 std::cout &lt;&lt; getIdForType&lt;TypeA&gt;=
() &lt;&lt; std::endl; // Prints &#39;2&#39;</div><div class=3D"gmail_quote=
"><br></div><div class=3D"gmail_quote">Is that the expected result?</div></=
div></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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 />

--20cf30223fc75cb59f05036b9e02--

.
