Topic: Intrusive data members and local variables using


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 20 Jan 2015 18:23:07 -0800 (PST)
Raw View
------=_Part_5634_1847565727.1421806987813
Content-Type: multipart/alternative;
 boundary="----=_Part_5635_1571121716.1421806987813"

------=_Part_5635_1571121716.1421806987813
Content-Type: text/plain; charset=UTF-8

We could use pointer or reference non-type template parameters to refer to
other local variables or data members of a class type. This would allow for
objects that can refer to sibling objects within the same scope without
storing an internal pointer.

These kinds of objects are called Intrusive objects. They are intrusive
because the relative memory location of a particular instance becomes are
part of its type. Such a feature would require a lot of work and careful
analysis, but I wanted to provide a basic sketch here.

*Intrusive local variables:*

template <auto& x>
struct XY {
  decltype(x) y;

  auto sum() { return x + y; }
};

void foo() {
  int x = 3;
  XY<x> xy = { 4 };

  assert(xy.sum() == 7);

  XY<x> xy2 = { 2 };
  assert(xy2.sum() == 5);

  assert(std::is_same<decltype(xy),decltype(xy2)>::value == false);

}

In the above example, xy and xy2 are Intrusive Local Variables (ILV)
because one of their template arguments references a local variable.

The type of xy and xy2 depends on the relative location of the object with
respect to the local variable x. As a result, we have the following rules:

   - Each instance of an ILV has a unique type, as shown above in the
   is_same assertion
   - Only one instance of an ILV can exist, therefore the copy and move
   constructors of an ILV are always deleted, even if the underlying template
   defines them.


*Intrusive data members:*

We can also create intrusive objects as data members of a class, and these
objects can reference other data members or the outer class this pointer.

template <auto* outer_this>
struct inner {
  int y;

  auto sum() { return outer_this->x + y; }
};

struct outer {
  int x;
  inner<x> xy;

  auto sum() { return xy.sum(); }
}


In the above, outer::xy is an Intrusive Data Member (IDM). Similar to
ILV's, the location of xy within the class becomes a part of its type.
Therefore we have the following restrictions:

   - Each instance of an IDM within the same outer class instance has a
   unique type. That is if we created another inner<x> data member, its type
   would be different than xy.
   - A stand-alone instance of an IDM cannot be created. IDM's can only be
   constructed within the initializer list in the outer class's constructors.
   - IDM's may be copied and moved, particularly from one outer class
   instance to the other.


*Use Cases:*

   - Intrusive Linked lists and other data structures.
   - Intrusive reference counting
   - Separating different parts of a larger class
   - Sharing a single data member (example an integer set of flags), with
   other data members without storing additional pointers or passing the
   object into every member function that needs it.


Do you see any reasons why such a feature would not be worth pursuing
further?

--

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

<div dir=3D"ltr"><div>We could use pointer or reference non-type template p=
arameters to refer to other local variables or data members of a class type=
.. This would allow for objects that can refer to sibling objects within the=
 same scope without storing an internal pointer.&nbsp;</div><div><br></div>=
<div>These kinds of objects are called Intrusive objects. They are intrusiv=
e because the relative memory location of a particular instance becomes are=
 part of its type. Such a feature would require a lot of work and careful a=
nalysis, but I wanted to provide a basic sketch here.</div><div><br></div><=
div><b>Intrusive local variables:</b></div><div><br></div><div><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">template</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> XY </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; </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">x</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> sum</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y</s=
pan><font color=3D"#008800"><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
></font><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> x</span><font color=3D"#666600"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">3=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></=
font><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; X=
Y</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;x&gt;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> xy</span>=
<font color=3D"#666600"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=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: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">4</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"styl=
ed-by-prettify"><br></span></font><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">&nbsp; <br>&nbsp; </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">xy</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">sum</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><font color=3D"#00=
0000"><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">7</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></font><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>&nbsp; XY</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&lt;x&gt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> xy2 </span><span style=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: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</=
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; </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">xy2</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">sum</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: #660;" class=3D"styled-by-prettify">=3D=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #066;" class=3D"styled-by-prettify">5</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">is_same</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">decltype</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x=
y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">xy2</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)&gt;::</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">value </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">}</span></div></code></div><br></div><div>In the above example, xy and=
 xy2 are Intrusive Local Variables (ILV) because one of their template argu=
ments references a local variable.&nbsp;</div><div><br></div><div>The type =
of xy and xy2 depends on the relative location of the object with respect t=
o the local variable x. As a result, we have the following rules:</div><div=
><ul><li><span style=3D"font-size: 13px;">Each instance of an ILV has a uni=
que type, as shown above in the is_same assertion</span><br></li><li><span =
style=3D"font-size: 13px;">Only one instance of an ILV can exist, therefore=
 the copy and move constructors of an ILV are always deleted, even if the u=
nderlying template defines them.</span></li></ul></div><div><br></div><div>=
<b>Intrusive data members:</b></div><div><br></div><div>We can also create =
intrusive objects as data members of a class, and these objects can referen=
ce other data members or the outer class this pointer.</div><div><br></div>=
<div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 18=
7); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">template</span><font color=3D"#666600"><spa=
n 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"co=
lor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> outer_this</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;</span></font><span style=3D"color: #000;" c=
lass=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"> inner </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; </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; <br>=
&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> sum</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> outer_this</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">x </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> outer </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; =
inner</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;x=
&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> xy</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> sum</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> xy</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">sum</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #=
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>&nbsp; </span><font color=3D"#666600"></font></div>=
</code></div><br></div><div>In the above, outer::xy is an Intrusive Data Me=
mber (IDM). Similar to ILV's, the location of xy within the class becomes a=
 part of its type. Therefore we have the following restrictions:</div><div>=
<ul><li><span style=3D"font-size: 13px;">Each instance of an IDM within the=
 same outer class instance has a unique type. That is if we created another=
 inner&lt;x&gt; data member, its type would be different than xy.</span><sp=
an style=3D"font-size: 13px;">&nbsp;</span><br></li><li><span style=3D"font=
-size: 13px;">A stand-alone instance of an IDM cannot be created. IDM's can=
 only be constructed within the initializer list in the outer class's const=
ructors.</span><br></li><li><span style=3D"font-size: 13px;">IDM's may be c=
opied and moved, particularly from one outer class instance to the other.</=
span><br></li></ul></div><div><br></div><div><b>Use Cases:</b></div><div><u=
l><li><span style=3D"font-size: 13px;">Intrusive Linked lists and other dat=
a structures.</span><br></li><li><span style=3D"font-size: 13px;">Intrusive=
 reference counting</span><br></li><li><span style=3D"font-size: 13px;">Sep=
arating different parts of a larger class</span><br></li><li><span style=3D=
"font-size: 13px;">Sharing a single data member (example an integer set of =
flags), with other data members without storing additional pointers or pass=
ing the object into every member function that needs it.</span><br></li></u=
l></div><div><br></div><div>Do you see any reasons why such a feature would=
 not be worth pursuing further?</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 />

------=_Part_5635_1571121716.1421806987813--
------=_Part_5634_1847565727.1421806987813--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 20 Jan 2015 18:28:32 -0800 (PST)
Raw View
------=_Part_1207_1653080333.1421807312719
Content-Type: multipart/alternative;
 boundary="----=_Part_1208_1325215492.1421807312719"

------=_Part_1208_1325215492.1421807312719
Content-Type: text/plain; charset=UTF-8



On Tuesday, January 20, 2015 at 9:23:07 PM UTC-5, Matthew Fioravante wrote:
>
> We could use pointer or reference non-type template parameters to refer to
> other local variables or data members of a class type. This would allow for
> objects that can refer to sibling objects within the same scope without
> storing an internal pointer.
>
> These kinds of objects are called Intrusive objects. They are intrusive
> because the relative memory location of a particular instance becomes are
> part of its type. Such a feature would require a lot of work and careful
> analysis, but I wanted to provide a basic sketch here.
>
> *Intrusive local variables:*
>
> template <auto& x>
> struct XY {
>   decltype(x) y;
>
>   auto sum() { return x + y; }
> };
>
> void foo() {
>   int x = 3;
>   XY<x> xy = { 4 };
>
>   assert(xy.sum() == 7);
>
>   XY<x> xy2 = { 2 };
>   assert(xy2.sum() == 5);
>
>   assert(std::is_same<decltype(xy),decltype(xy2)>::value == false);
>
> }
>
> In the above example, xy and xy2 are Intrusive Local Variables (ILV)
> because one of their template arguments references a local variable.
>
> The type of xy and xy2 depends on the relative location of the object with
> respect to the local variable x. As a result, we have the following rules:
>
>    - Each instance of an ILV has a unique type, as shown above in the
>    is_same assertion
>    - Only one instance of an ILV can exist, therefore the copy and move
>    constructors of an ILV are always deleted, even if the underlying template
>    defines them.
>
>
> *Intrusive data members:*
>
> We can also create intrusive objects as data members of a class, and these
> objects can reference other data members or the outer class this pointer.
>
> template <auto* outer_this>
> struct inner {
>   int y;
>
>   auto sum() { return outer_this->x + y; }
> };
>
> struct outer {
>   int x;
>   inner<x> xy;
>
>   auto sum() { return xy.sum(); }
> }
>
>
> In the above, outer::xy is an Intrusive Data Member (IDM). Similar to
> ILV's, the location of xy within the class becomes a part of its type.
> Therefore we have the following restrictions:
>
>    - Each instance of an IDM within the same outer class instance has a
>    unique type. That is if we created another inner<x> data member, its type
>    would be different than xy.
>    - A stand-alone instance of an IDM cannot be created. IDM's can only
>    be constructed within the initializer list in the outer class's
>    constructors.
>    - IDM's may be copied and moved, particularly from one outer class
>    instance to the other.
>
>
> *Use Cases:*
>
>    - Intrusive Linked lists and other data structures.
>    - Intrusive reference counting
>    - Separating different parts of a larger class
>    - Sharing a single data member (example an integer set of flags), with
>    other data members without storing additional pointers or passing the
>    object into every member function that needs it.
>
>
> Do you see any reasons why such a feature would not be worth pursuing
> further?
>


Typo above:

inner<x> xy; should be inner<this> xy;

--

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

<div dir=3D"ltr"><br><br>On Tuesday, January 20, 2015 at 9:23:07 PM UTC-5, =
Matthew Fioravante 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"><div>We could use pointer or reference non-type template parame=
ters to refer to other local variables or data members of a class type. Thi=
s would allow for objects that can refer to sibling objects within the same=
 scope without storing an internal pointer.&nbsp;</div><div><br></div><div>=
These kinds of objects are called Intrusive objects. They are intrusive bec=
ause the relative memory location of a particular instance becomes are part=
 of its type. Such a feature would require a lot of work and careful analys=
is, but I wanted to provide a basic sketch here.</div><div><br></div><div><=
b>Intrusive local variables:</b></div><div><br></div><div><div style=3D"bor=
der:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(25=
0,250,250)"><code><div><span style=3D"color:#008">template</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#660">&amp;</span><span sty=
le=3D"color:#000"> x</span><span style=3D"color:#660">&gt;</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#008">struct</span><span s=
tyle=3D"color:#000"> XY </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>&nbsp; </span><span style=3D"color:#008">decltype</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">x</span><s=
pan style=3D"color:#660">)</span><span style=3D"color:#000"> y</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"><br><br>&nbsp; </sp=
an><span style=3D"color:#008">auto</span><span style=3D"color:#000"> sum</s=
pan><span style=3D"color:#660">()</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">return</span><span style=3D"color:#000"> x </span><sp=
an style=3D"color:#660">+</span><span style=3D"color:#000"> y</span><font c=
olor=3D"#008800"><span style=3D"color:#660">;</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">}</span></font><span style=3D"color:=
#000"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#=
000"><br><br></span><span style=3D"color:#008">void</span><span style=3D"co=
lor:#000"> foo</span><span style=3D"color:#660">()</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#0=
00"><br>&nbsp; </span><span style=3D"color:#008">int</span><span style=3D"c=
olor:#000"> x</span><font color=3D"#666600"><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span=
><span style=3D"color:#066">3</span><span style=3D"color:#660">;</span></fo=
nt><span style=3D"color:#000"><br>&nbsp; XY</span><span style=3D"color:#080=
">&lt;x&gt;</span><span style=3D"color:#000"> xy</span><font color=3D"#6666=
00"><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#066">4</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br></span></font><span style=3D"color:#000">&nbsp; <br>&nb=
sp; </span><span style=3D"color:#008">assert</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">xy</span><span style=3D"color:#660">.=
</span><span style=3D"color:#000">sum</span><span style=3D"color:#660">()</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">=3D</spa=
n><font color=3D"#000000"><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">7</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br></span></font><span styl=
e=3D"color:#000"><br>&nbsp; XY</span><span style=3D"color:#080">&lt;x&gt;</=
span><span style=3D"color:#000"> xy2 </span><span style=3D"color:#660">=3D<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">};</span><span st=
yle=3D"color:#000"><br>&nbsp; </span><span style=3D"color:#008">assert</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">xy2</span><=
span style=3D"color:#660">.</span><span style=3D"color:#000">sum</span><spa=
n style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#066">5</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br><br>&nbsp; </span><span style=3D"color:#008">assert</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">is_same</spa=
n><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">x<wbr>=
y</span><span style=3D"color:#660">),</span><span style=3D"color:#008">decl=
type</span><span style=3D"color:#660">(</span><span style=3D"color:#000">xy=
2</span><span style=3D"color:#660">)&gt;::</span><span style=3D"color:#000"=
>value </span><span style=3D"color:#660">=3D=3D</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">false</span><span style=3D"color:#=
660">);</span><span style=3D"color:#000"><br><br></span><span style=3D"colo=
r:#660">}</span></div></code></div><br></div><div>In the above example, xy =
and xy2 are Intrusive Local Variables (ILV) because one of their template a=
rguments references a local variable.&nbsp;</div><div><br></div><div>The ty=
pe of xy and xy2 depends on the relative location of the object with respec=
t to the local variable x. As a result, we have the following rules:</div><=
div><ul><li><span style=3D"font-size:13px">Each instance of an ILV has a un=
ique type, as shown above in the is_same assertion</span><br></li><li><span=
 style=3D"font-size:13px">Only one instance of an ILV can exist, therefore =
the copy and move constructors of an ILV are always deleted, even if the un=
derlying template defines them.</span></li></ul></div><div><br></div><div><=
b>Intrusive data members:</b></div><div><br></div><div>We can also create i=
ntrusive objects as data members of a class, and these objects can referenc=
e other data members or the outer class this pointer.</div><div><br></div><=
div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;ba=
ckground-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">temp=
late</span><font color=3D"#666600"><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">auto</span><spa=
n style=3D"color:#660">*</span><span style=3D"color:#000"> outer_this</span=
><span style=3D"color:#660">&gt;</span></font><span style=3D"color:#000"><b=
r></span><span style=3D"color:#008">struct</span><span style=3D"color:#000"=
> inner </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>&nbsp; </span><span style=3D"color:#008">int</span><span style=3D"col=
or:#000"> y</span><span style=3D"color:#660">;</span><span style=3D"color:#=
000"><br>&nbsp; <br>&nbsp; </span><span style=3D"color:#008">auto</span><sp=
an style=3D"color:#000"> sum</span><span style=3D"color:#660">()</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">return</span><span sty=
le=3D"color:#000"> outer_this</span><span style=3D"color:#660">-&gt;</span>=
<span style=3D"color:#000">x </span><span style=3D"color:#660">+</span><spa=
n style=3D"color:#000"> y</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">struct</span><spa=
n style=3D"color:#000"> outer </span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"><br>&nbsp; </span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> x</span><span style=3D"color:#660">;</span>=
<span style=3D"color:#000"><br>&nbsp; inner</span><span style=3D"color:#080=
">&lt;x&gt;</span><span style=3D"color:#000"> xy</span><span style=3D"color=
:#660">;</span><span style=3D"color:#000"><br><br>&nbsp; </span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> sum</span><span styl=
e=3D"color:#660">()</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#008">return</span><span style=3D"color:#000"> xy</span><span style=3D"co=
lor:#660">.</span><span style=3D"color:#000">sum</span><span style=3D"color=
:#660">();</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br>&nbsp; </span><font color=3D"#6666=
00"></font></div></code></div><br></div><div>In the above, outer::xy is an =
Intrusive Data Member (IDM). Similar to ILV's, the location of xy within th=
e class becomes a part of its type. Therefore we have the following restric=
tions:</div><div><ul><li><span style=3D"font-size:13px">Each instance of an=
 IDM within the same outer class instance has a unique type. That is if we =
created another inner&lt;x&gt; data member, its type would be different tha=
n xy.</span><span style=3D"font-size:13px">&nbsp;</span><br></li><li><span =
style=3D"font-size:13px">A stand-alone instance of an IDM cannot be created=
.. IDM's can only be constructed within the initializer list in the outer cl=
ass's constructors.</span><br></li><li><span style=3D"font-size:13px">IDM's=
 may be copied and moved, particularly from one outer class instance to the=
 other.</span><br></li></ul></div><div><br></div><div><b>Use Cases:</b></di=
v><div><ul><li><span style=3D"font-size:13px">Intrusive Linked lists and ot=
her data structures.</span><br></li><li><span style=3D"font-size:13px">Intr=
usive reference counting</span><br></li><li><span style=3D"font-size:13px">=
Separating different parts of a larger class</span><br></li><li><span style=
=3D"font-size:13px">Sharing a single data member (example an integer set of=
 flags), with other data members without storing additional pointers or pas=
sing the object into every member function that needs it.</span><br></li></=
ul></div><div><br></div><div>Do you see any reasons why such a feature woul=
d not be worth pursuing further?</div></div></blockquote><div><br></div><di=
v><br></div><div><span style=3D"font-size: 13.1428575515747px;">Typo above:=
</span></div><div><br></div><div>inner&lt;x&gt; xy; should be inner&lt;this=
&gt; xy;&nbsp;</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 />

------=_Part_1208_1325215492.1421807312719--
------=_Part_1207_1653080333.1421807312719--

.


Author: Daniela Engert <dani@ngrt.de>
Date: Wed, 21 Jan 2015 17:04:35 +0100
Raw View
This is an OpenPGP/MIME signed message (RFC 4880 and 3156)
--xD4rVXSWnMrlE3rDkq7gNxb8CdtnV2Crw
Content-Type: text/plain; charset=UTF-8

Am 21.01.2015 um 03:23 schrieb Matthew Fioravante:
> We could use pointer or reference non-type template parameters to refer
> to other local variables or data members of a class type. This would
> allow for objects that can refer to sibling objects within the same
> scope without storing an internal pointer.

I'd love to see this functionality in C++. Everytime when I needed
something like that in the past I had to use horrible macro magic or  or
other, even worse workarounds.

Ciao
  Dani


--

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

--xD4rVXSWnMrlE3rDkq7gNxb8CdtnV2Crw
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iF4EAREIAAYFAlS/zh8ACgkQugNWoSxGOMVybwD/Wiuh/PZhCxc9tZ2URyO13m7l
UGkIXamThwt1uxG67vcA/i38UaOitAil0lOh+dNateMsfeWUQGts3Bl6zphg7cQ5
=hiSW
-----END PGP SIGNATURE-----

--xD4rVXSWnMrlE3rDkq7gNxb8CdtnV2Crw--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 22 Jan 2015 12:22:06 +0800
Raw View
--Apple-Mail=_98A98FB6-C40B-4C1B-A6E4-FCD5BE65AD1F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9301=E2=80=9321, at 10:23 AM, Matthew Fioravante <fmatthew5=
876@gmail.com> wrote:
>=20
> We could use pointer or reference non-type template parameters to refer t=
o other local variables or data members of a class type. This would allow f=
or objects that can refer to sibling objects within the same scope without =
storing an internal pointer.=20
>=20
> These kinds of objects are called Intrusive objects. They are intrusive b=
ecause the relative memory location of a particular instance becomes are pa=
rt of its type.

Sounds a lot like a lambda. A capture by reference becomes a reference memb=
er of the lambda object. Reference members (and references in general) are =
not required to use real storage though. Function inlining optimization all=
ows the compiler to see that the capture is a reference to another local ob=
ject, so that it can be evaluated without indirection.

> Such a feature would require a lot of work and careful analysis, but I wa=
nted to provide a basic sketch here.
>=20
> Intrusive local variables:
>=20
> template <auto& x>
> struct XY {
>   decltype(x) y;
>=20
>   auto sum() { return x + y; }
> };
>=20
> void foo() {
>   int x =3D 3;
>   XY<x> xy =3D { 4 };
>  =20
>   assert(xy.sum() =3D=3D 7);
>=20
>   XY<x> xy2 =3D { 2 };
>   assert(xy2.sum() =3D=3D 5);
>=20
>   assert(std::is_same<decltype(xy),decltype(xy2)>::value =3D=3D false);
>=20
> }

template< typename get_x >
struct XY {
    get_x x;
    decltype( x() ) y;

    auto sum() { return x() + y; }
};

template< typename get_x >
XY< get_x > make_XY( get_x x, decltype( x() ) y )
    { return { x, y }; }

int main() {
    int x =3D 3;
    auto xy =3D make_XY( [&]{ return x; }, 4 );

    assert(xy.sum() =3D=3D 7);

    auto xy2 =3D make_XY( [&]{ return x; }, 2 );
    assert(xy2.sum() =3D=3D 5);

    static_assert(std::is_same<decltype(xy),decltype(xy2)>::value =3D=3D fa=
lse, "");
};

GCC optimizes away this entire program: http://goo.gl/tMT3Fd <http://goo.gl=
/tMT3Fd>

If you reuse the same lambda object as an argument, then is_same will retur=
n true. It=E2=80=99s nice to have the choice to avoid additional instantiat=
ions, so I=E2=80=99m not sure why unique types are essential to your demons=
tration.

Transparently converting arguments to lambdas is the subject of the recent =
discussion thread, =E2=80=9CParameters evaluated on use.=E2=80=9D Also, the=
 idea is essentially like using an expression alias as a parameter. Express=
ion aliases are a topic of active development.

> Intrusive data members:
>=20
> We can also create intrusive objects as data members of a class, and thes=
e objects can reference other data members or the outer class this pointer.
>=20
> In the above, outer::xy is an Intrusive Data Member (IDM). Similar to ILV=
's, the location of xy within the class becomes a part of its type. Therefo=
re we have the following restrictions:

This is also like an expression alias. See my paper N4147, =E2=80=9CInline =
variables, or encapsulated expressions,=E2=80=9D sections 2.5 and 2.6. For =
example, =C2=A72.5 has CRTP instead of outer_this.

> IDM's may be copied and moved, particularly from one outer class instance=
 to the other.
This seems to disagree with the other semantics. If you can change the refe=
rent, then you need storage and the whole thing is just a glorified pointer=
..

--=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=_98A98FB6-C40B-4C1B-A6E4-FCD5BE65AD1F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9301=
=E2=80=9321, at 10:23 AM, Matthew Fioravante &lt;<a href=3D"mailto:fmatthew=
5876@gmail.com" class=3D"">fmatthew5876@gmail.com</a>&gt; wrote:</div><br c=
lass=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=
=3D""><div class=3D"">We could use pointer or reference non-type template p=
arameters to refer to other local variables or data members of a class type=
.. This would allow for objects that can refer to sibling objects within the=
 same scope without storing an internal pointer.&nbsp;</div><div class=3D""=
><br class=3D""></div><div class=3D"">These kinds of objects are called Int=
rusive objects. They are intrusive because the relative memory location of =
a particular instance becomes are part of its type. </div></div></div></blo=
ckquote><div><br class=3D""></div><div>Sounds a lot like a lambda. A captur=
e by reference becomes a reference member of the lambda object. Reference m=
embers (and references in general) are not required to use real storage tho=
ugh. Function inlining optimization allows the compiler to see that the cap=
ture is a reference to another local object, so that it can be evaluated wi=
thout indirection.</div><br class=3D""><blockquote type=3D"cite" class=3D""=
><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"">Such a feature=
 would require a lot of work and careful analysis, but I wanted to provide =
a basic sketch here.</div><div class=3D""><br class=3D""></div><div class=
=3D""><b class=3D"">Intrusive local variables:</b></div><div class=3D""><br=
 class=3D""></div><div class=3D""><div class=3D"prettyprint" style=3D"borde=
r: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: r=
gb(250, 250, 250);"><code class=3D"prettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span> <span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&amp;</span> x<span style=3D"color: #660;" class=3D"style=
d-by-prettify">&gt;</span><br class=3D""><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span> XY <span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><br class=3D"">&nbsp; <span style=3D"color:=
 #008;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span>x<span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span> y<span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><br class=3D""><br class=3D"">&nbsp; <span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span> sum<span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span> <span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{</span> <span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span> x <span style=3D"color: #660;=
" class=3D"styled-by-prettify">+</span> y<font color=3D"#008800" class=3D""=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</span></font><br class=3D""><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">};</span><br class=3D""><br class=
=3D""><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span>=
 foo<span style=3D"color: #660;" class=3D"styled-by-prettify">()</span> <sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><br class=3D=
"">&nbsp; <span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an> x<font color=3D"#666600" class=3D""><span style=3D"" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span></font><br class=3D"">&nbsp=
; XY<span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;x&gt;</sp=
an> xy<font color=3D"#666600" class=3D""><span style=3D"" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">4</span><span style=3D"" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"" class=3D"styled-by-prettify"><br class=3D""></span></font>&=
nbsp; <br class=3D"">&nbsp; <span style=3D"color: #008;" class=3D"styled-by=
-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span>xy<span style=3D"color: #660;" class=3D"styled-by-prettify">=
..</span>sum<span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an> <span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><fo=
nt class=3D""><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">7</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"" class=3D"style=
d-by-prettify"><br class=3D""></span></font><br class=3D"">&nbsp; XY<span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">&lt;x&gt;</span> xy2 <sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span> <span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span> <span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">2</span> <span style=3D"color: #66=
0;" class=3D"styled-by-prettify">};</span><br class=3D"">&nbsp; <span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span>xy2<span style=3D"color:=
 #660;" class=3D"styled-by-prettify">.</span>sum<span style=3D"color: #660;=
" class=3D"styled-by-prettify">()</span> <span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span> <span style=3D"color: #066;" class=3D=
"styled-by-prettify">5</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><br class=3D""><br class=3D"">&nbsp; <span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span>std<span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span>is_same<span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span>xy<span style=3D"color: #660;" class=3D"sty=
led-by-prettify">),</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">decltype</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span>xy2<span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)&gt;::</span>value <span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D=3D</span> <span style=3D"color: #008;" class=3D"styled-by-prettify"=
>false</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><br class=3D""><br class=3D""><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span></code></div></div></div></div></blockquote><div>=
<br class=3D""></div><div><font face=3D"Courier" class=3D"">template&lt; ty=
pename get_x &gt;</font></div><div><div><font face=3D"Courier" class=3D"">s=
truct XY {</font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp;=
 get_x x;</font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; =
decltype( x() ) y;</font></div><div><font face=3D"Courier" class=3D""><br c=
lass=3D""></font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp;=
 auto sum() { return x() + y; }</font></div><div><font face=3D"Courier" cla=
ss=3D"">};</font></div><div><font face=3D"Courier" class=3D""><br class=3D"=
"></font></div><div><font face=3D"Courier" class=3D"">template&lt; typename=
 get_x &gt;</font></div><div><font face=3D"Courier" class=3D"">XY&lt; get_x=
 &gt; make_XY( get_x x, decltype( x() ) y )</font></div><div><font face=3D"=
Courier" class=3D"">&nbsp; &nbsp; { return { x, y }; }</font></div><div><fo=
nt face=3D"Courier" class=3D""><br class=3D""></font></div><div><font face=
=3D"Courier" class=3D"">int main() {</font></div><div><font face=3D"Courier=
" class=3D"">&nbsp; &nbsp; int x =3D 3;</font></div><div><font face=3D"Cour=
ier" class=3D"">&nbsp; &nbsp; auto xy =3D make_XY( [&amp;]{ return x; }, 4 =
);</font></div><div><font face=3D"Courier" class=3D""><br class=3D""></font=
></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; assert(xy.sum()=
 =3D=3D 7);</font></div><div><font face=3D"Courier" class=3D""><br class=3D=
""></font></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; auto x=
y2 =3D make_XY( [&amp;]{ return x; }, 2 );</font></div><div><font face=3D"C=
ourier" class=3D"">&nbsp; &nbsp; assert(xy2.sum() =3D=3D 5);</font></div><d=
iv><font face=3D"Courier" class=3D""><br class=3D""></font></div><div><font=
 face=3D"Courier" class=3D"">&nbsp; &nbsp; static_assert(std::is_same&lt;de=
cltype(xy),decltype(xy2)&gt;::value =3D=3D false, "");</font></div><div><fo=
nt face=3D"Courier" class=3D"">};</font></div><div class=3D""><br class=3D"=
"></div><div class=3D"">GCC optimizes away this entire program:&nbsp;<a hre=
f=3D"http://goo.gl/tMT3Fd" class=3D"">http://goo.gl/tMT3Fd</a></div><div cl=
ass=3D""><br class=3D""></div><div class=3D"">If you reuse the same lambda =
object as an argument, then <font face=3D"Courier" class=3D"">is_same</font=
> will return true. It=E2=80=99s nice to have the choice to avoid additiona=
l instantiations, so I=E2=80=99m not sure why unique types are essential to=
 your demonstration.</div><div class=3D""><br class=3D""></div><div class=
=3D"">Transparently converting arguments to lambdas is the subject of the r=
ecent discussion thread, =E2=80=9CParameters evaluated on use.=E2=80=9D Als=
o, the idea is essentially like using an expression alias as a parameter. E=
xpression aliases are a topic of active development.</div><div class=3D""><=
br class=3D""></div></div><blockquote type=3D"cite" class=3D""><div dir=3D"=
ltr" class=3D""><div class=3D""><b class=3D"">Intrusive data members:</b></=
div><div class=3D""><br class=3D""></div><div class=3D"">We can also create=
 intrusive objects as data members of a class, and these objects can refere=
nce other data members or the outer class this pointer.</div></div></blockq=
uote><blockquote type=3D"cite" class=3D""><br class=3D""></blockquote><bloc=
kquote type=3D"cite" class=3D""><div dir=3D"ltr" class=3D""><div class=3D""=
>In the above, outer::xy is an Intrusive Data Member (IDM). Similar to ILV'=
s, the location of xy within the class becomes a part of its type. Therefor=
e we have the following restrictions:</div></div></blockquote><div><br clas=
s=3D""></div><div>This is also like an expression alias. See my paper N4147=
, =E2=80=9CInline variables, or encapsulated expressions,=E2=80=9D sections=
 2.5 and 2.6. For example, =C2=A72.5 has CRTP instead of <font face=3D"Cour=
ier" class=3D"">outer_this</font>.</div><div><br class=3D""></div><blockquo=
te type=3D"cite" class=3D""><div dir=3D"ltr" class=3D""><div class=3D""><ul=
 class=3D""><li class=3D""><span style=3D"font-size: 13px;" class=3D"">IDM'=
s may be copied and moved, particularly from one outer class instance to th=
e other.</span></li></ul></div></div></blockquote><div>This seems to disagr=
ee with the other semantics. If you can change the referent, then you need =
storage and the whole thing is just a glorified pointer.</div></div></body>=
</html>

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

--Apple-Mail=_98A98FB6-C40B-4C1B-A6E4-FCD5BE65AD1F--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 21 Jan 2015 21:00:47 -0800 (PST)
Raw View
------=_Part_70_1349696281.1421902847653
Content-Type: multipart/alternative;
 boundary="----=_Part_71_475631506.1421902847653"

------=_Part_71_475631506.1421902847653
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, January 21, 2015 at 11:22:17 PM UTC-5, David Krauss wrote:
>
>
> On 2015=E2=80=9301=E2=80=9321, at 10:23 AM, Matthew Fioravante <fmatth...=
@gmail.com=20
> <javascript:>> wrote:
>
> We could use pointer or reference non-type template parameters to refer t=
o=20
> other local variables or data members of a class type. This would allow f=
or=20
> objects that can refer to sibling objects within the same scope without=
=20
> storing an internal pointer.=20
>
> These kinds of objects are called Intrusive objects. They are intrusive=
=20
> because the relative memory location of a particular instance becomes are=
=20
> part of its type.=20
>
>
> Sounds a lot like a lambda. A capture by reference becomes a reference=20
> member of the lambda object. Reference members (and references in general=
)=20
> are not required to use real storage though. Function inlining optimizati=
on=20
> allows the compiler to see that the capture is a reference to another loc=
al=20
> object, so that it can be evaluated without indirection.
>

References can only be "storage free" with the help of an inlining=20
optimizer.=20


> Such a feature would require a lot of work and careful analysis, but I=20
> wanted to provide a basic sketch here.
>
> *Intrusive local variables:*
>
> template <auto& x>
> struct XY {
>   decltype(x) y;
>
>   auto sum() { return x + y; }
> };
>
> void foo() {
>   int x =3D 3;
>   XY<x> xy =3D { 4 };
>  =20
>   assert(xy.sum() =3D=3D 7);
>
>   XY<x> xy2 =3D { 2 };
>   assert(xy2.sum() =3D=3D 5);
>
>   assert(std::is_same<decltype(xy),decltype(xy2)>::value =3D=3D false);
>
> }
>
>
> template< typename get_x >
> struct XY {
>     get_x x;
>     decltype( x() ) y;
>
>     auto sum() { return x() + y; }
> };
>
> template< typename get_x >
> XY< get_x > make_XY( get_x x, decltype( x() ) y )
>     { return { x, y }; }
>
> int main() {
>     int x =3D 3;
>     auto xy =3D make_XY( [&]{ return x; }, 4 );
>
>     assert(xy.sum() =3D=3D 7);
>
>     auto xy2 =3D make_XY( [&]{ return x; }, 2 );
>     assert(xy2.sum() =3D=3D 5);
>
>     static_assert(std::is_same<decltype(xy),decltype(xy2)>::value =3D=3D=
=20
> false, "");
> };
>
> GCC optimizes away this entire program: http://goo.gl/tMT3Fd
>
> If you reuse the same lambda object as an argument, then is_same will=20
> return true. It=E2=80=99s nice to have the choice to avoid additional=20
> instantiations, so I=E2=80=99m not sure why unique types are essential to=
 your=20
> demonstration.
>

In the way my feature would work, each instance maintains the constexpr=20
relative offset from its physical location to the sibling variable. In each=
=20
instance this offset would be different because each instance occupies a=20
separate memory location and thus its relative offset to the sibling has=20
changed. Since this offset is not stored in actual memory it has to be part=
=20
of the type and thus the compiled code from the template would be different=
=20
for each one.

Ignoring inlining, the following example describes what the compiler will=
=20
do.

template <auto& x> struct xy {
  int y;
  auto sum() { return x + y; }
}

void foo() {
  int x; //Located at address 0 from stack ptr
  xy xy0<x>; //Located at address 4
  xy xy1<x>; //Located at address 8

  xy0.sum() //Compiles as: add this->y and the integer 4 bytes before this
  xy1.sum() //Compiles as: add this->y and the integer 8 bytes before this

  assert(sizeof(xy0) =3D=3D sizeof(int)); //Reference to x is encoded in th=
e=20
type, not stored
  assert(sizeof(xy1) =3D=3D sizeof(int)); //Reference to x is encoded in th=
e=20
type, not stored
}



Gcc may have optimized away your entire program, but that's only because=20
its a very simple example. Your XY depends on an unnamed lambda type, so it=
=20
cannot be passed along to any functions that are not type deducing template=
=20
code. Also as soon as your XY object gets out of view of the inliner, those=
=20
lambdas will have to store an internal reference. If you add a return=20
sizeof(xy); to your example, you'll see that its returning 16, the size of=
=20
an 8 byte pointer (to main's x) + 4 byte int (XY::y) + 4 bytes of padding.


> Transparently converting arguments to lambdas is the subject of the recen=
t=20
> discussion thread, =E2=80=9CParameters evaluated on use.=E2=80=9D Also, t=
he idea is=20
> essentially like using an expression alias as a parameter. Expression=20
> aliases are a topic of active development.
>

Given the power of optimizers, the use cases of an ILV is probably small.=
=20
My real motivating case is for the Intrusive data members to implement=20
intrusive data structures such as the linked lists used in the linux kernel=
=20
and other C projects via macros.

>
> *Intrusive data members:*
>
> We can also create intrusive objects as data members of a class, and thes=
e=20
> objects can reference other data members or the outer class this pointer.
>
>
> In the above, outer::xy is an Intrusive Data Member (IDM). Similar to=20
> ILV's, the location of xy within the class becomes a part of its type.=20
> Therefore we have the following restrictions:
>
>
> This is also like an expression alias. See my paper N4147, =E2=80=9CInlin=
e=20
> variables, or encapsulated expressions,=E2=80=9D sections 2.5 and 2.6. Fo=
r example,=20
> =C2=A72.5 has CRTP instead of outer_this.
>

CRTP requires inheritance. This feature is about composition. Unless I=20
misunderstood, I don't believe your paper allows a data member of a class=
=20
to access another data member without the use of a pointer or reference.=20

>
>
>    - IDM's may be copied and moved, particularly from one outer class=20
>    instance to the other.
>
> This seems to disagree with the other semantics. If you can change the=20
> referent, then you need storage and the whole thing is just a glorified=
=20
> pointer.
>

You can't change the referent since it is encoded within the type and not=
=20
stored anywhere. You can only copy an IDM of the same type from one=20
instance of the outer class to another. Maybe the following example would=
=20
make more sense.

template <auto* outer_this> struct inner {};
struct outer {
  inner i0<this>; //i0::outer_this is implemented as a constexpr 0 byte=20
offset from i0::this
  inner i1<this>; //i1::outer_this is implemented as a constexpr=20
-sizeof(i0) byte offset from i1::this
};

void foo() {
  outer o0, o1;

  o0.i0 =3D o1.i0; //Ok
  o0.i1 =3D o1.i1; //Ok
  o0.i0 =3D o1.i1; //Error: outer::i0 and outer::i1 have different types
  o0.i1 =3D o1.i0; //Error: outer::i1 and outer::i0 have different types
}

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_71_475631506.1421902847653
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, January 21, 2015 at 11:22:17 PM UTC-=
5, David Krauss wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div sty=
le=3D"word-wrap:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=
=E2=80=9301=E2=80=9321, at 10:23 AM, Matthew Fioravante &lt;<a href=3D"java=
script:" target=3D"_blank" gdf-obfuscated-mailto=3D"udtwyy5bfc0J" rel=3D"no=
follow" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"t=
his.href=3D'javascript:';return true;">fmatth...@gmail.com</a>&gt; wrote:</=
div><br><div><div dir=3D"ltr"><div>We could use pointer or reference non-ty=
pe template parameters to refer to other local variables or data members of=
 a class type. This would allow for objects that can refer to sibling objec=
ts within the same scope without storing an internal pointer.&nbsp;</div><d=
iv><br></div><div>These kinds of objects are called Intrusive objects. They=
 are intrusive because the relative memory location of a particular instanc=
e becomes are part of its type. </div></div></div></blockquote><div><br></d=
iv><div>Sounds a lot like a lambda. A capture by reference becomes a refere=
nce member of the lambda object. Reference members (and references in gener=
al) are not required to use real storage though. Function inlining optimiza=
tion allows the compiler to see that the capture is a reference to another =
local object, so that it can be evaluated without indirection.</div></div><=
/div></blockquote><div><br></div><div>References can only be "storage free"=
 with the help of an inlining optimizer.&nbsp;</div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><d=
iv><br><blockquote type=3D"cite"><div><div dir=3D"ltr"><div>Such a feature =
would require a lot of work and careful analysis, but I wanted to provide a=
 basic sketch here.</div><div><br></div><div><b>Intrusive local variables:<=
/b></div><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187=
);word-wrap:break-word;background-color:rgb(250,250,250)"><code><span style=
=3D"color:#008">template</span> <span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;</span> x<=
span style=3D"color:#660">&gt;</span><br><span style=3D"color:#008">struct<=
/span> XY <span style=3D"color:#660">{</span><br>&nbsp; <span style=3D"colo=
r:#008">decltype</span><span style=3D"color:#660">(</span>x<span style=3D"c=
olor:#660">)</span> y<span style=3D"color:#660">;</span><br><br>&nbsp; <spa=
n style=3D"color:#008">auto</span> sum<span style=3D"color:#660">()</span> =
<span style=3D"color:#660">{</span> <span style=3D"color:#008">return</span=
> x <span style=3D"color:#660">+</span> y<font color=3D"#008800"><span styl=
e=3D"color:#660">;</span><span> </span><span style=3D"color:#660">}</span><=
/font><br><span style=3D"color:#660">};</span><br><br><span style=3D"color:=
#008">void</span> foo<span style=3D"color:#660">()</span> <span style=3D"co=
lor:#660">{</span><br>&nbsp; <span style=3D"color:#008">int</span> x<font c=
olor=3D"#666600"><span> </span><span style=3D"color:#660">=3D</span><span> =
</span><span style=3D"color:#066">3</span><span style=3D"color:#660">;</spa=
n></font><br>&nbsp; XY<span style=3D"color:#080">&lt;x&gt;</span> xy<font c=
olor=3D"#666600"><span> </span><span style=3D"color:#660">=3D</span><span> =
</span><span style=3D"color:#660">{</span><span> </span><span style=3D"colo=
r:#066">4</span><span> </span><span style=3D"color:#660">};</span><span><br=
></span></font>&nbsp; <br>&nbsp; <span style=3D"color:#008">assert</span><s=
pan style=3D"color:#660">(</span>xy<span style=3D"color:#660">.</span>sum<s=
pan style=3D"color:#660">()</span> <span style=3D"color:#660">=3D</span><fo=
nt><span style=3D"color:#660">=3D</span><span> </span><span style=3D"color:=
#066">7</span><span style=3D"color:#660">);</span><span><br></span></font><=
br>&nbsp; XY<span style=3D"color:#080">&lt;x&gt;</span> xy2 <span style=3D"=
color:#660">=3D</span> <span style=3D"color:#660">{</span> <span style=3D"c=
olor:#066">2</span> <span style=3D"color:#660">};</span><br>&nbsp; <span st=
yle=3D"color:#008">assert</span><span style=3D"color:#660">(</span>xy2<span=
 style=3D"color:#660">.</span>sum<span style=3D"color:#660">()</span> <span=
 style=3D"color:#660">=3D=3D</span> <span style=3D"color:#066">5</span><spa=
n style=3D"color:#660">);</span><br><br>&nbsp; <span style=3D"color:#008">a=
ssert</span><span style=3D"color:#660">(</span>std<span style=3D"color:#660=
">::</span>is_same<span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#008">decltype</span><span style=3D"color:#660">(</span>x<wbr>y<span styl=
e=3D"color:#660">),</span><span style=3D"color:#008">decltype</span><span s=
tyle=3D"color:#660">(</span>xy2<span style=3D"color:#660">)&gt;::</span>val=
ue <span style=3D"color:#660">=3D=3D</span> <span style=3D"color:#008">fals=
e</span><span style=3D"color:#660">);</span><br><br><span style=3D"color:#6=
60">}</span></code></div></div></div></div></blockquote><div><br></div><div=
><font face=3D"Courier">template&lt; typename get_x &gt;</font></div><div><=
div><font face=3D"Courier">struct XY {</font></div><div><font face=3D"Couri=
er">&nbsp; &nbsp; get_x x;</font></div><div><font face=3D"Courier">&nbsp; &=
nbsp; decltype( x() ) y;</font></div><div><font face=3D"Courier"><br></font=
></div><div><font face=3D"Courier">&nbsp; &nbsp; auto sum() { return x() + =
y; }</font></div><div><font face=3D"Courier">};</font></div><div><font face=
=3D"Courier"><br></font></div><div><font face=3D"Courier">template&lt; type=
name get_x &gt;</font></div><div><font face=3D"Courier">XY&lt; get_x &gt; m=
ake_XY( get_x x, decltype( x() ) y )</font></div><div><font face=3D"Courier=
">&nbsp; &nbsp; { return { x, y }; }</font></div><div><font face=3D"Courier=
"><br></font></div><div><font face=3D"Courier">int main() {</font></div><di=
v><font face=3D"Courier">&nbsp; &nbsp; int x =3D 3;</font></div><div><font =
face=3D"Courier">&nbsp; &nbsp; auto xy =3D make_XY( [&amp;]{ return x; }, 4=
 );</font></div><div><font face=3D"Courier"><br></font></div><div><font fac=
e=3D"Courier">&nbsp; &nbsp; assert(xy.sum() =3D=3D 7);</font></div><div><fo=
nt face=3D"Courier"><br></font></div><div><font face=3D"Courier">&nbsp; &nb=
sp; auto xy2 =3D make_XY( [&amp;]{ return x; }, 2 );</font></div><div><font=
 face=3D"Courier">&nbsp; &nbsp; assert(xy2.sum() =3D=3D 5);</font></div><di=
v><font face=3D"Courier"><br></font></div><div><font face=3D"Courier">&nbsp=
; &nbsp; static_assert(std::is_same&lt;<wbr>decltype(xy),decltype(xy2)&gt;:=
:<wbr>value =3D=3D false, "");</font></div><div><font face=3D"Courier">};</=
font></div><div><br></div><div>GCC optimizes away this entire program:&nbsp=
;<a href=3D"http://goo.gl/tMT3Fd" target=3D"_blank" rel=3D"nofollow" onmous=
edown=3D"this.href=3D'http://goo.gl/tMT3Fd';return true;" onclick=3D"this.h=
ref=3D'http://goo.gl/tMT3Fd';return true;">http://goo.gl/tMT3Fd</a></div><d=
iv><br></div><div>If you reuse the same lambda object as an argument, then =
<font face=3D"Courier">is_same</font> will return true. It=E2=80=99s nice t=
o have the choice to avoid additional instantiations, so I=E2=80=99m not su=
re why unique types are essential to your demonstration.</div></div></div><=
/div></blockquote><div><br></div><div>In the way my feature would work, eac=
h instance maintains the constexpr relative offset from its physical locati=
on to the sibling variable. In each instance this offset would be different=
 because each instance occupies a separate memory location and thus its rel=
ative offset to the sibling has changed. Since this offset is not stored in=
 actual memory it has to be part of the type and thus the compiled code fro=
m the template would be different for each one.</div><div><br></div><div>Ig=
noring inlining, the following example describes what the compiler will do.=
</div><div><br></div><div><div class=3D"prettyprint" style=3D"border: 1px s=
olid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, =
250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"sty=
led-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=
">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x=
y</span><font color=3D"#666600"><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">in=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> sum</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #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"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #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">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> x</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: #800;" class=3D"style=
d-by-prettify">//Located at address 0 from stack ptr</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; xy xy0</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&lt;x&gt;</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">//Located at address 4</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; xy xy1</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&lt;x&gt;</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">//Located at address 8</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; xy0</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">sum</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">//Compiles as: add this-&gt;y and the integer 4 bytes befo=
re this</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>&nbsp; xy1</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">sum</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">//Compiles as: add this-&gt;y an=
d the integer 8 bytes before this</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>&nbsp; </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">xy0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</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: #800;" class=3D"styled-by-pretti=
fy">//Reference to x is encoded in the type, not stored</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">xy1</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">));</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">//Reference to x is encoded in the type, not stor=
ed</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><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></font><=
/div></code></div><br></div><div><br></div><div>Gcc may have optimized away=
 your entire program, but that's only because its a very simple example. Yo=
ur XY depends on an unnamed lambda type, so it cannot be passed along to an=
y functions that are not type deducing template code. Also as soon as your =
XY object gets out of view of the inliner, those lambdas will have to store=
 an internal reference. If you add a return sizeof(xy); to your example, yo=
u'll see that its returning 16, the size of an 8 byte pointer (to main's x)=
 + 4 byte int (XY::y) + 4 bytes of padding.</div><div><br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div>=
<div><div><br></div><div>Transparently converting arguments to lambdas is t=
he subject of the recent discussion thread, =E2=80=9CParameters evaluated o=
n use.=E2=80=9D Also, the idea is essentially like using an expression alia=
s as a parameter. Expression aliases are a topic of active development.</di=
v></div></div></div></blockquote><div><br></div><div>Given the power of opt=
imizers, the use cases of an ILV is probably small. My real motivating case=
 is for the Intrusive data members to implement intrusive data structures s=
uch as the linked lists used in the linux kernel and other C projects via m=
acros.</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word=
-wrap:break-word"><div><div><div><br></div></div><blockquote type=3D"cite">=
<div dir=3D"ltr"><div><b>Intrusive data members:</b></div><div><br></div><d=
iv>We can also create intrusive objects as data members of a class, and the=
se objects can reference other data members or the outer class this pointer=
..</div></div></blockquote><blockquote type=3D"cite"><br></blockquote><block=
quote type=3D"cite"><div dir=3D"ltr"><div>In the above, outer::xy is an Int=
rusive Data Member (IDM). Similar to ILV's, the location of xy within the c=
lass becomes a part of its type. Therefore we have the following restrictio=
ns:</div></div></blockquote><div><br></div><div>This is also like an expres=
sion alias. See my paper N4147, =E2=80=9CInline variables, or encapsulated =
expressions,=E2=80=9D sections 2.5 and 2.6. For example, =C2=A72.5 has CRTP=
 instead of <font face=3D"Courier">outer_this</font>.</div></div></div></bl=
ockquote><div><br></div><div>CRTP requires inheritance. This feature is abo=
ut composition. Unless I misunderstood, I don't believe your paper allows a=
 data member of a class to access another data member without the use of a =
pointer or reference.&nbsp;</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div style=3D"word-wrap:break-word"><div><div><br></div><blockquote type=
=3D"cite"><div dir=3D"ltr"><div><ul><li><span style=3D"font-size:13px">IDM'=
s may be copied and moved, particularly from one outer class instance to th=
e other.</span></li></ul></div></div></blockquote><div>This seems to disagr=
ee with the other semantics. If you can change the referent, then you need =
storage and the whole thing is just a glorified pointer.</div></div></div><=
/blockquote><div><br></div><div>You can't change the referent since it is e=
ncoded within the type and not stored anywhere. You can only copy an IDM of=
 the same type from one instance of the outer class to another. Maybe the f=
ollowing example would make more sense.</div><div><br></div><div><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">template</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> outer_this</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> inner </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> outer</span><font color=3D"#666600"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; inner i0</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&lt;this&gt;</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">//i0::outer_this is implemented as a constexpr 0 byte of=
fset from i0::this</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>&nbsp; inner i1</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">&lt;this&gt;</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>//i1::outer_this is implemented as a constexpr -sizeof(i0) byte offset fro=
m i1::this</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>&nbsp; outer o0</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> o1</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br>&nbsp; o0</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">i0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> o1</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">i0</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: #800;" class=
=3D"styled-by-prettify">//Ok</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>&nbsp; o0</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">i1 </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> o=
1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">i1</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;=
" class=3D"styled-by-prettify">//Ok</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>&nbsp; o0</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">i0 </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> o1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">i1</span><s=
pan 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=
: #800;" class=3D"styled-by-prettify">//Error: outer::i0 and outer::i1 have=
 different types</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>&nbsp; o0</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
i1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> o1</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">i0</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">//Error: outer::i1 and outer::i0 have different types<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">}</span></font></=
div></code></div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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_71_475631506.1421902847653--
------=_Part_70_1349696281.1421902847653--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 21 Jan 2015 21:32:09 -0800 (PST)
Raw View
------=_Part_73_2090645772.1421904729302
Content-Type: multipart/alternative;
 boundary="----=_Part_74_356057790.1421904729303"

------=_Part_74_356057790.1421904729303
Content-Type: text/plain; charset=UTF-8

For further clarification and to serve as another example, if one were to
add a templated copy constructor, then they could copy different IDM's:

template <auto* outer_this> struct inner {
  template <auto* other_outer_this>
    inner<outer_this>& inner(const inner<other_outer_this>& other);
};
struct outer {
  inner i0<this>; //i0::outer_this is implemented as a constexpr 0 byte
offset from i0::this
  inner i1<this>; //i1::outer_this is implemented as a constexpr
-sizeof(i0) byte offset from i1::this
};

void foo() {
  outer o0, o1;

  o0.i0 = o1.i0; //Ok
  o0.i1 = o1.i1; //Ok
  o0.i0 = o1.i1; //Ok, uses templated copy constructor
  o0.i1 = o1.i0; //Ok, uses templated copy constructor
}

An intrusive linked list node data structure might look something like this:

template <auto* parent_ptr>
class ilist_node {
  public:
    using object_type = std::remove_reference_t<decltype(*parent_ptr)>;

    auto& object() { return *parent_ptr; }
    auto* next() { return _next; }
    auto* prev() { return _prev; }

    void append(ilist_node<parent_ptr>* node);
    void remove(ilist_node<parent_ptr>* node);
    ilist_node<parent_ptr>* find(const object_type& obj);
    template <typename F>
    ilist_node<parent_ptr>* find_if(F pred);


  private:
    ilist_node<parent_ptr>* _prev = nullptr;
    ilist_node<parent_ptr>* _next = nullptr;
};

struct Thing {
  //stuff...

  ilist_node<this> _list_0;
  ilist_node<this> _list_1;
};

I don't use linked lists often, but when I do its almost always a hand
rolled intrusive list because std::list is just unusably inefficient. Not
only does std::list allocate additional memory for each list node, its also
horribly cache inefficient. A std::list contains linked list nodes randomly
located in memory which point to objects which are also randomly located in
memory. An intrusive list cuts the number of random memory locations in
half by having each object directly point to the next one.


--

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

<div dir=3D"ltr">For further clarification and to serve as another example,=
 if one were to add a templated copy constructor, then they could copy diff=
erent IDM's:<div><br></div><div><div class=3D"prettyprint" style=3D"border:=
 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb=
(250, 250, 250);"><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 styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> outer_this</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> inner </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>&nbsp; </span><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">auto</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> other_outer_this</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>&nbsp; &nbsp; inner</span><=
span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;outer_this&gt;=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> inner</span><s=
pan style=3D"color: #660;" 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"> inner</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&lt;</span><font color=3D"#000000"><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">other_outer_this&gt=
;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> other</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span></font><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">};</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"> outer </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; inner i0</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">&lt;this&gt;</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: #800;" class=3D"style=
d-by-prettify">//i0::outer_this is implemented as a constexpr 0 byte offset=
 from i0::this</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>&nbsp; inner i1</span><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&lt;this&gt;</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//i=
1::outer_this is implemented as a constexpr -sizeof(i0) byte offset from i1=
::this</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>&nbsp; outer o0</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> o1</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; o0</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">i=
0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> o1</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">i0</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">//Ok</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>&nbsp; o0</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">i1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> o1</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">i1</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: #800;" cla=
ss=3D"styled-by-prettify">//Ok</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>&nbsp; o0</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">i0 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> o1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">i1</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: #8=
00;" class=3D"styled-by-prettify">//Ok, uses templated copy constructor</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; o0<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">i1 </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> o1</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">i0</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
/Ok, uses templated copy constructor</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span></div></code></div><font style=3D"font-family: =
monospace; font-size: 13.1428575515747px; background-color: rgb(250, 250, 2=
50);"><div style=3D"color: rgb(102, 102, 0);"><font color=3D"#666600" style=
=3D"font-family: monospace; font-size: 13.1428575515747px; background-color=
: rgb(250, 250, 250);"><br></font></div><div style=3D"color: rgb(102, 102, =
0);"><span style=3D"color: rgb(34, 34, 34); font-family: Arial, Helvetica, =
sans-serif; font-size: 13.1428575515747px; background-color: rgb(255, 255, =
255);">An intrusive linked list node data structure might look something li=
ke this:</span><font color=3D"#666600" style=3D"font-family: monospace; fon=
t-size: 13.1428575515747px; background-color: rgb(250, 250, 250);"><br></fo=
nt></div><div style=3D"color: rgb(102, 102, 0);"><span style=3D"color: rgb(=
34, 34, 34); font-family: Arial, Helvetica, sans-serif; font-size: 13.14285=
75515747px; background-color: rgb(255, 255, 255);"><br></span></div><div><s=
pan style=3D"font-family: Arial, Helvetica, sans-serif; font-size: 13.14285=
75515747px; background-color: rgb(255, 255, 255);"><div class=3D"prettyprin=
t" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; ba=
ckground-color: rgb(250, 250, 250);"><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">auto</span><fo=
nt color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">*</span></font><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> parent_ptr</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> ilist_node </=
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; </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">public</span><span s=
tyle=3D"color: #660;" 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">using</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> object_type </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">remove_reference_t</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(*</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">parent_ptr</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)&gt;;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">object</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"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">parent_ptr</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</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"><b=
r>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">next</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> _next</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> prev</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> _prev</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> append</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">ilist_node</span><span style=3D"=
color: #080;" class=3D"styled-by-prettify">&lt;parent_ptr&gt;</span><font c=
olor=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-prettify">=
*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> node</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">&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"> remove</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">ilist_node</span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">&lt;parent_ptr&gt;</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> node</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>&nbsp; &nbsp; ilist_node</span><span style=3D=
"color: #080;" class=3D"styled-by-prettify">&lt;parent_ptr&gt;</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> find</span><span style=3D"color=
: #660;" 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"> object_type</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> obj</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; &nbsp; </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">template</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ty=
pename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; =
ilist_node</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
&lt;parent_ptr&gt;</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
find_if</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">F pred</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; <br><b=
r>&nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">p=
rivate</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &n=
bsp; ilist_node</span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">&lt;parent_ptr&gt;</span><font color=3D"#666600"><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> _prev </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">nullptr</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span></font><span style=3D"color: #000;" class=3D"styled-by-prettify">&n=
bsp; &nbsp; ilist_node</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify">&lt;parent_ptr&gt;</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> _next </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">nullptr<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></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><br></span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Thing</span><font color=3D"#666600"><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: #800;"=
 class=3D"styled-by-prettify">//stuff...</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br><br>&nbsp; ilist_node</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;this&gt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> _list_0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>&nbsp; ilist_node</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">&lt;this&gt;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> _list_1</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></span></font><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">};</span></div></code></div><br>I =
don't use linked lists often, but when I do its almost always a hand rolled=
 intrusive list because std::list is just unusably inefficient. Not only do=
es std::list allocate additional memory for each list node, its also horrib=
ly cache inefficient. A std::list contains linked list nodes randomly locat=
ed in memory which point to objects which are also randomly located in memo=
ry. An intrusive list cuts the number of random memory locations in half by=
 having each object directly point to the next one.</span></div><br></font>=
<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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_74_356057790.1421904729303--
------=_Part_73_2090645772.1421904729302--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 21 Jan 2015 23:59:57 -0600
Raw View
--089e0118390e262aea050d376462
Content-Type: text/plain; charset=UTF-8

On 21 January 2015 at 23:32, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:

> Not only does std::list allocate additional memory for each list node, its
> also horribly cache inefficient. A std::list contains linked list nodes
> randomly located in memory which point to objects which are also randomly
> located in memory.


What STL version has ever done that?

For instance, in libstdc++, the user's data is embedded in the list node.
I'd be very surprised at any implementation which didn't do that, so please
share.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra">On 21 January 2015 at 23:32, Ma=
tthew Fioravante <span dir=3D"ltr">&lt;<a href=3D"mailto:fmatthew5876@gmail=
..com" target=3D"_blank">fmatthew5876@gmail.com</a>&gt;</span> wrote:<br><di=
v class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Not only does std::l=
ist allocate additional memory for each list node, its also horribly cache =
inefficient. A std::list contains linked list nodes randomly located in mem=
ory which point to objects which are also randomly located in memory.</bloc=
kquote></div><br>What STL version has ever done that?</div><div class=3D"gm=
ail_extra"><br></div><div class=3D"gmail_extra">For instance, in libstdc++,=
 the user&#39;s data is embedded in the list node.=C2=A0 I&#39;d be very su=
rprised at any implementation which didn&#39;t do that, so please share.</d=
iv><div class=3D"gmail_extra">--=C2=A0<br></div><div class=3D"gmail_extra">=
<div class=3D"gmail_signature">=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;=
mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@ev=
iloverlord.com</a>&gt;=C2=A0 (847) 691-1404</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 />

--089e0118390e262aea050d376462--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 22 Jan 2015 00:01:41 -0600
Raw View
--001a1139fd464ba7a5050d376a0b
Content-Type: text/plain; charset=UTF-8

On 21 January 2015 at 23:00, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:

> My real motivating case is for the Intrusive data members to implement
> intrusive data structures such as the linked lists used in the linux kernel
> and other C projects via macros.


And I thought the reason that C++ isn't used in the kernel was because
Linus Torvalds hates C++.  Ah well, live and learn...


--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On 21 January 2015 at 23:00, Matthew Fioravante <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.c=
om</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">My real motivati=
ng case is for the Intrusive data members to implement intrusive data struc=
tures such as the linked lists used in the linux kernel and other C project=
s via macros.</blockquote></div><br>And I thought the reason that C++ isn&#=
39;t used in the kernel was because Linus Torvalds hates C++.=C2=A0 Ah well=
, live and learn...<br><br clear=3D"all"><div><br></div>-- <br><div class=
=3D"gmail_signature">=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></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 />

--001a1139fd464ba7a5050d376a0b--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 22 Jan 2015 14:07:55 +0800
Raw View
--Apple-Mail=_8E92FA3D-A0D9-4E10-ADE9-6490AD568043
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9301=E2=80=9322, at 1:00 PM, Matthew Fioravante <fmatthew58=
76@gmail.com> wrote:
>=20
> References can only be "storage free" with the help of an inlining optimi=
zer.=20

The same applies to your proposal. To find a local in a calling frame, eith=
er the evaluation has to occur in an inlined context, or there needs to be =
an indirection.

>   int x; //Located at address 0 from stack ptr
>   xy xy0<x>; //Located at address 4
>   xy xy1<x>; //Located at address 8
>=20
>   xy0.sum() //Compiles as: add this->y and the integer 4 bytes before thi=
s
>   xy1.sum() //Compiles as: add this->y and the integer 8 bytes before thi=
s

This arithmetic works because the object can never be moved. It would also =
work for a lambda that hasn=E2=80=99t been moved. If the analysis is so ben=
eficial, the compiler could do it with lambda closures, by keeping track of=
 whether a given closure is the original one in the calling frame or one th=
at was passed by value.

I don=E2=80=99t think there=E2=80=99s more expressiveness here than would b=
e achievable in an attribute [[local_identity]] attached to a lambda, which=
 would encourage the compiler to avoid reference member storage and complai=
n if a copy/move occurs.

By the way, I=E2=80=99ve mentioned this implementation style to implementer=
s a few times, but the response tends to be that lambdas are fast enough al=
ready. A related notion, not exactly the same, is that there should be some=
 concrete best practices to keep lambdas small and prevent capture bloat: h=
ttp://stackoverflow.com/q/24303079/153285 <http://stackoverflow.com/q/24303=
079/153285> .

> My real motivating case is for the Intrusive data members to implement in=
trusive data structures such as the linked lists used in the linux kernel a=
nd other C projects via macros.

=E2=80=9CCasting=E2=80=9D a data payload to the enclosing list node is a pr=
oblem, and Melissa mentioned it recently too. If that=E2=80=99s going to be=
 solved, I think it should be done without templates though.

> CRTP requires inheritance. This feature is about composition. Unless I mi=
sunderstood, I don't believe your paper allows a data member of a class to =
access another data member without the use of a pointer or reference.=20

My paper allows any arbitrary computation. If offsetof works, you can use t=
hat.

There was a proposal to add pointer-to-member operators, such as negation w=
hich would produce an inverse PTM, which you could call an MTP: (&this->mem=
) ->* (- &foo::mem) would yield this. As far as I know, this is the preferr=
ed direction of offsetof evolution, which is to say EWG expressed not much =
disgust but neither much interest.

The idea is mentioned in N0496 (from 1994), and I recall a somewhat recent =
paper that went crazy and defined about a half-dozen operators, but I can=
=E2=80=99t find it now.

> You can't change the referent since it is encoded within the type and not=
 stored anywhere. You can only copy an IDM of the same type from one instan=
ce of the outer class to another. Maybe the following example would make mo=
re sense.
>=20
> template <auto* outer_this> struct inner {};
> struct outer {
>   inner i0<this>; //i0::outer_this is implemented as a constexpr 0 byte o=
ffset from i0::this
>   inner i1<this>; //i1::outer_this is implemented as a constexpr -sizeof(=
i0) byte offset from i1::this
> };
>=20
> void foo() {
>   outer o0, o1;
>=20
>   o0.i0 =3D o1.i0; //Ok

But what does this do?

--=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=_8E92FA3D-A0D9-4E10-ADE9-6490AD568043
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9301=
=E2=80=9322, at 1:00 PM, Matthew Fioravante &lt;<a href=3D"mailto:fmatthew5=
876@gmail.com" class=3D"">fmatthew5876@gmail.com</a>&gt; wrote:</div><br cl=
ass=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" style=3D=
"font-family: Helvetica; font-size: 12px; font-style: normal; font-variant:=
 normal; font-weight: normal; letter-spacing: normal; line-height: normal; =
orphans: auto; text-align: start; text-indent: 0px; text-transform: none; w=
hite-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-wi=
dth: 0px;" class=3D"">References can only be "storage free" with the help o=
f an inlining optimizer.&nbsp;</div></div></blockquote><div><br class=3D"">=
</div><div>The same applies to your proposal. To find a local in a calling =
frame, either the evaluation has to occur in an inlined context, or there n=
eeds to be an indirection.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; =
font-size: 12px; font-style: normal; font-variant: normal; font-weight: nor=
mal; letter-spacing: normal; line-height: normal; orphans: auto; text-align=
: start; text-indent: 0px; text-transform: none; white-space: normal; widow=
s: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><di=
v class=3D""><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,=
 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><=
code class=3D"prettyprint"><font color=3D"#666600" class=3D""><span class=
=3D"styled-by-prettify" style=3D"">&nbsp;<span class=3D"Apple-converted-spa=
ce">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: =
rgb(0, 0, 136);">int</span><span class=3D"styled-by-prettify" style=3D""><s=
pan class=3D"Apple-converted-space">&nbsp;</span>x</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span class=3D"=
styled-by-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;=
</span></span><span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0=
, 0);">//Located at address 0 from stack ptr</span><span class=3D"styled-by=
-prettify" style=3D""><br class=3D"">&nbsp; xy xy0</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(0, 136, 0);">&lt;x&gt;</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span =
class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-spac=
e">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: r=
gb(136, 0, 0);">//Located at address 4</span><span class=3D"styled-by-prett=
ify" style=3D""><br class=3D"">&nbsp; xy xy1</span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(0, 136, 0);">&lt;x&gt;</span><span class=3D"=
styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span class=
=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-space">&n=
bsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: rgb(13=
6, 0, 0);">//Located at address 8</span><span class=3D"styled-by-prettify" =
style=3D""><br class=3D""><br class=3D"">&nbsp; xy0</span><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(102, 102, 0);">.</span><span class=3D=
"styled-by-prettify" style=3D"">sum</span><span class=3D"styled-by-prettify=
" style=3D"color: rgb(102, 102, 0);">()</span><span class=3D"styled-by-pret=
tify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span></span>=
<span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0, 0);">//Compi=
les as: add this-&gt;y and the integer 4 bytes before this</span><span clas=
s=3D"styled-by-prettify" style=3D""><br class=3D"">&nbsp; xy1</span><span c=
lass=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">.</span><spa=
n class=3D"styled-by-prettify" style=3D"">sum</span><span class=3D"styled-b=
y-prettify" style=3D"color: rgb(102, 102, 0);">()</span><span class=3D"styl=
ed-by-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</sp=
an></span><span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0, 0)=
;">//Compiles as: add this-&gt;y and the integer 8 bytes before this</span>=
<span class=3D"styled-by-prettify" style=3D""><br class=3D""></span></font>=
</code></div></div></div></div></blockquote><div><br class=3D""></div><div>=
This arithmetic works because the object can never be moved. It would also =
work for a lambda that hasn=E2=80=99t been moved. If the analysis is so ben=
eficial, the compiler could do it with lambda closures, by keeping track of=
 whether a given closure is the original one in the calling frame or one th=
at was passed by value.</div><div><br class=3D""></div><div>I don=E2=80=99t=
 think there=E2=80=99s more expressiveness here than would be achievable in=
 an attribute <font face=3D"Courier" class=3D"">[[local_identity]]</font> a=
ttached to a lambda, which would encourage the compiler to avoid reference =
member storage and complain if a copy/move occurs.</div><div><br class=3D""=
></div><div>By the way, I=E2=80=99ve mentioned this implementation style to=
 implementers a few times, but the response tends to be that lambdas are fa=
st enough already. A related notion, not exactly the same, is that there sh=
ould be some concrete best practices to keep lambdas small and prevent capt=
ure bloat:&nbsp;<a href=3D"http://stackoverflow.com/q/24303079/153285" clas=
s=3D"">http://stackoverflow.com/q/24303079/153285</a>&nbsp;.</div><br class=
=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr"=
 style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font=
-variant: normal; font-weight: normal; letter-spacing: normal; line-height:=
 normal; orphans: auto; text-align: start; text-indent: 0px; text-transform=
: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-=
stroke-width: 0px;" class=3D""><div class=3D"">My real motivating case is f=
or the Intrusive data members to implement intrusive data structures such a=
s the linked lists used in the linux kernel and other C projects via macros=
..</div></div></div></blockquote><div><br class=3D""></div><div>=E2=80=9CCas=
ting=E2=80=9D a data payload to the enclosing list node is a problem, and M=
elissa mentioned it recently too. If that=E2=80=99s going to be solved, I t=
hink it should be done without templates though.</div><br class=3D""><block=
quote type=3D"cite" class=3D""><div dir=3D"ltr" style=3D"font-family: Helve=
tica; font-size: 12px; font-style: normal; font-variant: normal; font-weigh=
t: normal; letter-spacing: normal; line-height: normal; orphans: auto; text=
-align: start; text-indent: 0px; text-transform: none; white-space: normal;=
 widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D=
""><div class=3D"">CRTP requires inheritance. This feature is about composi=
tion. Unless I misunderstood, I don't believe your paper allows a data memb=
er of a class to access another data member without the use of a pointer or=
 reference.&nbsp;</div></div></blockquote><div><br class=3D""></div><div>My=
 paper allows any arbitrary computation. If <font face=3D"Courier" class=3D=
"">offsetof</font> works, you can use that.</div><div><br class=3D""></div>=
<div>There was a proposal to add pointer-to-member operators, such as negat=
ion which would produce an inverse PTM, which you could call an MTP: <font =
face=3D"Courier" class=3D"">(&amp;this-&gt;mem) -&gt;* (- &amp;foo::mem)</f=
ont> would yield <font face=3D"Courier" class=3D"">this</font>. As far as I=
 know, this is the preferred direction of <font face=3D"Courier" class=3D""=
>offsetof</font> evolution, which is to say EWG expressed not much disgust =
but neither much interest.</div><div><br class=3D""></div><div>The idea is =
mentioned in N0496 (from 1994), and I recall a somewhat recent paper that w=
ent crazy and defined about a half-dozen operators, but I can=E2=80=99t fin=
d it now.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div dir=
=3D"ltr" style=3D"font-family: Helvetica; font-size: 12px; font-style: norm=
al; font-variant: normal; font-weight: normal; letter-spacing: normal; line=
-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-t=
ransform: none; white-space: normal; widows: auto; word-spacing: 0px; -webk=
it-text-stroke-width: 0px;" class=3D""><div class=3D"">You can't change the=
 referent since it is encoded within the type and not stored anywhere. You =
can only copy an IDM of the same type from one instance of the outer class =
to another. Maybe the following example would make more sense.</div></div><=
/blockquote><blockquote type=3D"cite" class=3D""><div dir=3D"ltr" style=3D"=
font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: =
normal; font-weight: normal; letter-spacing: normal; line-height: normal; o=
rphans: auto; text-align: start; text-indent: 0px; text-transform: none; wh=
ite-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-wid=
th: 0px;" class=3D""><div class=3D""><br class=3D""></div><div class=3D""><=
div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); wo=
rd-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"=
prettyprint"><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 1=
36);">template</span>&nbsp;<span class=3D"styled-by-prettify" style=3D"colo=
r: rgb(102, 102, 0);">&lt;</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(0, 0, 136);">auto</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: rgb(102, 102, 0);">*</span><span class=3D"Apple-converted-sp=
ace">&nbsp;</span>outer_this<span class=3D"styled-by-prettify" style=3D"col=
or: rgb(102, 102, 0);">&gt;</span>&nbsp;<span class=3D"styled-by-prettify" =
style=3D"color: rgb(0, 0, 136);">struct</span><span class=3D"styled-by-pret=
tify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span>inner<s=
pan class=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styl=
ed-by-prettify" style=3D"color: rgb(102, 102, 0);">{};</span><br class=3D""=
><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">struct=
</span><span class=3D"Apple-converted-space">&nbsp;</span>outer<font color=
=3D"#666600" class=3D""><span class=3D"styled-by-prettify" style=3D""><span=
 class=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-=
by-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span class=3D"styl=
ed-by-prettify" style=3D""><br class=3D"">&nbsp; inner i0</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(0, 136, 0);">&lt;this&gt;</span=
><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</s=
pan><span class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-conv=
erted-space">&nbsp;</span></span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(136, 0, 0);">//i0::outer_this is implemented as a constexpr =
0 byte offset from i0::this</span><span class=3D"styled-by-prettify" style=
=3D""><br class=3D"">&nbsp; inner i1</span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(0, 136, 0);">&lt;this&gt;</span><span class=3D"style=
d-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span class=3D"st=
yled-by-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</=
span></span><span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0, =
0);">//i1::outer_this is implemented as a constexpr -sizeof(i0) byte offset=
 from i1::this</span><span class=3D"styled-by-prettify" style=3D""><br clas=
s=3D""></span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 1=
02, 0);">};</span><span class=3D"styled-by-prettify" style=3D""><br class=
=3D""><br class=3D""></span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(0, 0, 136);">void</span><span class=3D"styled-by-prettify" style=3D=
""><span class=3D"Apple-converted-space">&nbsp;</span>foo</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">()</span><span c=
lass=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-space=
">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: rg=
b(102, 102, 0);">{</span><span class=3D"styled-by-prettify" style=3D""><br =
class=3D"">&nbsp; outer o0</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(102, 102, 0);">,</span><span class=3D"styled-by-prettify" st=
yle=3D""><span class=3D"Apple-converted-space">&nbsp;</span>o1</span><span =
class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><sp=
an class=3D"styled-by-prettify" style=3D""><br class=3D""><br class=3D"">&n=
bsp; o0</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 1=
02, 0);">.</span><span class=3D"styled-by-prettify" style=3D"">i0<span clas=
s=3D"Apple-converted-space">&nbsp;</span></span><span class=3D"styled-by-pr=
ettify" style=3D"color: rgb(102, 102, 0);">=3D</span><span class=3D"styled-=
by-prettify" style=3D""><span class=3D"Apple-converted-space">&nbsp;</span>=
o1</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0=
);">.</span><span class=3D"styled-by-prettify" style=3D"">i0</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">;</span><span=
 class=3D"styled-by-prettify" style=3D""><span class=3D"Apple-converted-spa=
ce">&nbsp;</span></span><span class=3D"styled-by-prettify" style=3D"color: =
rgb(136, 0, 0);">//Ok</span><span class=3D"styled-by-prettify" style=3D""><=
br class=3D""></span></font></code></div></div></div></blockquote><div><br =
class=3D""></div><div>But what does this do?</div></div></body></html>

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

--Apple-Mail=_8E92FA3D-A0D9-4E10-ADE9-6490AD568043--

.


Author: David Krauss <potswa@gmail.com>
Date: Thu, 22 Jan 2015 14:15:15 +0800
Raw View
--Apple-Mail=_35D15979-D637-41EC-9AD8-1D18A0080EC8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9301=E2=80=9322, at 1:32 PM, Matthew Fioravante <fmatthew58=
76@gmail.com> wrote:
>=20
> I don't use linked lists often, but when I do its almost always a hand ro=
lled intrusive list because std::list is just unusably inefficient. Not onl=
y does std::list allocate additional memory for each list node, its also ho=
rribly cache inefficient. A std::list contains linked list nodes randomly l=
ocated in memory which point to objects which are also randomly located in =
memory. An intrusive list cuts the number of random memory locations in hal=
f by having each object directly point to the next one.

std::list is intrusive, in that the template argument type intrudes into th=
e standard library implementation. As Nevin says, the pointers and your dat=
a are in one allocation block. De-randomizing allocations is a job for an a=
llocator :) .

There is boost::intrusive_list and I seem to recall a proposal for intrusiv=
e equivalents to the current standard containers. No extra pointers are nee=
ded if the intrusive implementation keeps track of parent pointers and uses=
 a pointer-to-member to find its links within any given parent. That=E2=80=
=99s also more natural, IMHO, than linking to the internal pointer and then=
 using subtraction to find the parent.

--=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=_35D15979-D637-41EC-9AD8-1D18A0080EC8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9301=
=E2=80=9322, at 1:32 PM, Matthew Fioravante &lt;<a href=3D"mailto:fmatthew5=
876@gmail.com" class=3D"">fmatthew5876@gmail.com</a>&gt; wrote:</div><br cl=
ass=3D"Apple-interchange-newline"><div class=3D""><span style=3D"font-famil=
y: Arial, Helvetica, sans-serif; font-size: 13px; font-style: normal; font-=
variant: normal; font-weight: normal; letter-spacing: normal; line-height: =
normal; orphans: auto; text-align: start; text-indent: 0px; text-transform:=
 none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-s=
troke-width: 0px; background-color: rgb(255, 255, 255); float: none; displa=
y: inline !important;" class=3D"">I don't use linked lists often, but when =
I do its almost always a hand rolled intrusive list because std::list is ju=
st unusably inefficient. Not only does std::list allocate additional memory=
 for each list node, its also horribly cache inefficient. A std::list conta=
ins linked list nodes randomly located in memory which point to objects whi=
ch are also randomly located in memory. An intrusive list cuts the number o=
f random memory locations in half by having each object directly point to t=
he next one.</span></div></blockquote></div><br class=3D""><div class=3D"">=
<font face=3D"Courier" class=3D"">std::list</font> is intrusive, in that th=
e template argument type intrudes into the standard library implementation.=
 As Nevin says, the pointers and your data are in one allocation block. De-=
randomizing allocations is a job for an allocator :) .</div><div class=3D""=
><br class=3D""></div><div class=3D"">There is <font face=3D"Courier" class=
=3D"">boost::intrusive_list</font> and I seem to recall a proposal for intr=
usive equivalents to the current standard containers. No extra pointers are=
 needed if the intrusive implementation keeps track of parent pointers and =
uses a pointer-to-member to find its links within any given parent. That=E2=
=80=99s also more natural, IMHO, than linking to the internal pointer and t=
hen using subtraction to find the parent.</div></body></html>

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

--Apple-Mail=_35D15979-D637-41EC-9AD8-1D18A0080EC8--

.


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 22 Jan 2015 09:32:18 -0800 (PST)
Raw View
------=_Part_140_1018248219.1421947938639
Content-Type: multipart/alternative;
 boundary="----=_Part_141_400633790.1421947938639"

------=_Part_141_400633790.1421947938639
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable


On Thursday, January 22, 2015 at 1:08:07 AM UTC-5, David Krauss wrote:
>
> I don=E2=80=99t think there=E2=80=99s more expressiveness here than would=
 be achievable in=20
> an attribute [[local_identity]] attached to a lambda, which would=20
> encourage the compiler to avoid reference member storage and complain if =
a=20
> copy/move occurs.
> =20
>
=20
You're probably right about that. Anyway as mentioned before the real use=
=20
case is for data members, not local variables. Let's drop ILV for now in=20
favor of lambdas.
=20

> By the way, I=E2=80=99ve mentioned this implementation style to implement=
ers a few=20
> times, but the response tends to be that lambdas are fast enough already.=
 A=20
> related notion, not exactly the same, is that there should be some concre=
te=20
> best practices to keep lambdas small and prevent capture bloat:=20
> http://stackoverflow.com/q/24303079/153285=20
> <http://www.google.com/url?q=3Dhttp%3A%2F%2Fstackoverflow.com%2Fq%2F24303=
079%2F153285&sa=3DD&sntz=3D1&usg=3DAFQjCNFgXcbRd6CpF5s782OUS5G0pRNsmg>
>  .
>
=20
If the lambda only stores a pointer to the stack frame, it can use compile=
=20
time offsets to reference all of the local variables. I believe such an=20
implementation is possible today no?=20
=20

> My real motivating case is for the Intrusive data members to implement=20
> intrusive data structures such as the linked lists used in the linux kern=
el=20
> and other C projects via macros.
>
>
> =E2=80=9CCasting=E2=80=9D a data payload to the enclosing list node is a =
problem, and=20
> Melissa mentioned it recently too. If that=E2=80=99s going to be solved, =
I think it=20
> should be done without templates though.
>
=20
Storing an object in multiple lists is another problem.=20

> There was a proposal to add pointer-to-member operators, such as negation=
=20
> which would produce an inverse PTM, which you could call an MTP: (&this->=
mem)=20
> ->* (- &foo::mem) would yield this. As far as I know, this is the=20
> preferred direction of offsetof evolution, which is to say EWG expressed=
=20
> not much disgust but neither much interest.
> =20
>
=20
Using inverse pointer to member or some other mechanism like offsetof() as=
=20
the template argument might be better. The below code is confusing because=
=20
a and b look like they should have the same type.
=20
template <auto* outer_this> inner {}

struct outer {
  inner<this> a;
  inner<this> b;
};
=20
Using some kind of negated pointer to member or offsetof() kind of magic=20
makes it obvious that x and y have different types.
=20
template <auto* outer_this> inner {
};

struct outer {
  inner<-&outer::x> x;
  inner<-&outer::y> y;
};
=20
There is a ordering problem with my idea. We're asking the compiler to=20
refer to x in the template parameter before x is actually declared and=20
declaring x requires evaluating all of the template parameters first.=20
=20
To do this, the compiler would need to first determine the size and=20
alignment of x without knowing the value of template parameter outer_this=
=20
which I'm not sure is possible. There would have to be a lot of=20
restrictions placed on the template specialization so that the data layout=
=20
of the inner type can never change depending on the value of outer_this.
=20

> The idea is mentioned in N0496 (from 1994), and I recall a somewhat recen=
t=20
> paper that went crazy and defined about a half-dozen operators, but I can=
=E2=80=99t=20
> find it now.
>
> You can't change the referent since it is encoded within the type and not=
=20
> stored anywhere. You can only copy an IDM of the same type from one=20
> instance of the outer class to another. Maybe the following example would=
=20
> make more sense.
>
>
> template <auto* outer_this> struct inner {};
> struct outer {
>   inner i0<this>; //i0::outer_this is implemented as a constexpr 0 byte=
=20
> offset from i0::this
>   inner i1<this>; //i1::outer_this is implemented as a constexpr=20
> -sizeof(i0) byte offset from i1::this
> };
>
> void foo() {
>   outer o0, o1;
>
>   o0.i0 =3D o1.i0; //Ok
>
>
> But what does this do?
>
=20
It calls the copy constructor of decltype(outer::i0). Both o0.i0 and o1.i0=
=20
have the same constant offset from inner::this to outer::this so the local=
=20
state of inner can be freely copied from one outer::inner instance to=20
another.
=20
=20
Here is another use case involving shared external state without internal=
=20
references.
=20
//Assumptions:
//optional<T> is implemented as struct { T t; bool b; }
//sizeof(T*) =3D=3D 8
//sizeof(bool) =3D=3D 1
//sizeof(bitset<N>) =3D=3D 8 when N <=3D 64
//A cache line on this platform is 64 bytes

struct X { /* stuff */};

struct A {
  optional<X*> a;
  optional<X*> b;
  optional<X*> c;
  optional<X*> d;
};

static_assert(sizeof(A) =3D=3D 64);
//A contains 4 optionals, which fill an entire cache line
//7 * 4 =3D 28 bytes are wasted padding the bools for each optional

//Similar to optional, except it uses the specified bit from bits
//to store the active state
//sizeof(bit_optional<T,...> =3D=3D sizeof(T)
template <typename T, size_t bit, auto& bits>
class bit_optional { /* ... */ }
struct B {
private:
  bitset<7> _bits;
public:
  bit_optional<X*,0,_bits> a;
  bit_optional<X*,1,_bits> b;
  bit_optional<X*,2,_bits> c;
  bit_optional<X*,3,_bits> d;
  bit_optional<X*,4,_bits> e;
  bit_optional<X*,5,_bits> f;
  bit_optional<X*,6,_bits> g;
};

static_assert(sizeof(B) =3D=3D 64);
//B fits into a single cache line but now we can store 7 optionals instead=
=20
of only 4.


=20
In the above example, struct B has much more compact storage than A and can=
=20
fit a lot more data onto a single cache line.

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

<div dir=3D"ltr"><br>On Thursday, January 22, 2015 at 1:08:07 AM UTC-5, Dav=
id Krauss wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-lef=
t: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; bord=
er-left-style: solid;" class=3D"gmail_quote"><div style=3D"word-wrap: break=
-word;"><div><div>I don=E2=80=99t think there=E2=80=99s more expressiveness=
 here than would be achievable in an attribute <font face=3D"Courier">[[loc=
al_identity]]</font> attached to a lambda, which would encourage the compil=
er to avoid reference member storage and complain if a copy/move occurs.</d=
iv><div>&nbsp;</div></div></div></blockquote><div>&nbsp;</div><div>You're p=
robably right about that. Anyway as mentioned before the real use case is f=
or data members, not local variables. Let's drop ILV for now in favor of la=
mbdas.</div><div>&nbsp;</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex=
; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wid=
th: 1px; border-left-style: solid;" class=3D"gmail_quote"><div style=3D"wor=
d-wrap: break-word;"><div><div></div><div>By the way, I=E2=80=99ve mentione=
d this implementation style to implementers a few times, but the response t=
ends to be that lambdas are fast enough already. A related notion, not exac=
tly the same, is that there should be some concrete best practices to keep =
lambdas small and prevent capture bloat:&nbsp;<a onmousedown=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fstackoverflow.com%2Fq%2F2430=
3079%2F153285\46sa\75D\46sntz\0751\46usg\75AFQjCNFgXcbRd6CpF5s782OUS5G0pRNs=
mg';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75htt=
p%3A%2F%2Fstackoverflow.com%2Fq%2F24303079%2F153285\46sa\75D\46sntz\0751\46=
usg\75AFQjCNFgXcbRd6CpF5s782OUS5G0pRNsmg';return true;" href=3D"http://www.=
google.com/url?q=3Dhttp%3A%2F%2Fstackoverflow.com%2Fq%2F24303079%2F153285&a=
mp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNFgXcbRd6CpF5s782OUS5G0pRNsmg" rel=3D=
"nofollow" target=3D"_blank">http://stackoverflow.<wbr>com/q/24303079/15328=
5</a>&nbsp;.</div></div></div></blockquote><div>&nbsp;</div><div>If the lam=
bda only stores a pointer to the stack frame, it can use compile time offse=
ts to reference all of the local variables. I&nbsp;believe such an implemen=
tation is possible today no?&nbsp;</div><div>&nbsp;</div><blockquote style=
=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(20=
4, 204, 204); border-left-width: 1px; border-left-style: solid;" class=3D"g=
mail_quote"><div style=3D"word-wrap: break-word;"><div><blockquote type=3D"=
cite"><div><div style=3D"font: 12px/normal Helvetica; text-transform: none;=
 text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: =
normal; font-size-adjust: none; font-stretch: normal;" dir=3D"ltr"><div>My =
real motivating case is for the Intrusive data members to implement intrusi=
ve data structures such as the linked lists used in the linux kernel and ot=
her C projects via macros.</div></div></div></blockquote><div><br></div><di=
v>=E2=80=9CCasting=E2=80=9D a data payload to the enclosing list node is a =
problem, and Melissa mentioned it recently too. If that=E2=80=99s going to =
be solved, I think it should be done without templates though.</div></div><=
/div></blockquote><div>&nbsp;</div><div>Storing an object in multiple lists=
 is another problem. <br></div><blockquote style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;" class=3D"gmail_quote"><div style=3D"w=
ord-wrap: break-word;"><div><div>There was a proposal to add pointer-to-mem=
ber operators, such as negation which would produce an inverse PTM, which y=
ou could call an MTP: <font face=3D"Courier">(&amp;this-&gt;mem) -&gt;* (- =
&amp;foo::mem)</font> would yield <font face=3D"Courier">this</font>. As fa=
r as I know, this is the preferred direction of <font face=3D"Courier">offs=
etof</font> evolution, which is to say EWG expressed not much disgust but n=
either much interest.</div><div>&nbsp;</div></div></div></blockquote><div>&=
nbsp;</div><div>Using inverse pointer to member or some other mechanism lik=
e offsetof()&nbsp;as the template argument might be better. The below code =
is confusing because a and b look like they should have the same type.</div=
><div><code class=3D"prettyprint">&nbsp;</code></div><code class=3D"prettyp=
rint"><div><div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: b=
reak-word; background-color: rgb(250, 250, 250);" class=3D"prettyprint"><di=
v class=3D"subprettyprint"><div style=3D"border: 1px solid rgb(187, 187, 18=
7); word-wrap: break-word; background-color: rgb(250, 250, 250);" class=3D"=
prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">*</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"> outer_this</span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> inner </span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">{}</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: rgb(0=
, 0, 136);" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 rgb(0, 0, 0);" class=3D"styled-by-prettify"> outer </span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp; inner</sp=
an><span style=3D"color: rgb(0, 136, 0);" class=3D"styled-by-prettify">&lt;=
this&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pret=
tify"> a</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-=
prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"><br>&nbsp; inner</span><span style=3D"color: rgb(0, 136, 0);" clas=
s=3D"styled-by-prettify">&lt;this&gt;</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify"> b</span><span style=3D"color: rgb(102, =
102, 0);" class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">};</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span></div></code><font c=
olor=3D"#880000"></font></div></div></div></div></code><div><div style=3D"b=
order: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-colo=
r: rgb(250, 250, 250);" class=3D"prettyprint"></div></div><div>&nbsp;</div>=
<div>Using&nbsp;some kind of negated&nbsp;pointer to member or offsetof() k=
ind of magic makes it&nbsp;obvious that x and y have different types.</div>=
<div>&nbsp;</div><div style=3D"border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word; background-color: rgb(250, 250, 250);" class=3D"prettyprin=
t"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">template</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">auto</sp=
an><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*<=
/span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> ou=
ter_this</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-=
prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-b=
y-prettify"> inner </span><span style=3D"color: rgb(102, 102, 0);" class=3D=
"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=3D"styled-by-prettify"><br><br></span><span style=3D"color: rgb(0, 0, 13=
6);" class=3D"styled-by-prettify">struct</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"> outer </span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"color=
: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp; inner</span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;-&amp;<=
/span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">out=
er</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy">x</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"> x</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-=
by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-b=
y-prettify"><br>&nbsp; inner</span><span style=3D"color: rgb(102, 102, 0);"=
 class=3D"styled-by-prettify">&lt;-&amp;</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify">outer</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">::</span><span style=3D"color:=
 rgb(0, 0, 0);" class=3D"styled-by-prettify">y</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> y</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span><span=
 style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span></d=
iv></code></div><div>&nbsp;</div><div>There is&nbsp;a ordering problem with=
 my idea. We're asking the compiler to refer to x in the template parameter=
 before x is actually declared and declaring x requires evaluating all of t=
he template parameters first. </div><div>&nbsp;</div><div>To do this,&nbsp;=
the compiler would need to first determine the size and alignment of x with=
out knowing the value of&nbsp;template parameter outer_this which I'm not s=
ure is possible. There would have to be a lot of restrictions placed on the=
 template specialization so that the data layout of the inner type can neve=
r change depending on the value of outer_this.</div><div>&nbsp;</div><block=
quote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-co=
lor: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"=
 class=3D"gmail_quote"><div style=3D"word-wrap: break-word;"><div><div></di=
v><div>The idea is mentioned in N0496 (from 1994), and I recall a somewhat =
recent paper that went crazy and defined about a half-dozen operators, but =
I can=E2=80=99t find it now.</div><br><blockquote type=3D"cite"><div style=
=3D"font: 12px/normal Helvetica; text-transform: none; text-indent: 0px; le=
tter-spacing: normal; word-spacing: 0px; white-space: normal; font-size-adj=
ust: none; font-stretch: normal;" dir=3D"ltr"><div>You can't change the ref=
erent since it is encoded within the type and not stored anywhere. You can =
only copy an IDM of the same type from one instance of the outer class to a=
nother. Maybe the following example would make more sense.</div></div></blo=
ckquote><blockquote type=3D"cite"><div style=3D"font: 12px/normal Helvetica=
; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spac=
ing: 0px; white-space: normal; font-size-adjust: none; font-stretch: normal=
;" dir=3D"ltr"><div><br></div><div><div style=3D"border: 1px solid rgb(187,=
 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><=
code><span style=3D"color: rgb(0, 0, 136);">template</span>&nbsp;<span styl=
e=3D"color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 1=
36);">auto</span><span style=3D"color: rgb(102, 102, 0);">*</span><span>&nb=
sp;</span>outer_this<span style=3D"color: rgb(102, 102, 0);">&gt;</span>&nb=
sp;<span style=3D"color: rgb(0, 0, 136);">st<wbr>ruct</span><span><span>&nb=
sp;</span>inner<span>&nbsp;</span></span><span style=3D"color: rgb(102, 102=
, 0);">{};</span><br><span style=3D"color: rgb(0, 0, 136);">struct</span><s=
pan>&nbsp;</span>outer<font color=3D"#666600"><span><span>&nbsp;</span></sp=
an><span style=3D"color: rgb(102, 102, 0);">{</span><span><br>&nbsp; inner =
i0</span><span style=3D"color: rgb(0, 136, 0);">&lt;this&gt;</span><span st=
yle=3D"color: rgb(102, 102, 0);">;</span><span><span>&nbsp;</span></span><s=
pan style=3D"color: rgb(136, 0, 0);">//i0::outer_this is implemented as a c=
onstexpr 0 byte offset from i0::this</span><span><br>&nbsp; inner i1</span>=
<span style=3D"color: rgb(0, 136, 0);">&lt;this&gt;</span><span style=3D"co=
lor: rgb(102, 102, 0);">;</span><span><span>&nbsp;</span></span><span style=
=3D"color: rgb(136, 0, 0);">//i1::outer_this is implemented as a constexpr =
-sizeof(i0) byte offset from i1::this</span><span><br></span><span style=3D=
"color: rgb(102, 102, 0);">};</span><span><br><br></span><span style=3D"col=
or: rgb(0, 0, 136);">void</span><span><span>&nbsp;</span>foo</span><span st=
yle=3D"color: rgb(102, 102, 0);">()</span><span><span>&nbsp;</span></span><=
span style=3D"color: rgb(102, 102, 0);">{</span><span><br>&nbsp; outer o0</=
span><span style=3D"color: rgb(102, 102, 0);">,</span><span><span>&nbsp;</s=
pan>o1</span><span style=3D"color: rgb(102, 102, 0);">;</span><span><br><br=
>&nbsp; o0</span><span style=3D"color: rgb(102, 102, 0);">.</span><span>i0<=
span>&nbsp;</span></span><span style=3D"color: rgb(102, 102, 0);">=3D</span=
><span><span>&nbsp;</span>o1</span><span style=3D"color: rgb(102, 102, 0);"=
>.</span><span>i0</span><span style=3D"color: rgb(102, 102, 0);">;</span><s=
pan><span>&nbsp;</span></span><span style=3D"color: rgb(136, 0, 0);">//Ok</=
span><span><br></span></font></code></div></div></div></blockquote><div><br=
></div><div>But what does this do?</div></div></div></blockquote><div>&nbsp=
;</div><div>It calls the copy constructor of&nbsp;decltype(outer::i0). Both=
 o0.i0 and o1.i0 have the same&nbsp;constant offset from inner::this to out=
er::this&nbsp;so the local state of inner&nbsp;can be freely copied from on=
e outer::inner instance&nbsp;to another.</div><div>&nbsp;</div><div>&nbsp;<=
/div><div>Here is another use case involving shared external state without =
internal references.</div><div>&nbsp;</div><div><div style=3D"border: 1px s=
olid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, =
250, 250);" class=3D"prettyprint"><code class=3D"prettyprint"><div style=3D=
"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-co=
lor: rgb(250, 250, 250);" class=3D"prettyprint"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: rgb(136, 0, 0);" class=
=3D"styled-by-prettify">//Assumptions:</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(13=
6, 0, 0);" class=3D"styled-by-prettify">//optional&lt;T&gt; is implemented =
as struct { T t; bool b; }</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(136, 0, 0);" c=
lass=3D"styled-by-prettify">//sizeof(T*) =3D=3D 8</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: rgb(136, 0, 0);" class=3D"styled-by-prettify">//sizeof(bool) =3D=3D 1<=
/span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify"=
>//sizeof(bitset&lt;N&gt;) =3D=3D 8 when N &lt;=3D 64</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//A cache line on =
this platform is 64 bytes</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: rgb(0, 0, 136)=
;" class=3D"styled-by-prettify">struct</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"> X </span><span style=3D"color: rgb(102=
, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(1=
36, 0, 0);" class=3D"styled-by-prettify">/* stuff */</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br></span><span=
 style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">struct</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> A </spa=
n><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</=
span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=
&nbsp; optional</span><span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify">X</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">*&gt;</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> a</span><span style=3D"color: rgb(102, 102, 0);=
" class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);"=
 class=3D"styled-by-prettify"><br>&nbsp; optional</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">X</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*&gt;</span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> b</span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><=
span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp;=
 optional</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-=
by-prettify">X</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify">*&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify"> c</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br>&nbsp; optional</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify">X</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">*&gt;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> d</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">sta=
tic_assert</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-=
by-prettify">sizeof</span><span style=3D"color: rgb(102, 102, 0);" class=3D=
"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify">A</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">)</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 102, 10=
2);" class=3D"styled-by-prettify">64</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">);</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(=
136, 0, 0);" class=3D"styled-by-prettify">//A contains 4 optionals, which f=
ill an entire cache line</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(136, 0, 0);" c=
lass=3D"styled-by-prettify">//7 * 4 =3D 28 bytes are wasted padding the boo=
ls for each optional</span><span style=3D"color: rgb(0, 0, 0);" class=3D"st=
yled-by-prettify"><br><br></span><span style=3D"color: rgb(136, 0, 0);" cla=
ss=3D"styled-by-prettify">//Similar to optional, except it uses the specifi=
ed bit from bits</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled=
-by-prettify"><br></span><span style=3D"color: rgb(136, 0, 0);" class=3D"st=
yled-by-prettify">//to store the active state</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 rgb(136, 0, 0);" class=3D"styled-by-prettify">//sizeof(bit_optional&lt;T,.=
...&gt; =3D=3D sizeof(T)</span><span style=3D"color: rgb(0, 0, 0);" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">template</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, =
0);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0=
, 136);" class=3D"styled-by-prettify">typename</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> T</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"> size_t bit</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">auto</span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&amp;</sp=
an><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> bits<=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pre=
ttify">class</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify"> bit_optional </span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: rgb(136, 0, 0);" cla=
ss=3D"styled-by-prettify">/* ... */</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">}</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(0, =
0, 136);" class=3D"styled-by-prettify">struct</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"> B </span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: rgb(0, 0, 136);" class=3D"styled-by-prettify">private</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">:</span><span s=
tyle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp; bitse=
t</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: rgb(0, 102, 102);" class=3D"styled-by-p=
rettify">7</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled=
-by-prettify"> _bits</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">public</span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">:</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify"><br>&nbsp; bit_optional</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">X</span><span=
 style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*,</span><=
span style=3D"color: rgb(0, 102, 102);" class=3D"styled-by-prettify">0</spa=
n><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</=
span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">_bit=
s</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prett=
ify"> a</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pr=
ettify"><br>&nbsp; bit_optional</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify">X</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">*,</span><span style=3D"color: rgb(0,=
 102, 102);" class=3D"styled-by-prettify">1</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify">_bits</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> b</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp; bit_op=
tional</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify">X</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-=
by-prettify">*,</span><span style=3D"color: rgb(0, 102, 102);" class=3D"sty=
led-by-prettify">2</span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">,</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify">_bits</span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" c=
lass=3D"styled-by-prettify"> c</span><span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify"><br>&nbsp; bit_optional</span><span style=3D=
"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">X</span><span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*,</span><span=
 style=3D"color: rgb(0, 102, 102);" class=3D"styled-by-prettify">3</span><s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">_bits</s=
pan><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"=
> d</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"><br>&nbsp; bit_optional</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify">X</span><span style=3D"color: rgb(102, 102, =
0);" class=3D"styled-by-prettify">*,</span><span style=3D"color: rgb(0, 102=
, 102);" class=3D"styled-by-prettify">4</span><span style=3D"color: rgb(102=
, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify">_bits</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> e</span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span style=3D=
"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>&nbsp; bit_optional=
</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy">X</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify">*,</span><span style=3D"color: rgb(0, 102, 102);" class=3D"styled-by=
-prettify">5</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">,</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-=
by-prettify">_bits</span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> f</span><span style=3D"color: rgb(102, 102, 0);" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"><br>&nbsp; bit_optional</span><span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">X</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*,</span><span s=
tyle=3D"color: rgb(0, 102, 102);" class=3D"styled-by-prettify">6</span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><=
span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">_bits</spa=
n><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt=
;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> =
g</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pr=
ettify"><br><br></span><span style=3D"color: rgb(0, 0, 136);" class=3D"styl=
ed-by-prettify">static_assert</span><span style=3D"color: rgb(102, 102, 0);=
" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 136)=
;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: rgb(102,=
 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify">B</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">)</span><span style=3D"color: rgb=
(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(0, 102, 102);" class=3D"styled-by-prettify">64</span><span style=3D"=
color: rgb(102, 102, 0);" class=3D"styled-by-prettify">);</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//B fits into a =
single cache line but now we can store 7 optionals instead of only 4.</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br>=
</span></div></code></div><br></code><code class=3D"prettyprint"></code></d=
iv><code class=3D"prettyprint"><div class=3D"subprettyprint">&nbsp;</div></=
code>In the above example, struct B has much more compact storage than A an=
d can fit a lot more data onto a single cache line.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&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_141_400633790.1421947938639--
------=_Part_140_1018248219.1421947938639--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 23 Jan 2015 07:00:48 +0800
Raw View
--Apple-Mail=_9601EBCA-CE36-4E7D-BEFD-FAD4077CC8FA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9301=E2=80=9323, at 1:32 AM, Matthew Fioravante <fmatthew58=
76@gmail.com> wrote:
>=20
> There is a ordering problem with my idea. We're asking the compiler to re=
fer to x in the template parameter before x is actually declared and declar=
ing x requires evaluating all of the template parameters first.=20
> =20
> To do this, the compiler would need to first determine the size and align=
ment of x without knowing the value of template parameter outer_this which =
I'm not sure is possible. There would have to be a lot of restrictions plac=
ed on the template specialization so that the data layout of the inner type=
 can never change depending on the value of outer_this.

Taking a look at Boost.Intrusive, they avoid this problem by defining the l=
ist object separately from the link node member. Put another way, it=E2=80=
=99s an extrusive interface on an intrusively-stored list.

http://www.boost.org/doc/libs/1_57_0/doc/html/intrusive/usage.html#intrusiv=
e.usage.usage_member_hook <http://www.boost.org/doc/libs/1_57_0/doc/html/in=
trusive/usage.html#intrusive.usage.usage_member_hook>


> In the above example, struct B has much more compact storage than A and c=
an fit a lot more data onto a single cache line.

This is interesting. I think translating the idea into expression aliases w=
ould still make it more powerful: Allow the outer type to specify any Boole=
an expression (containing this) as a template argument. A recurring suggest=
ion is function function parameters evaluated on use, so the syntax could b=
e reused for template non-type parameters.

// Introduce syntax T -> declarator as expression alias parameter.
template <typename T, bool -> bit>
class bit_optional { /* ... */ };

struct B {
private:
  bitset<7> _bits;
public:
  bit_optional<X*,this->_bits[0]> a;
  bit_optional<X*,this->_bits[1]> b;
  bit_optional<X*,this->_bits[2]> c;
  bit_optional<X*,this->_bits[3]> d;
=E2=80=A6

One implementation difficulty with either of our ideas is that the member a=
ccess won=E2=80=99t be well-formed until the enclosing type is complete. Cu=
rrently, a member declaration can refer to types of preceding member declar=
ations, but not to the class layout. Allowing dependencies on the layout of=
 a partially complete class would essentially force  members to be laid out=
 in declaration order, which a few implementations (namely MSVC) don=E2=80=
=99t do.

--=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=_9601EBCA-CE36-4E7D-BEFD-FAD4077CC8FA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9301=
=E2=80=9323, at 1:32 AM, Matthew Fioravante &lt;<a href=3D"mailto:fmatthew5=
876@gmail.com" class=3D"">fmatthew5876@gmail.com</a>&gt; wrote:</div><br cl=
ass=3D"Apple-interchange-newline"><div class=3D""><div style=3D"font-family=
: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; fon=
t-weight: normal; letter-spacing: normal; line-height: normal; orphans: aut=
o; text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" c=
lass=3D"">There is&nbsp;a ordering problem with my idea. We're asking the c=
ompiler to refer to x in the template parameter before x is actually declar=
ed and declaring x requires evaluating all of the template parameters first=
..<span class=3D"Apple-converted-space">&nbsp;</span></div><div style=3D"fon=
t-family: Helvetica; font-size: 12px; font-style: normal; font-variant: nor=
mal; font-weight: normal; letter-spacing: normal; line-height: normal; orph=
ans: auto; text-align: start; text-indent: 0px; text-transform: none; white=
-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width:=
 0px;" class=3D"">&nbsp;</div><div style=3D"font-family: Helvetica; font-si=
ze: 12px; font-style: normal; font-variant: normal; font-weight: normal; le=
tter-spacing: normal; line-height: normal; orphans: auto; text-align: start=
; text-indent: 0px; text-transform: none; white-space: normal; widows: auto=
; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">To do this=
,&nbsp;the compiler would need to first determine the size and alignment of=
 x without knowing the value of&nbsp;template parameter outer_this which I'=
m not sure is possible. There would have to be a lot of restrictions placed=
 on the template specialization so that the data layout of the inner type c=
an never change depending on the value of outer_this.</div></div></blockquo=
te><br class=3D""></div><div>Taking a look at Boost.Intrusive, they avoid t=
his problem by defining the list object separately from the link node membe=
r. Put another way, it=E2=80=99s an extrusive interface on an intrusively-s=
tored list.</div><div><br class=3D""></div><div><a href=3D"http://www.boost=
..org/doc/libs/1_57_0/doc/html/intrusive/usage.html#intrusive.usage.usage_me=
mber_hook" class=3D"">http://www.boost.org/doc/libs/1_57_0/doc/html/intrusi=
ve/usage.html#intrusive.usage.usage_member_hook</a></div><div><br class=3D"=
"></div><div><br class=3D""></div><div><blockquote type=3D"cite" class=3D""=
><div class=3D"">In the above example, struct B has much more compact stora=
ge than A and can fit a lot more data onto a single cache line.</div></bloc=
kquote><br class=3D""></div><div>This is interesting. I think translating t=
he idea into expression aliases would still make it more powerful: Allow th=
e outer type to specify any Boolean expression (containing&nbsp;<font face=
=3D"Courier" class=3D"">this</font>) as a template argument. A recurring su=
ggestion is function function parameters evaluated on use, so the syntax co=
uld be reused for template non-type parameters.</div><div><br class=3D""></=
div><div><span class=3D"styled-by-prettify" style=3D"font-family: monospace=
;">// Introduce syntax T -&gt; declarator as expression alias parameter.</s=
pan></div><div><span class=3D"styled-by-prettify" style=3D"font-family: mon=
ospace; color: rgb(0, 0, 136);">template</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace;">&nbsp;</span><span class=3D"styled=
-by-prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0);">&l=
t;</span><span class=3D"styled-by-prettify" style=3D"font-family: monospace=
; color: rgb(0, 0, 136);">typename</span><span class=3D"styled-by-prettify"=
 style=3D"font-family: monospace;">&nbsp;T</span><span class=3D"styled-by-p=
rettify" style=3D"font-family: monospace; color: rgb(102, 102, 0);">,</span=
><span class=3D"styled-by-prettify" style=3D"font-family: monospace;">&nbsp=
;bool -&gt; bit</span><span class=3D"styled-by-prettify" style=3D"font-fami=
ly: monospace; color: rgb(102, 102, 0);">&gt;</span><span class=3D"styled-b=
y-prettify" style=3D"font-family: monospace;"><br class=3D""></span><span c=
lass=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(0, =
0, 136);">class</span><span class=3D"styled-by-prettify" style=3D"font-fami=
ly: monospace;">&nbsp;bit_optional&nbsp;</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; color: rgb(102, 102, 0);">{</span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace;">&nbsp;<=
/span><span class=3D"styled-by-prettify" style=3D"font-family: monospace; c=
olor: rgb(136, 0, 0);">/* ... */</span><span class=3D"styled-by-prettify" s=
tyle=3D"font-family: monospace;">&nbsp;</span><span class=3D"styled-by-pret=
tify" style=3D"font-family: monospace; color: rgb(102, 102, 0);">};</span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace;"><br cla=
ss=3D""></span><span class=3D"styled-by-prettify" style=3D"font-family: mon=
ospace; color: rgb(0, 0, 136);"><br class=3D""></span></div><div><span clas=
s=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(0, 0, =
136);">struct</span><span class=3D"styled-by-prettify" style=3D"font-family=
: monospace;">&nbsp;B&nbsp;</span><span class=3D"styled-by-prettify" style=
=3D"font-family: monospace; color: rgb(102, 102, 0);">{</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace;"><br class=3D""></=
span><span class=3D"styled-by-prettify" style=3D"font-family: monospace; co=
lor: rgb(0, 0, 136);">private</span><span class=3D"styled-by-prettify" styl=
e=3D"font-family: monospace; color: rgb(102, 102, 0);">:</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace;"><br class=3D"">&n=
bsp; bitset</span><span class=3D"styled-by-prettify" style=3D"font-family: =
monospace; color: rgb(102, 102, 0);">&lt;</span><span class=3D"styled-by-pr=
ettify" style=3D"font-family: monospace; color: rgb(0, 102, 102);">7</span>=
<span class=3D"styled-by-prettify" style=3D"font-family: monospace; color: =
rgb(102, 102, 0);">&gt;</span><span class=3D"styled-by-prettify" style=3D"f=
ont-family: monospace;">&nbsp;_bits</span><span class=3D"styled-by-prettify=
" style=3D"font-family: monospace; color: rgb(102, 102, 0);">;</span><span =
class=3D"styled-by-prettify" style=3D"font-family: monospace;"><br class=3D=
""></span><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e; color: rgb(0, 0, 136);">public</span><span class=3D"styled-by-prettify" =
style=3D"font-family: monospace; color: rgb(102, 102, 0);">:</span><span cl=
ass=3D"styled-by-prettify" style=3D"font-family: monospace;"><br class=3D""=
>&nbsp; bit_optional</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; color: rgb(102, 102, 0);">&lt;</span><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace;">X</span><span class=3D"s=
tyled-by-prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0)=
;">*,</span><span style=3D"color: rgb(0, 0, 136); font-family: monospace;" =
class=3D"">this-&gt;</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace;">_bits[0]</span><span class=3D"styled-by-prettify" styl=
e=3D"font-family: monospace; color: rgb(102, 102, 0);">&gt;</span><span cla=
ss=3D"styled-by-prettify" style=3D"font-family: monospace;">&nbsp;a</span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace; color: r=
gb(102, 102, 0);">;</span></div><div><span class=3D"styled-by-prettify" sty=
le=3D"font-family: monospace;">&nbsp; bit_optional</span><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0);"=
>&lt;</span><span class=3D"styled-by-prettify" style=3D"font-family: monosp=
ace;">X</span><span class=3D"styled-by-prettify" style=3D"font-family: mono=
space; color: rgb(102, 102, 0);">*,</span><span style=3D"color: rgb(0, 0, 1=
36); font-family: monospace;" class=3D"">this-&gt;</span><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace;">_bits</span><span style=
=3D"font-family: monospace;" class=3D"">[1]</span><span class=3D"styled-by-=
prettify" style=3D"font-family: monospace; color: rgb(102, 102, 0);">&gt;</=
span><span class=3D"styled-by-prettify" style=3D"font-family: monospace;">&=
nbsp;b</span><span class=3D"styled-by-prettify" style=3D"font-family: monos=
pace; color: rgb(102, 102, 0);">;</span></div><div><span class=3D"styled-by=
-prettify" style=3D"font-family: monospace;">&nbsp; bit_optional</span><spa=
n class=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(=
102, 102, 0);">&lt;</span><span class=3D"styled-by-prettify" style=3D"font-=
family: monospace;">X</span><span class=3D"styled-by-prettify" style=3D"fon=
t-family: monospace; color: rgb(102, 102, 0);">*,</span><span style=3D"colo=
r: rgb(0, 0, 136); font-family: monospace;" class=3D"">this-&gt;</span><spa=
n class=3D"styled-by-prettify" style=3D"font-family: monospace;">_bits</spa=
n><span style=3D"font-family: monospace;" class=3D"">[2]</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; color: rgb(102, 10=
2, 0);">&gt;</span><span class=3D"styled-by-prettify" style=3D"font-family:=
 monospace;">&nbsp;c</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; color: rgb(102, 102, 0);">;</span></div><div><span clas=
s=3D"styled-by-prettify" style=3D"font-family: monospace;">&nbsp; bit_optio=
nal</span><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e; color: rgb(102, 102, 0);">&lt;</span><span class=3D"styled-by-prettify" =
style=3D"font-family: monospace;">X</span><span class=3D"styled-by-prettify=
" style=3D"font-family: monospace; color: rgb(102, 102, 0);">*,</span><span=
 style=3D"color: rgb(0, 0, 136); font-family: monospace;" class=3D"">this-&=
gt;</span><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e;">_bits</span><span style=3D"font-family: monospace;" class=3D"">[3]</spa=
n><span class=3D"styled-by-prettify" style=3D"font-family: monospace; color=
: rgb(102, 102, 0);">&gt;</span><span class=3D"styled-by-prettify" style=3D=
"font-family: monospace;">&nbsp;d</span><span class=3D"styled-by-prettify" =
style=3D"font-family: monospace; color: rgb(102, 102, 0);">;</span></div><d=
iv><font face=3D"monospace" class=3D"">=E2=80=A6</font></div><div><font fac=
e=3D"monospace" class=3D""><br class=3D""></font></div><div>One implementat=
ion difficulty with either of our ideas is that the member access won=E2=80=
=99t be well-formed until the enclosing type is complete. Currently, a memb=
er declaration can refer to types of preceding member declarations, but not=
 to the class layout. Allowing dependencies on the layout of a partially co=
mplete class would essentially force &nbsp;members to be laid out in declar=
ation order, which a few implementations (namely MSVC) don=E2=80=99t do.</d=
iv></body></html>

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

--Apple-Mail=_9601EBCA-CE36-4E7D-BEFD-FAD4077CC8FA--

.