Topic: Draft proposal - std::recover_cast: undoing type erasure
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 17:12:15 +0800
Raw View
--Apple-Mail=_218C076A-525F-408C-B85B-376CCEAAA2C8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Abstract:
C++ has a couple built-in type erasure mechanisms, with respective faciliti=
es to recover the original object: polymorphic classes with dynamic_cast, a=
nd void pointers with static_cast or reinterpret_cast. A library facility r=
ecover_cast is proposed to analogously handle erasure classes like std::fun=
ction, any, and variant. Besides being a uniform, generic interface, it sim=
plifies implementation and and even improves performance.
Highlight:
template< typename T, typename ErasureClass >
constexpr auto *
recover_cast( ErasureClass cq * e ) noexcept; // cq is const or empty.
Requires: ErasureClass is capable of erasing T. (Thus, T shall not be void.=
A class may not assign semantics to =E2=80=9Cerased values of type void,=
=E2=80=9D and the implementation should diagnose an attempt to use recover_=
cast< void >( & e ) as a substitute for static_cast< void * >( e ).)
Returns: ( remove_reference_t< T cq > * ) e.operator void const * () if e c=
ontains type T according to e.verify_type< T >(). Otherwise, nullptr.
template< typename T, typename ErasureClass >
auto && // cq is const or empty. ref is & or &&.
recover_cast( ErasureClass cq ref e ) noexcept;
Requires: ErasureClass is capable of erasing T.
Effects: Let p be recover_cast< T >( & e ). If p is a null pointer, throw a=
n object of class bad_type_recovery. Otherwise, return static_cast< T cq re=
f >( * p ).
Complete PDF: http://bit.ly/reccast <http://bit.ly/reccast>
--=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=_218C076A-525F-408C-B85B-376CCEAAA2C8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webk=
it-line-break: after-white-space;" class=3D""><p style=3D"margin: 0px 0px 1=
6px; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: in=
itial; font-size: 14px;" class=3D"">Abstract:</p><p style=3D"margin: 0px 0p=
x 16px; font-family: Times; -webkit-text-stroke-color: rgb(0, 0, 0); -webki=
t-text-stroke-width: initial; font-size: 14px;" class=3D"">C++ has a couple=
built-in type erasure mechanisms, with respective facilities to recover th=
e original object: polymorphic classes with <span style=3D"font-size: 13px;=
font-family: Courier; background-color: rgb(245, 245, 245);" class=3D"">dy=
namic_cast</span>, and <span style=3D"font-size: 13px; font-family: Courier=
; background-color: rgb(245, 245, 245);" class=3D"">void</span> pointers wi=
th <span style=3D"font-size: 13px; font-family: Courier; background-color: =
rgb(245, 245, 245);" class=3D"">static_cast</span> or <span style=3D"font-s=
ize: 13px; font-family: Courier; background-color: rgb(245, 245, 245);" cla=
ss=3D"">reinterpret_cast</span>. A library facility <span style=3D"font-siz=
e: 13px; font-family: Courier; background-color: rgb(245, 245, 245);" class=
=3D"">recover_cast</span> is proposed to analogously handle erasure classes=
like <span style=3D"font-size: 13px; font-family: Courier; background-colo=
r: rgb(245, 245, 245);" class=3D"">std::function</span>, <span style=3D"fon=
t-size: 13px; font-family: Courier; background-color: rgb(245, 245, 245);" =
class=3D"">any</span>, and <span style=3D"font-size: 13px; font-family: Cou=
rier; background-color: rgb(245, 245, 245);" class=3D"">variant</span>. Bes=
ides being a uniform, generic interface, it simplifies implementation and&n=
bsp;<span style=3D"-webkit-text-stroke-width: initial;" class=3D"">and even=
improves performance</span><span style=3D"-webkit-text-stroke-width: initi=
al;" class=3D"">.</span></p><div class=3D""><br class=3D""></div><div style=
=3D"font-size: 14px;" class=3D"">Highlight:</div><div style=3D"font-size: 1=
4px;" class=3D""><br class=3D""></div><div style=3D"font-size: 14px;" class=
=3D""><div style=3D"margin: 0px; font-size: 13px; font-family: Courier; -we=
bkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" =
class=3D"">template< typename T, typename ErasureClass ></div><div st=
yle=3D"margin: 0px; font-size: 13px; font-family: Courier; -webkit-text-str=
oke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D"">co=
nstexpr auto *</div><p style=3D"margin: 0px 0px 6px; font-size: 13px; font-=
family: Courier; -webkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stro=
ke-width: initial;" class=3D"">recover_cast( ErasureClass <i class=3D"">cq =
</i>* e ) noexcept;<span class=3D"Apple-tab-span" style=3D"white-space:pre"=
> </span>// <i class=3D"">cq</i><span style=3D"font-family: Charter;" class=
=3D""><i class=3D""> is </i></span>const<span style=3D"font-family: Charter=
;" class=3D""><i class=3D""> or empty.</i></span></p><p style=3D"margin: 0p=
x 0px 6px 36px; text-indent: -36px; font-family: Times; -webkit-text-stroke=
-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D""><i cl=
ass=3D"">Requires:</i> <span style=3D"font-size: 13px; font-family: Courier=
; background-color: rgb(245, 245, 245);" class=3D"">ErasureClass</span> is =
capable of erasing <span style=3D"font-size: 13px; font-family: Courier; ba=
ckground-color: rgb(245, 245, 245);" class=3D"">T</span>. (Thus, <span styl=
e=3D"font-size: 13px; font-family: Courier; background-color: rgb(245, 245,=
245);" class=3D"">T</span> shall not be <span style=3D"font-size: 13px; fo=
nt-family: Courier; background-color: rgb(245, 245, 245);" class=3D"">void<=
/span>. A class may not assign semantics to =E2=80=9Cerased values of type =
<span style=3D"font-size: 13px; font-family: Courier; background-color: rgb=
(245, 245, 245);" class=3D"">void</span>,=E2=80=9D and the implementation s=
hould diagnose an attempt to use <span style=3D"font-size: 13px; font-famil=
y: Courier; background-color: rgb(245, 245, 245);" class=3D"">recover_cast&=
lt; void >( & e )</span> as a substitute for <span style=3D"font-siz=
e: 13px; font-family: Courier; background-color: rgb(245, 245, 245);" class=
=3D"">static_cast< void * >( e )</span>.)</p><p style=3D"margin: 0px =
0px 6px 36px; text-indent: -36px; font-size: 13px; font-family: Courier; -w=
ebkit-text-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;"=
class=3D""><span style=3D"font-size: 14px; font-family: Times;" class=3D""=
><i class=3D"">Returns:</i> </span><span style=3D"font-kerning: none; backg=
round-color: #f5f5f5" class=3D"">( remove_reference_t< T <i class=3D"">c=
q</i> > * ) e.operator void const * ()</span><span style=3D"font-size: 1=
4px; font-family: Times;" class=3D""> if </span><span style=3D"font-kerning=
: none; background-color: #f5f5f5" class=3D"">e</span><span style=3D"font-s=
ize: 14px; font-family: Times;" class=3D""> contains type </span><span styl=
e=3D"font-kerning: none; background-color: #f5f5f5" class=3D"">T</span><spa=
n style=3D"font-size: 14px; font-family: Times;" class=3D""> according to <=
/span><span style=3D"font-kerning: none; background-color: #f5f5f5" class=
=3D"">e.verify_type< T >()</span><span style=3D"font-size: 14px; font=
-family: Times;" class=3D"">. Otherwise, </span><span style=3D"font-kerning=
: none; background-color: #f5f5f5" class=3D"">nullptr</span><span style=3D"=
font-size: 14px; font-family: Times;" class=3D"">.</span></p><div style=3D"=
margin: 0px; font-size: 13px; font-family: Courier; -webkit-text-stroke-col=
or: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D"">template&=
lt; typename T, typename ErasureClass ></div><div style=3D"margin: 0px; =
font-size: 13px; font-family: Courier; -webkit-text-stroke-color: rgb(0, 0,=
0); -webkit-text-stroke-width: initial;" class=3D"">auto &&<span c=
lass=3D"Apple-tab-span" style=3D"white-space:pre"> </span> <span class=3D=
"Apple-tab-span" style=3D"white-space:pre"> </span>// <i class=3D"">cq</i><=
span style=3D"font-family: Charter;" class=3D""><i class=3D""> is </i></spa=
n>const<span style=3D"font-family: Charter;" class=3D""><i class=3D""> or e=
mpty. </i></span><i class=3D"">ref</i><span style=3D"font-family: Charter;"=
class=3D""><i class=3D""> is </i></span>&<span style=3D"font-family: C=
harter;" class=3D""><i class=3D""> or </i></span>&&<span style=3D"f=
ont-family: Charter;" class=3D""><i class=3D"">.</i></span></div><p style=
=3D"margin: 0px 0px 6px; font-size: 13px; font-family: Courier; -webkit-tex=
t-stroke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D=
"">recover_cast( ErasureClass <i class=3D"">cq ref</i> e ) noexcept;</p><p =
style=3D"margin: 0px 0px 6px; font-family: Times; -webkit-text-stroke-color=
: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D""><i class=3D=
"">Requires:</i> <span style=3D"font-size: 13px; font-family: Courier; back=
ground-color: rgb(245, 245, 245);" class=3D"">ErasureClass</span> is capabl=
e of erasing <span style=3D"font-size: 13px; font-family: Courier; backgrou=
nd-color: rgb(245, 245, 245);" class=3D"">T</span>.</p><p style=3D"margin: =
0px 0px 6px 36px; text-indent: -36px; font-family: Times; -webkit-text-stro=
ke-color: rgb(0, 0, 0); -webkit-text-stroke-width: initial;" class=3D""><i =
class=3D"">Effects:</i> Let <span style=3D"font-size: 13px; font-family: Co=
urier; background-color: rgb(245, 245, 245);" class=3D""><i class=3D"">p</i=
></span> be <span style=3D"font-size: 13px; font-family: Courier; backgroun=
d-color: rgb(245, 245, 245);" class=3D"">recover_cast< T >( & e )=
</span>. If <span style=3D"font-size: 13px; font-family: Courier; backgroun=
d-color: rgb(245, 245, 245);" class=3D""><i class=3D"">p</i></span> is a nu=
ll pointer, throw an object of class <span style=3D"font-size: 13px; font-f=
amily: Courier; background-color: rgb(245, 245, 245);" class=3D"">bad_type_=
recovery</span>. Otherwise, return <span style=3D"font-size: 13px; font-fam=
ily: Courier; background-color: rgb(245, 245, 245);" class=3D"">static_cast=
< T <i class=3D"">cq ref</i> >( * <i class=3D"">p</i> )</span>.</p></=
div><div class=3D""><br class=3D""></div><div class=3D""><br class=3D""></d=
iv><div style=3D"font-size: 14px;" class=3D"">Complete PDF: <a href=3D"http=
://bit.ly/reccast" class=3D"">http://bit.ly/reccast</a></div><div class=3D"=
"><br class=3D""></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" 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=_218C076A-525F-408C-B85B-376CCEAAA2C8--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 5 Sep 2015 12:15:52 +0300
Raw View
On 5 September 2015 at 12:12, David Krauss <potswa@gmail.com> wrote:
> Abstract:
>
> C++ has a couple built-in type erasure mechanisms, with respective
> facilities to recover the original object: polymorphic classes with
> dynamic_cast, and void pointers with static_cast or reinterpret_cast. A
> library facility recover_cast is proposed to analogously handle erasure
> classes like std::function, any, and variant. Besides being a uniform,
> generic interface, it simplifies implementation and and even improves
> performance.
Any particular reason why the writeup doesn't mention shared_ptr and
dynamic_pointer_cast?
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 17:36:48 +0800
Raw View
> On 2015=E2=80=9309=E2=80=9305, at 5:15 PM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> Any particular reason why the writeup doesn't mention shared_ptr and
> dynamic_pointer_cast?
It didn=E2=80=99t seem to come up. What would you add?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 5 Sep 2015 12:41:24 +0300
Raw View
On 5 September 2015 at 12:36, David Krauss <potswa@gmail.com> wrote:
>
>> On 2015=E2=80=9309=E2=80=9305, at 5:15 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>>
>> Any particular reason why the writeup doesn't mention shared_ptr and
>> dynamic_pointer_cast?
>
> It didn=E2=80=99t seem to come up. What would you add?
Well, it's another type-erasing facility that can recover a pointer to
the original type
with a specialized mechanism. I would've expected it to be mentioned alongs=
ide
the other types and their mechanisms, and I expected that this
recover_cast would
be applicable to shared_ptrs as well.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 19:11:48 +0800
Raw View
--Apple-Mail=_26531372-5219-4AC5-9F61-8F98C27455F1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9305, at 5:41 PM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> Well, it's another type-erasing facility that can recover a pointer to
> the original type
> with a specialized mechanism. I would've expected it to be mentioned alon=
gside
> the other types and their mechanisms,
Well, the only types/mechanisms mentioned are exactly analogous, where a ty=
pe goes in, it=E2=80=99s checked against a stored value (e.g. type_info), a=
nd a native reference or pointer comes out. The *_pointer_cast functions wr=
ap a conversion of the embedded native pointer, with the result being anoth=
er smart pointer.
I should suggest as future work that the *_pointer_casts could perhaps be m=
ade generic across some sort of class interface, and extended to unique_ptr=
and user types. The important thing is that the deleter gets preserved. Th=
at makes an implicit decision that ADL is not the right way to call smart p=
ointer casts.
> and I expected that this
> recover_cast would
> be applicable to shared_ptrs as well.
Interesting. I=E2=80=99d thought that converting to shared_ptr<void> access=
ed the hidden master pointer (used for deletion), but apparently the closes=
t you can get is applying dynamic_pointer_cast<void> to a shared_ptr<T> whe=
re T is statically polymorphic type.
So, under my proposal, recover_cast applied to shared_ptr would allow you t=
o query the type of the master pointer, and observe it. Were you thinking a=
long these lines?
--=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=_26531372-5219-4AC5-9F61-8F98C27455F1
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=9309=
=E2=80=9305, at 5:41 PM, Ville Voutilainen <<a href=3D"mailto:ville.vout=
ilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</d=
iv><br class=3D"Apple-interchange-newline"><div class=3D"">Well, it's anoth=
er type-erasing facility that can recover a pointer to<br class=3D"">the or=
iginal type<br class=3D"">with a specialized mechanism. I would've expected=
it to be mentioned alongside<br class=3D"">the other types and their mecha=
nisms, </div></blockquote><div><br class=3D""></div><div>Well, the only typ=
es/mechanisms mentioned are exactly analogous, where a type goes in, it=E2=
=80=99s checked against a stored value (e.g. <font face=3D"Courier" cl=
ass=3D"">type_info</font>), and a native reference or pointer comes out. Th=
e <font face=3D"Courier" class=3D"">*_pointer_cast</font> functio=
ns wrap a conversion of the embedded native pointer, with the result being =
another smart pointer.</div><div><br class=3D""></div><div>I should suggest=
as future work that the <span style=3D"font-family: Courier;" class=
=3D"">*_pointer_cast</span>s could perhaps be made generic across some sort=
of class interface, and extended to <font face=3D"Courier" class=3D"">uniq=
ue_ptr</font> and user types. The important thing is that the deleter gets =
preserved. That makes an implicit decision that ADL is not the right way to=
call smart pointer casts.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D"">and I expected that this<br class=3D"">recover_cas=
t would<br class=3D"">be applicable to shared_ptrs as well.<br class=3D""><=
/div></blockquote><div><br class=3D""></div></div>Interesting. I=E2=80=99d =
thought that converting to <font face=3D"Courier" class=3D"">shared_ptr<=
void></font> accessed the hidden master pointer (used for deletion), but=
apparently the closest you can get is applying <font face=3D"Courier" clas=
s=3D"">dynamic_pointer_cast<void></font> to a <font face=3D"Courier" =
class=3D"">shared_ptr<T></font> where T is statically polymorphic typ=
e.<div class=3D""><br class=3D""></div><div class=3D"">So, under my proposa=
l, <font face=3D"Courier" class=3D"">recover_cast</font> applied to <font f=
ace=3D"Courier" class=3D"">shared_ptr</font> would allow you to query the t=
ype of the master pointer, and observe it. Were you thinking along these li=
nes?</div><div class=3D""><br class=3D""></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" 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=_26531372-5219-4AC5-9F61-8F98C27455F1--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 21:24:51 +0800
Raw View
--Apple-Mail=_67760585-73F2-4B4F-9E1E-CDF31CBCEEF5
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9305, at 7:11 PM, David Krauss <potswa@gmail.com=
<mailto:potswa@gmail.com>> wrote:
>=20
> So, under my proposal, recover_cast applied to shared_ptr would allow you=
to query the type of the master pointer, and observe it. Were you thinking=
along these lines?
=E2=80=A6 or were you thinking of the deleter instead? I think it would be =
odd for recover_cast to act as if the deleter was the value of the shared_p=
tr. There isn=E2=80=99t even a member deleter accessor, only std::get_delet=
er.
It might make sense to overload get_deleter(p) with no explicit template ar=
gument, to return std::experimental::any initialized with a D*, and then fr=
om that point my proposal applies. I haven=E2=80=99t checked to see whether=
this is feasible without adding overhead. It=E2=80=99s hard to judge what=
=E2=80=99s useful, because I don=E2=80=99t know any use cases of get_delete=
r.
--=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=_67760585-73F2-4B4F-9E1E-CDF31CBCEEF5
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"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3D=
utf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: spac=
e; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><div c=
lass=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=
=80=9309=E2=80=9305, at 7:11 PM, David Krauss <<a href=3D"mailto:potswa@=
gmail.com" class=3D"">potswa@gmail.com</a>> wrote:</div><br class=3D"App=
le-interchange-newline"><div class=3D""><span style=3D"font-family: Helveti=
ca; font-size: 12px; font-style: normal; font-variant: normal; font-weight:=
normal; letter-spacing: normal; line-height: normal; orphans: auto; text-a=
lign: start; text-indent: 0px; text-transform: none; white-space: normal; w=
idows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none=
; display: inline !important;" class=3D"">So, under my proposal,<span class=
=3D"Apple-converted-space"> </span></span><font face=3D"Courier" class=
=3D"" style=3D"font-size: 12px; font-style: normal; font-variant: normal; f=
ont-weight: normal; letter-spacing: normal; line-height: normal; orphans: a=
uto; text-align: start; text-indent: 0px; text-transform: none; white-space=
: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"=
>recover_cast</font><span style=3D"font-family: Helvetica; font-size: 12px;=
font-style: normal; font-variant: normal; font-weight: normal; letter-spac=
ing: normal; line-height: normal; orphans: auto; text-align: start; text-in=
dent: 0px; text-transform: none; white-space: normal; widows: auto; word-sp=
acing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !i=
mportant;" class=3D""><span class=3D"Apple-converted-space"> </span>ap=
plied to<span class=3D"Apple-converted-space"> </span></span><font fac=
e=3D"Courier" class=3D"" style=3D"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;">shared_ptr</font><span style=3D"font-family: Helvetica;=
font-size: 12px; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; line-height: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; d=
isplay: inline !important;" class=3D""><span class=3D"Apple-converted-space=
"> </span>would allow you to query the type of the master pointer, and=
observe it. Were you thinking along these lines?</span></div></blockquote>=
</div><br class=3D""><div class=3D"">=E2=80=A6 or were you thinking of the =
deleter instead? I think it would be odd for <font face=3D"Courier" class=
=3D"">recover_cast</font> to act as if the deleter was the value of the <fo=
nt face=3D"Courier" class=3D"">shared_ptr</font>. There isn=E2=80=99t even =
a member deleter accessor, only <font face=3D"Courier" class=3D"">std::get_=
deleter</font>.</div><div class=3D""><br class=3D""></div><div class=3D"">I=
t might make sense to overload <font face=3D"Courier" class=3D"">get_delete=
r(p)</font> with no explicit template argument, to return <font f=
ace=3D"Courier" class=3D"">std::experimental::any</font> initialized w=
ith a <font face=3D"Courier" class=3D"">D*</font>, and then from that =
point my proposal applies. I haven=E2=80=99t checked to see whether this is=
feasible without adding overhead. It=E2=80=99s hard to judge what=E2=80=99=
s useful, because I don=E2=80=99t know any use cases of <font face=3D"Couri=
er" class=3D"">get_deleter</font>.</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" 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=_67760585-73F2-4B4F-9E1E-CDF31CBCEEF5--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 21:25:22 +0800
Raw View
--Apple-Mail=_D167A963-7D6C-47B3-931E-307D37B74B2F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9305, at 7:11 PM, David Krauss <potswa@gmail.com=
<mailto:potswa@gmail.com>> wrote:
>=20
> So, under my proposal, recover_cast applied to shared_ptr would allow you=
to query the type of the master pointer, and observe it. Were you thinking=
along these lines?
=E2=80=A6 or were you thinking of the deleter instead? I think it would be =
odd for recover_cast to act as if the deleter was the value of the shared_p=
tr. There isn=E2=80=99t even a member deleter accessor, only std::get_delet=
er.
It might make sense to overload get_deleter(p) with no explicit template ar=
gument, to return std::experimental::any initialized with a D*, and then fr=
om that point my proposal applies. I haven=E2=80=99t checked to see whether=
this is feasible without adding overhead. It=E2=80=99s hard to judge what=
=E2=80=99s useful, because I don=E2=80=99t know any use cases of get_delete=
r.
--=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=_D167A963-7D6C-47B3-931E-307D37B74B2F
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"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3D=
utf-8"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3Dutf=
-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D""><br class=3D""><div clas=
s=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=
=9309=E2=80=9305, at 7:11 PM, David Krauss <<a href=3D"mailto:potswa@gma=
il.com" class=3D"">potswa@gmail.com</a>> wrote:</div><br class=3D"Apple-=
interchange-newline"><div class=3D""><span style=3D"font-family: Helvetica;=
font-size: 12px; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; line-height: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; d=
isplay: inline !important;" class=3D"">So, under my proposal,<span class=3D=
"Apple-converted-space"> </span></span><font face=3D"Courier" class=3D=
"" style=3D"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: n=
ormal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">re=
cover_cast</font><span style=3D"font-family: Helvetica; font-size: 12px; fo=
nt-style: normal; font-variant: normal; font-weight: normal; letter-spacing=
: normal; line-height: normal; orphans: auto; text-align: start; text-inden=
t: 0px; text-transform: none; white-space: normal; widows: auto; word-spaci=
ng: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !impo=
rtant;" class=3D""><span class=3D"Apple-converted-space"> </span>appli=
ed to<span class=3D"Apple-converted-space"> </span></span><font face=
=3D"Courier" class=3D"" style=3D"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-s=
troke-width: 0px;">shared_ptr</font><span 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; float: none; di=
splay: inline !important;" class=3D""><span class=3D"Apple-converted-space"=
> </span>would allow you to query the type of the master pointer, and =
observe it. Were you thinking along these lines?</span></div></blockquote><=
/div><br class=3D""><div class=3D"">=E2=80=A6 or were you thinking of the d=
eleter instead? I think it would be odd for <font face=3D"Courier" class=3D=
"">recover_cast</font> to act as if the deleter was the value of the <font =
face=3D"Courier" class=3D"">shared_ptr</font>. There isn=E2=80=99t even a m=
ember deleter accessor, only <font face=3D"Courier" class=3D"">std::get_del=
eter</font>.</div><div class=3D""><br class=3D""></div><div class=3D"">It m=
ight make sense to overload <font face=3D"Courier" class=3D"">get_deleter(p=
)</font> with no explicit template argument, to return <font face=
=3D"Courier" class=3D"">std::experimental::any</font> initialized with=
a <font face=3D"Courier" class=3D"">D*</font>, and then from that poi=
nt my proposal applies. I haven=E2=80=99t checked to see whether this is fe=
asible without adding overhead. It=E2=80=99s hard to judge what=E2=80=99s u=
seful, because I don=E2=80=99t know any use cases of <font face=3D"Courier"=
class=3D"">get_deleter</font>.</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" 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=_D167A963-7D6C-47B3-931E-307D37B74B2F--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 5 Sep 2015 17:34:33 +0300
Raw View
On 5 September 2015 at 16:25, David Krauss <potswa@gmail.com> wrote:
> So, under my proposal, recover_cast applied to shared_ptr would allow you=
to
> query the type of the master pointer, and observe it. Were you thinking
> along these lines?
> =E2=80=A6 or were you thinking of the deleter instead? I think it would b=
e odd for
> recover_cast to act as if the deleter was the value of the shared_ptr. Th=
ere
> isn=E2=80=99t even a member deleter accessor, only std::get_deleter.
I wasn't thinking of the deleter, I was assuming that recover_cast would
include shared_ptr in the interface unification. I don't see why it would b=
e
excluded. any_cast is to any as dynamic_pointer_cast is to shared_ptr,
and I was thinking that recover_cast should work on both, in addition to
the other types you mention in your paper.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 5 Sep 2015 22:40:31 +0800
Raw View
--Apple-Mail=_30B57F32-6989-46FD-A912-E70DA54A8E9E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9305, at 10:34 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>=20
> any_cast is to any as dynamic_pointer_cast is to shared_ptr,
dynamic_pointer_cast only transforms one shared_ptr into another. any_cast =
is an accessor.
any_cast is to any as operator* is to shared_ptr.
--=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=_30B57F32-6989-46FD-A912-E70DA54A8E9E
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=9309=
=E2=80=9305, at 10:34 PM, Ville Voutilainen <<a href=3D"mailto:ville.vou=
tilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><span 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; float: none; display: inline !important;" class=3D"">any_cast is t=
o any as dynamic_pointer_cast is to shared_ptr,</span></div></blockquote></=
div><br class=3D""><div class=3D""><font face=3D"Courier" class=3D"">dynami=
c_pointer_cast</font> only transforms one <font face=3D"Courier" class=
=3D"">shared_ptr</font> into another. <font face=3D"Courier" class=3D"">any=
_cast</font> is an accessor.</div><div class=3D""><br class=3D""></div><div=
class=3D""><font face=3D"Courier" class=3D"">any_cast</font> is to <font f=
ace=3D"Courier" class=3D"">any</font> as <font face=3D"Courier" class=3D"">=
operator*</font> is to <font face=3D"Courier" class=3D"">shared_ptr</font>.=
</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" 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=_30B57F32-6989-46FD-A912-E70DA54A8E9E--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 5 Sep 2015 17:50:33 +0300
Raw View
On 5 September 2015 at 17:40, David Krauss <potswa@gmail.com> wrote:
>
> On 2015=E2=80=9309=E2=80=9305, at 10:34 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com>
> wrote:
>
> any_cast is to any as dynamic_pointer_cast is to shared_ptr,
>
>
> dynamic_pointer_cast only transforms one shared_ptr into another. any_cas=
t
> is an accessor.
Sure, but they also allow retrieving the original type from the
type-erased wrapper.
> any_cast is to any as operator* is to shared_ptr.
Except that operator* doesn't "undo type erasure". So again, why isn't "und=
oing
type erasure" as a supposedly general facility including shared_ptr in the =
types
it supports? Similarly, it seems to me it could just as well support unique=
_ptr
and raw pointers, or even reference types. If you're striving for uniformit=
y and
generality, what's the rationale of excluding the aforementioned types from=
that
uniformity and generality?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 00:16:45 +0800
Raw View
--Apple-Mail=_258A4E24-951E-4D65-854B-419480A564F8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9305, at 10:50 PM, Ville Voutilainen <ville.vout=
ilainen@gmail.com> wrote:
>=20
> On 5 September 2015 at 17:40, David Krauss <potswa@gmail.com> wrote:
>>=20
>> dynamic_pointer_cast only transforms one shared_ptr into another. any_ca=
st
>> is an accessor.
>=20
> Sure, but they also allow retrieving the original type from the
> type-erased wrapper.
dynamic_pointer_cast doesn=E2=80=99t access the shared, type-erased wrapper=
at all. It casts the non-shared, local pointer inside the given shared_ptr=
object according to dynamic_cast. Aside from RTTI, there=E2=80=99s no eras=
ure there, and recover_cast doesn=E2=80=99t wrap RTTI.
>> any_cast is to any as operator* is to shared_ptr.
>=20
> Except that operator* doesn't "undo type erasure". So again, why isn't "u=
ndoing
> type erasure" as a supposedly general facility including shared_ptr in th=
e types
> it supports?
It could be done, but accessing the control block is quite different from t=
he usual shared_ptr usage model. See the new =E2=80=9CFurther work=E2=80=9D=
section =E2=80=94 I just mailed you a copy.
> Similarly, it seems to me it could just as well support unique_ptr
> and raw pointers, or even reference types. If you're striving for uniform=
ity and
> generality, what's the rationale of excluding the aforementioned types fr=
om that
> uniformity and generality?
We have various type-casting facilities already; mine addresses erasure cla=
sses which essentially decorate a void* with a dynamic type. Ideally all th=
e facilities are orthogonal (aside from the bastard C-style cast expression=
).
Uniformity and generality across four, five, or N classes that sanitize voi=
d* doesn=E2=80=99t somehow extend to every cast under the sun.
--=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=_258A4E24-951E-4D65-854B-419480A564F8
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=9309=
=E2=80=9305, at 10:50 PM, Ville Voutilainen <<a href=3D"mailto:ville.vou=
tilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D"">On 5 September =
2015 at 17:40, David Krauss <<a href=3D"mailto:potswa@gmail.com" class=
=3D"">potswa@gmail.com</a>> wrote:<br class=3D""><blockquote type=3D"cit=
e" class=3D""><br class=3D"">dynamic_pointer_cast only transforms one share=
d_ptr into another. any_cast<br class=3D"">is an accessor.<br class=3D""></=
blockquote><br class=3D"">Sure, but they also allow retrieving the original=
type from the<br class=3D"">type-erased wrapper.<br class=3D""></div></blo=
ckquote><div><br class=3D""></div><div><font face=3D"Courier" class=3D"">dy=
namic_pointer_cast</font> doesn=E2=80=99t access the shared, type-erased wr=
apper at all. It casts the non-shared, local pointer inside the given =
<font face=3D"Courier" class=3D"">shared_ptr</font> object according to <fo=
nt face=3D"Courier" class=3D"">dynamic_cast</font>. Aside from RTTI, there=
=E2=80=99s no erasure there, and <font face=3D"Courier" class=3D"">recover_=
cast</font> doesn=E2=80=99t wrap RTTI.</div><div><br class=3D""></div><bloc=
kquote type=3D"cite" class=3D""><div class=3D""><blockquote type=3D"cite" c=
lass=3D"">any_cast is to any as operator* is to shared_ptr.<br class=3D""><=
/blockquote><br class=3D"">Except that operator* doesn't "undo type erasure=
". So again, why isn't "undoing<br class=3D"">type erasure" as a supposedly=
general facility including shared_ptr in the types<br class=3D"">it suppor=
ts? </div></blockquote><div><br class=3D""></div><div>It could be done, but=
accessing the control block is quite different from the usual <s=
pan style=3D"font-family: Courier;" class=3D"">shared_ptr</span> usage=
model. See the new =E2=80=9CFurther work=E2=80=9D section =E2=80=94 I just=
mailed you a copy.</div><br class=3D""><blockquote type=3D"cite" class=3D"=
"><div class=3D"">Similarly, it seems to me it could just as well support u=
nique_ptr<br class=3D"">and raw pointers, or even reference types. If you'r=
e striving for uniformity and<br class=3D"">generality, what's the rational=
e of excluding the aforementioned types from that<br class=3D"">uniformity =
and generality?<br class=3D""></div></blockquote></div><br class=3D""><div =
class=3D"">We have various type-casting facilities already; mine addresses =
erasure classes which essentially decorate a <font face=3D"Courier" class=
=3D"">void*</font> with a dynamic type. Ideally all the facilities are orth=
ogonal (aside from the bastard C-style cast expression).</div><div class=3D=
""><br class=3D""></div><div class=3D"">Uniformity and generality across fo=
ur, five, or N classes that sanitize <font face=3D"Courier" class=3D"">void=
*</font> doesn=E2=80=99t somehow extend to every cast under the sun.</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" 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=_258A4E24-951E-4D65-854B-419480A564F8--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 5 Sep 2015 20:31:28 +0300
Raw View
On 5 September 2015 at 19:16, David Krauss <potswa@gmail.com> wrote:
> dynamic_pointer_cast only transforms one shared_ptr into another. any_cas=
t
> is an accessor.
>
> Sure, but they also allow retrieving the original type from the
> type-erased wrapper.
>
> dynamic_pointer_cast doesn=E2=80=99t access the shared, type-erased wrapp=
er at all.
You seem to be talking about implementation specifics rather than
semantics there.
> It casts the non-shared, local pointer inside the given shared_ptr object
> according to dynamic_cast. Aside from RTTI, there=E2=80=99s no erasure th=
ere, and
> recover_cast doesn=E2=80=99t wrap RTTI.
"Aside from RTTI"? I don't know what that means. The simplest form
of "type erasure" is
Base* b =3D derived_ptr;
b->virtual_function();
delete b;
We can argue all day long whether that is truly "type erasure", but if your=
goal
is to provide a general facility to "undo type erasure", I would certainly =
want
to have a semantic explanation why it doesn't apply to such simple cases.
> Similarly, it seems to me it could just as well support unique_ptr
> and raw pointers, or even reference types. If you're striving for uniform=
ity
> and
> generality, what's the rationale of excluding the aforementioned types fr=
om
> that
> uniformity and generality?
>
>
> We have various type-casting facilities already; mine addresses erasure
> classes which essentially decorate a void* with a dynamic type. Ideally a=
ll
> the facilities are orthogonal (aside from the bastard C-style cast
> expression).
So you're saying that the goal of your facility is not uniformity and
generality?
> Uniformity and generality across four, five, or N classes that sanitize
> void* doesn=E2=80=99t somehow extend to every cast under the sun.
Claiming that std::any is "sanitizing void*" doesn't "somehow" make
that claim true. :)
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Sat, 5 Sep 2015 20:41:37 +0300
Raw View
On 05.09.2015 12:15, Ville Voutilainen wrote:
> On 5 September 2015 at 12:12, David Krauss <potswa@gmail.com> wrote:
>> Abstract:
>>
>> C++ has a couple built-in type erasure mechanisms, with respective
>> facilities to recover the original object: polymorphic classes with
>> dynamic_cast, and void pointers with static_cast or reinterpret_cast. A
>> library facility recover_cast is proposed to analogously handle erasure
>> classes like std::function, any, and variant. Besides being a uniform,
>> generic interface, it simplifies implementation and and even improves
>> performance.
>
>
> Any particular reason why the writeup doesn't mention shared_ptr and
> dynamic_pointer_cast?
I think with shared_ptr this tool would have ambiguous meaning due to
pointer aliasing.
struct Base
{
virtual ~Base() = default;
};
struct Derived : Base {};
struct Owner
{
unique_ptr< Base > m_p;
Owner() : m_p(new Derived()) {}
};
shared_ptr< Owner > owner = make_shared< Owner >();
shared_ptr< Base > p(owner.m_p, owner);
recover_cast< Derived* >(p); // (1)
recover_cast< Owner* >(p); // (2)
It's not clear whether (1) or (2) or both should work. I guess there
should be a clear specification as to what is considered the erased type
in this case.
--
---
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/.
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Sat, 5 Sep 2015 20:42:55 +0300
Raw View
On 05.09.2015 20:41, Andrey Semashev wrote:
> On 05.09.2015 12:15, Ville Voutilainen wrote:
>> On 5 September 2015 at 12:12, David Krauss <potswa@gmail.com> wrote:
>>> Abstract:
>>>
>>> C++ has a couple built-in type erasure mechanisms, with respective
>>> facilities to recover the original object: polymorphic classes with
>>> dynamic_cast, and void pointers with static_cast or reinterpret_cast. A
>>> library facility recover_cast is proposed to analogously handle erasure
>>> classes like std::function, any, and variant. Besides being a uniform,
>>> generic interface, it simplifies implementation and and even improves
>>> performance.
>>
>>
>> Any particular reason why the writeup doesn't mention shared_ptr and
>> dynamic_pointer_cast?
>
> I think with shared_ptr this tool would have ambiguous meaning due to
> pointer aliasing.
>
> struct Base
> {
> virtual ~Base() = default;
> };
>
> struct Derived : Base {};
>
> struct Owner
> {
> unique_ptr< Base > m_p;
>
> Owner() : m_p(new Derived()) {}
> };
>
> shared_ptr< Owner > owner = make_shared< Owner >();
> shared_ptr< Base > p(owner.m_p, owner);
That should be:
shared_ptr< Base > p(owner.m_p.get(), owner);
> recover_cast< Derived* >(p); // (1)
> recover_cast< Owner* >(p); // (2)
>
> It's not clear whether (1) or (2) or both should work. I guess there
> should be a clear specification as to what is considered the erased type
> in this case.
>
--
---
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/.
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Sat, 5 Sep 2015 21:07:16 +0300
Raw View
On 05.09.2015 12:12, David Krauss wrote:
> Abstract:
>
> C++ has a couple built-in type erasure mechanisms, with respective
> facilities to recover the original object: polymorphic classes with
> dynamic_cast, and void pointers with static_cast or reinterpret_cast. A
> library facility recover_cast is proposed to analogously handle erasure
> classes like std::function, any, and variant.
I can also add std::locale, which can be considered as a collection of=20
type erased facets.
> Besides being a uniform,
> generic interface, it simplifies implementation and and even improves
> performance.
>
>
> Highlight:
>
> template< typename T, typename ErasureClass >
> constexpr auto *
>
> recover_cast( ErasureClass /cq /* e ) noexcept;// /cq//is /const/or empty=
../
>
> /Requires:/ ErasureClass is capable of erasing T. (Thus, T shall not be
> void. A class may not assign semantics to =E2=80=9Cerased values of type =
void,=E2=80=9D
> and the implementation should diagnose an attempt to use recover_cast<
> void >( & e ) as a substitute for static_cast< void * >( e ).)
Why the special treatment of type void?
> /Returns:/ ( remove_reference_t< T /cq/ > * ) e.operator void const *
> ()if econtains type Taccording to e.verify_type< T >(). Otherwise, nullpt=
r.
>
> template< typename T, typename ErasureClass >
> auto &&// /cq//is /const/or empty. //ref//is /&/or /&&/./
>
> recover_cast( ErasureClass /cq ref/ e ) noexcept;
>
> /Requires:/ ErasureClass is capable of erasing T.
>
> /Effects:/ Let /p/ be recover_cast< T >( & e ). If /p/ is a null
> pointer, throw an object of class bad_type_recovery. Otherwise, return
> static_cast< T /cq ref/ >( * /p/ ).
I didn't like that the protocol you described in pdf is intrusive (i.e.=20
requires support built into the type erasing type). I would very much=20
preferred it to be decoupled from the type erasing wrapper. This would=20
allow to support the tool in non-standard type erasing types. Just=20
remove the ErasureClass concept and use functional API, in the=20
std::begin/end style.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 08:21:32 +0800
Raw View
--Apple-Mail=_17BC4F88-982F-4947-8E70-E670B127BE16
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 1:31 AM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> On 5 September 2015 at 19:16, David Krauss <potswa@gmail.com> wrote:
>=20
> We can argue all day long whether that is truly "type erasure", but if yo=
ur goal
> is to provide a general facility to "undo type erasure", I would certainl=
y want
> to have a semantic explanation why it doesn't apply to such simple cases.
My goal is not to =E2=80=9Cprovide a general facility to undo type erasure=
=E2=80=9D and the proposal never says anything to that effect. You seem to =
be extrapolating from the title alone.
What the paper says is =E2=80=9Canalogously handle erasure classes like std=
::function, any, and variant=E2=80=9D like dynamic_cast. Avoiding duplicati=
on of dynamic_cast semantics should be implicit, but I guess I should menti=
on orthogonality in the rationale. Maybe add a new =E2=80=9Cusage=E2=80=9D =
section. If you want a dynamic_cast with your recover_cast, you need to wri=
te e.g. dynamic_cast< derived * >( recover_cast< base * >( my_ptr_any ) ). =
I wouldn=E2=80=99t have it any other way.
I welcome suggestions about alternate titles or bikeshedding, but let=E2=80=
=99s judge the proposal on semantic merits. I can=E2=80=99t really tell whe=
ther you=E2=80=99re ironically making a slippery slope argument about unive=
rsality, or actually falling down that slippery slope.
--=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=_17BC4F88-982F-4947-8E70-E670B127BE16
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=9309=
=E2=80=9306, at 1:31 AM, Ville Voutilainen <<a href=3D"mailto:ville.vout=
ilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</d=
iv><br class=3D"Apple-interchange-newline"><div class=3D"">On 5 September 2=
015 at 19:16, David Krauss <<a href=3D"mailto:potswa@gmail.com" class=3D=
"">potswa@gmail.com</a>> wrote:<br class=3D""><br class=3D"">We can argu=
e all day long whether that is truly "type erasure", but if your goal<br cl=
ass=3D"">is to provide a general facility to "undo type erasure", I would c=
ertainly want<br class=3D"">to have a semantic explanation why it doesn't a=
pply to such simple cases.<br class=3D""></div></blockquote><div><br class=
=3D""></div><div>My goal is not to =E2=80=9Cprovide a general facility to u=
ndo type erasure=E2=80=9D and the proposal never says anything to that effe=
ct. You seem to be extrapolating from the title alone.</div><div><br class=
=3D""></div><div>What the paper says is =E2=80=9Canalogously handle erasure=
classes like <font face=3D"Courier" class=3D"">std::function</font>,&=
nbsp;<font face=3D"Courier" class=3D"">any</font>, and <font face=3D"C=
ourier" class=3D"">variant</font>=E2=80=9D like <font face=3D"Courier" clas=
s=3D"">dynamic_cast</font>. <i class=3D"">Avoiding</i> duplication of =
<font face=3D"Courier" class=3D"">dynamic_cast</font> semantics should be i=
mplicit, but I guess I should mention orthogonality in the rationale. Maybe=
add a new =E2=80=9Cusage=E2=80=9D section. If you want a <span style=
=3D"font-family: Courier;" class=3D"">dynamic_cast</span> with your <f=
ont face=3D"Courier" class=3D"">recover_cast</font>, you need to write e.g.=
<font face=3D"Courier" class=3D"">dynamic_cast< derived * >( re=
cover_cast< base * >( my_ptr_any ) )</font>. I wouldn=E2=80=99t have =
it any other way.</div><div><br class=3D""></div><div>I welcome suggestions=
about alternate titles or bikeshedding, but let=E2=80=99s judge the propos=
al on semantic merits. I can=E2=80=99t really tell whether you=E2=80=99re i=
ronically making a slippery slope argument about universality, or actually =
falling down that slippery slope.</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" 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=_17BC4F88-982F-4947-8E70-E670B127BE16--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 08:49:41 +0800
Raw View
--Apple-Mail=_DD4F9C99-085D-41FE-9A83-C878AFD1CDD8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 1:41 AM, Andrey Semashev <andrey.semash=
ev@gmail.com> wrote:
>=20
> struct Base
> {
> virtual ~Base() =3D default;
> };
>=20
> struct Derived : Base {};
>=20
> struct Owner
> {
> unique_ptr< Base > m_p;
>=20
> Owner() : m_p(new Derived()) {}
> };
>=20
> shared_ptr< Owner > owner =3D make_shared< Owner >();
> shared_ptr< Base > p(owner, owner->m_p.get()); // FTFY
>=20
> recover_cast< Derived* >(p); // (1)
> recover_cast< Owner* >(p); // (2)
>=20
> It's not clear whether (1) or (2) or both should work. I guess there shou=
ld be a clear specification as to what is considered the erased type in thi=
s case.
Right, this illustrates what I was saying to Ville.
shared_ptr does implement something like the proposal=E2=80=99s type erasur=
e model, but it diverges from familiar usage. #2 would work. #1 is a job fo=
r dynamic_cast or dynamic_pointer_cast instead. If Owner were derived from =
Base, and you plugged #1 into a tool attempting to unify dynamic_cast and r=
ecover_cast, confusion would ensue.
> On 2015=E2=80=9309=E2=80=9306, at 2:07 AM, Andrey Semashev <andrey.semash=
ev@gmail.com> wrote:
>=20
> I can also add std::locale, which can be considered as a collection of ty=
pe erased facets.
That problem is completely solved by use_facet (via facet ID=E2=80=99s and =
dynamic_cast).
>> /Requires:/ ErasureClass is capable of erasing T. (Thus, T shall not be
>> void. A class may not assign semantics to =E2=80=9Cerased values of type=
void,=E2=80=9D
>> and the implementation should diagnose an attempt to use recover_cast<
>> void >( & e ) as a substitute for static_cast< void * >( e ).)
>=20
> Why the special treatment of type void?
Because it has no values, it can=E2=80=99t be the erased value. It=E2=80=99=
s already used by function and any to represent disengagement.
> I didn't like that the protocol you described in pdf is intrusive (i.e. r=
equires support built into the type erasing type). I would very much prefer=
red it to be decoupled from the type erasing wrapper. This would allow to s=
upport the tool in non-standard type erasing types. Just remove the Erasure=
Class concept and use functional API, in the std::begin/end style.
None of the affected types support recover_cast without modification. It su=
pports user-defined types that provide the two member functions. I don=E2=
=80=99t think it can be less intrusive, but please share any suggestions.
--=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=_DD4F9C99-085D-41FE-9A83-C878AFD1CDD8
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""><div class=3D""><b=
r class=3D""></div><div><blockquote type=3D"cite" class=3D""><div class=3D"=
">On 2015=E2=80=9309=E2=80=9306, at 1:41 AM, Andrey Semashev <<a href=3D=
"mailto:andrey.semashev@gmail.com" class=3D"">andrey.semashev@gmail.com</a>=
> wrote:</div><br class=3D"Apple-interchange-newline"><div class=3D"">&n=
bsp; struct Base</div></blockquote><blockquote type=3D"cite" class=3D"">&nb=
sp;{<br class=3D""> virtual ~Base() =3D default;<br class=
=3D""> };<br class=3D""><br class=3D""> struct Derived : Base {};=
<br class=3D""><br class=3D""> struct Owner<br class=3D""> {<br c=
lass=3D""> unique_ptr< Base > m_p;<br class=3D""><br=
class=3D""> Owner() : m_p(new Derived()) {}<br class=3D""=
> };<br class=3D""><br class=3D""></blockquote><blockquote type=3D"cit=
e" class=3D""> shared_ptr< Owner > owner =3D make_shared< Own=
er >();<br class=3D""> shared_ptr< Base > p(owner, owner->=
m_p.get()); // FTFY<br class=3D""><br class=3D""> recover_cast< Der=
ived* >(p); // (1)<br class=3D""> recover_cast< Owner* >(p); =
// (2)<br class=3D""><br class=3D"">It's not clear whether (1) or (2) or bo=
th should work. I guess there should be a clear specification as to what is=
considered the erased type in this case.<br class=3D""></blockquote></div>=
<br class=3D""><div class=3D"">Right, this illustrates what I was saying to=
Ville.</div><div class=3D""><br class=3D""></div><div class=3D""><font fac=
e=3D"Courier" class=3D"">shared_ptr</font> does implement something li=
ke the proposal=E2=80=99s type erasure model, but it diverges from familiar=
usage. #2 would work. #1 is a job for <font face=3D"Courier" class=3D"">dy=
namic_cast</font> or <font face=3D"Courier" class=3D"">dynamic_pointer=
_cast</font> instead. If <font face=3D"Courier" class=3D"">Owner</font=
> were derived from <font face=3D"Courier" class=3D"">Base</font>, and you =
plugged #1 into a tool attempting to unify <font face=3D"Courier" class=3D"=
">dynamic_cast</font> and <font face=3D"Courier" class=3D"">recover_cast</f=
ont>, confusion would ensue.</div><div class=3D""><br class=3D""></div><div=
class=3D""><br class=3D""></div><div><blockquote type=3D"cite" class=3D"">=
<div class=3D"">On 2015=E2=80=9309=E2=80=9306, at 2:07 AM, Andrey Semashev =
<<a href=3D"mailto:andrey.semashev@gmail.com" class=3D"">andrey.semashev=
@gmail.com</a>> wrote:</div><br class=3D"Apple-interchange-newline"><div=
class=3D""><span style=3D"font-family: Helvetica; font-size: 12px; font-st=
yle: normal; font-variant: normal; font-weight: normal; letter-spacing: nor=
mal; line-height: normal; orphans: auto; text-align: start; text-indent: 0p=
x; text-transform: none; white-space: normal; widows: auto; word-spacing: 0=
px; -webkit-text-stroke-width: 0px; float: none; display: inline !important=
;" class=3D"">I can also add std::locale, which can be considered as a coll=
ection of type erased facets.</span><br style=3D"font-family: Helvetica; fo=
nt-size: 12px; font-style: normal; font-variant: normal; font-weight: norma=
l; 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=
></blockquote><div><br class=3D""></div><div>That problem is completely sol=
ved by <font face=3D"Courier" class=3D"">use_facet</font> (via facet ID=E2=
=80=99s and <font face=3D"Courier" class=3D"">dynamic_cast</font>).</d=
iv><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><blo=
ckquote type=3D"cite" style=3D"font-family: Helvetica; font-size: 12px; fon=
t-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-spacin=
g: 0px; -webkit-text-stroke-width: 0px;" class=3D"">/Requires:/ ErasureClas=
s is capable of erasing T. (Thus, T shall not be<br class=3D"">void. A clas=
s may not assign semantics to =E2=80=9Cerased values of type void,=E2=80=9D=
<br class=3D"">and the implementation should diagnose an attempt to use rec=
over_cast<<br class=3D"">void >( & e ) as a substitute for static=
_cast< void * >( e ).)<br class=3D""></blockquote><br style=3D"font-f=
amily: 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-sp=
ace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0p=
x;" class=3D""><span 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; float: none; display: inline !import=
ant;" class=3D"">Why the special treatment of type void?</span><br 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""></div></blockquote><div><br class=3D""></div><div>Bec=
ause it has no values, it can=E2=80=99t be the erased value. It=E2=80=99s a=
lready used by <font face=3D"Courier" class=3D"">function</font> and <font =
face=3D"Courier" class=3D"">any</font> to represent disengagement.</div><di=
v><br class=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D""=
><span style=3D"font-family: Helvetica; font-size: 12px; font-style: normal=
; font-variant: normal; font-weight: normal; letter-spacing: normal; line-h=
eight: normal; orphans: auto; text-align: start; text-indent: 0px; text-tra=
nsform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit=
-text-stroke-width: 0px; float: none; display: inline !important;" class=3D=
"">I didn't like that the protocol you described in pdf is intrusive (i.e. =
requires support built into the type erasing type). I would very much prefe=
rred it to be decoupled from the type erasing wrapper. This would allow to =
support the tool in non-standard type erasing types. Just remove the Erasur=
eClass concept and use functional API, in the std::begin/end style.</span><=
br style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; fo=
nt-variant: normal; font-weight: normal; letter-spacing: normal; line-heigh=
t: normal; orphans: auto; text-align: start; text-indent: 0px; text-transfo=
rm: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-tex=
t-stroke-width: 0px;" class=3D""></div></blockquote></div><br class=3D""><d=
iv class=3D"">None of the affected types support <font face=3D"Courier=
" class=3D"">recover_cast</font> without modification. It supports use=
r-defined types that provide the two member functions. I don=E2=80=99t thin=
k it can be less intrusive, but please share any suggestions.</div><div cla=
ss=3D""><br class=3D""></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" 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=_DD4F9C99-085D-41FE-9A83-C878AFD1CDD8--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 6 Sep 2015 03:30:51 +0200
Raw View
This is a multi-part message in MIME format.
--------------010207010305030302030802
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 05/09/15 11:12, David Krauss a =C3=A9crit :
> Abstract:
>
> C++ has a couple built-in type erasure mechanisms, with respective facili=
ties to recover the original object: polymorphic classes with dynamic_cast,=
and void pointers with static_cast or reinterpret_cast. A library facility=
recover_cast is proposed to analogously handle erasure classes like std::f=
unction, any, and variant. Besides being a uniform, generic interface, it s=
implifies implementation and and even improves performance.
>
>
> Highlight:
>
> template< typename T, typename ErasureClass >
> constexpr auto *
> recover_cast( ErasureClass cq * e ) noexcept; // cq is const or empty.
> Requires: ErasureClass is capable of erasing T. (Thus, T shall not be voi=
d. A class may not assign semantics to =E2=80=9Cerased values of type void,=
=E2=80=9D and the implementation should diagnose an attempt to use recover_=
cast< void >( & e ) as a substitute for static_cast< void * >( e ).)
> Returns: ( remove_reference_t< T cq > * ) e.operator void const * () if e=
contains type T according to e.verify_type< T >(). Otherwise, nullptr.
> template< typename T, typename ErasureClass >
> auto && // cq is const or empty. ref is & or &&.
> recover_cast( ErasureClass cq ref e ) noexcept;
> Requires: ErasureClass is capable of erasing T.
> Effects: Let p be recover_cast< T >( & e ). If p is a null pointer, throw=
an object of class bad_type_recovery. Otherwise, return static_cast< T cq =
ref >( * p ).
>
>
> Complete PDF: http://bit.ly/reccast <http://bit.ly/reccast>
>
Hi,
glad to see you have find this problematic also. I've updated yesterday=20
my ongoing proposal [1] with this same concern, but your paper explain=20
it much better;-)
The generic cast I was talking about was a cast on sum types. While=20
variant and optional are clear sum types, function and any can be seen=20
as degenerate sum types. All of them contains the part type.
I don't know if smart pointer types can be seen as sum types as they=20
don't contain the pointed type. Anyway, I believe that=20
dynamic_pointer_cast plays the same as any_cast, so we should have the=20
same name for both.
As Andrey, I don't believe that we need to go too far. I don't see the=20
need to require anything on some TypeErase concept.
We just need to allow to overload this function for several types. This=20
doesn't mean that we can not have a common implementation for some types.
[1] Adding Coherency Between |variant<Ts...>|, |any| and |optional<T>|
https://github.com/viboes/std-make/blob/master/doc/proposal/any_optional/fu=
ndamental_ts_improvements.md
--=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/.
--------------010207010305030302030802
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 05/09/15 11:12, David Krauss a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:7935FD03-ACA3-4D49-90B2-BDD107C2EF0B@gmail.com"
type=3D"cite">
<pre wrap=3D"">Abstract:
C++ has a couple built-in type erasure mechanisms, with respective faciliti=
es to recover the original object: polymorphic classes with dynamic_cast, a=
nd void pointers with static_cast or reinterpret_cast. A library facility r=
ecover_cast is proposed to analogously handle erasure classes like std::fun=
ction, any, and variant. Besides being a uniform, generic interface, it sim=
plifies implementation and and even improves performance.
Highlight:
template< typename T, typename ErasureClass >
constexpr auto *
recover_cast( ErasureClass cq * e ) noexcept; // cq is const or empty.
Requires: ErasureClass is capable of erasing T. (Thus, T shall not be void.=
A class may not assign semantics to =E2=80=9Cerased values of type void,=
=E2=80=9D and the implementation should diagnose an attempt to use recover_=
cast< void >( & e ) as a substitute for static_cast< void * &g=
t;( e ).)
Returns: ( remove_reference_t< T cq > * ) e.operator void const * () =
if e contains type T according to e.verify_type< T >(). Otherwise, nu=
llptr.
template< typename T, typename ErasureClass >
auto && // cq is const or empty. ref is & or &&.
recover_cast( ErasureClass cq ref e ) noexcept;
Requires: ErasureClass is capable of erasing T.
Effects: Let p be recover_cast< T >( & e ). If p is a null pointe=
r, throw an object of class bad_type_recovery. Otherwise, return static_cas=
t< T cq ref >( * p ).
Complete PDF: <a class=3D"moz-txt-link-freetext" href=3D"http://bit.ly/recc=
ast">http://bit.ly/reccast</a> <a class=3D"moz-txt-link-rfc2396E" href=3D"h=
ttp://bit.ly/reccast"><http://bit.ly/reccast></a>
</pre>
</blockquote>
<font size=3D"+1">Hi,<br>
<br>
glad to see you have find this problematic also. I've updated
yesterday my ongoing proposal [1]=C2=A0 with this same concern, but
your paper explain it much better;-)<br>
<br>
The generic cast I was talking about was a cast on sum types.
While variant and optional are clear sum types, function and any
can be seen as degenerate sum types. All of them contains the part
type.<br>
<br>
I don't know if smart pointer types can be seen as sum types as
they don't contain the pointed type. Anyway, I believe that
dynamic_pointer_cast plays the same as any_cast, so we should have
the same name for both.<br>
<br>
As Andrey, I don't believe that we need to go too far. I don't see
the need to require anything on some TypeErase concept. <br>
We just need to allow to overload this function for several types.
This doesn't mean that we can not have a common implementation for
some types.<br>
<br>
<br>
[1] </font>Adding Coherency Between <code>variant<Ts...></code>=
,
<code>any</code> and <code>optional<T></code><font size=3D"+1"><b=
r>
<a class=3D"moz-txt-link-freetext" href=3D"https://github.com/viboes/std-ma=
ke/blob/master/doc/proposal/any_optional/fundamental_ts_improvements.md">ht=
tps://github.com/viboes/std-make/blob/master/doc/proposal/any_optional/fund=
amental_ts_improvements.md</a><br>
</font>
</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" 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 />
--------------010207010305030302030802--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 10:17:30 +0800
Raw View
--Apple-Mail=_DD73C85C-EE70-440D-87F9-D43F4777FFC6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 9:30 AM, Vicente J. Botet Escriba <vice=
nte.botet@wanadoo.fr> wrote:
>=20
> As Andrey, I don't believe that we need to go too far. I don't see the ne=
ed to require anything on some TypeErase concept.=20
> We just need to allow to overload this function for several types. This d=
oesn't mean that we can not have a common implementation for some types.
The problem is that it=E2=80=99s difficult to implement the common protocol=
.. Besides any_cast, optional::operator*, and get(variant) having different =
specs, there have been implementation bugs and DRs against the handling of =
const and value category. Consider const&& references, for example.
The implementation experience so far shows that it=E2=80=99s a bad idea to =
have each class provide its own overload set.
Separately, most users call standard library functions, including cast func=
tions, as std::dynamic_pointer_cast, not considering ADL overloading =E2=80=
=94 and ADL can be fragile when template arguments bring in overloads from =
various libraries. The common implementation is more usable because std:: i=
s guaranteed to work. I touch on this in the paper, but perhaps should elab=
orate a little.
--=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=_DD73C85C-EE70-440D-87F9-D43F4777FFC6
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=9309=
=E2=80=9306, at 9:30 AM, Vicente J. Botet Escriba <<a href=3D"mailto:vic=
ente.botet@wanadoo.fr" class=3D"">vicente.botet@wanadoo.fr</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><span style=3D"=
font-family: Helvetica; font-size: large; 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; background-color: rgb(255, 255, 255); float: none; display: inlin=
e !important;" class=3D"">As Andrey, I don't believe that we need to go too=
far. I don't see the need to require anything on some TypeErase concept.<s=
pan class=3D"Apple-converted-space"> </span></span><br style=3D"font-f=
amily: Helvetica; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; line-height: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><s=
pan style=3D"font-family: Helvetica; font-size: large; font-style: normal; =
font-variant: normal; font-weight: normal; letter-spacing: normal; line-hei=
ght: normal; orphans: auto; text-align: start; text-indent: 0px; text-trans=
form: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-t=
ext-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; d=
isplay: inline !important;" class=3D"">We just need to allow to overload th=
is function for several types. This doesn't mean that we can not have a com=
mon implementation for some types.</span><br style=3D"font-family: Helvetic=
a; font-style: normal; font-variant: normal; font-weight: normal; letter-sp=
acing: 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></blockquot=
e></div><br class=3D""><div class=3D"">The problem is that it=E2=80=99s dif=
ficult to implement the common protocol. Besides <font face=3D"Courier" cla=
ss=3D"">any_cast</font>, <font face=3D"Courier" class=3D"">optional::operat=
or*</font>, and <font face=3D"Courier" class=3D"">get(variant)</font> havin=
g different specs, there have been implementation bugs and DRs against the =
handling of <font face=3D"Courier" class=3D"">const</font> and value catego=
ry. Consider <font face=3D"Courier" class=3D"">const&&</font> refer=
ences, for example.</div><div class=3D""><br class=3D""></div><div class=3D=
"">The implementation experience so far shows that it=E2=80=99s a bad idea =
to have each class provide its own overload set.</div><div class=3D""><br c=
lass=3D""></div><div class=3D"">Separately, most users call standard librar=
y functions, including cast functions, as <font face=3D"Courier" class=3D""=
>std::dynamic_pointer_cast</font>, not considering ADL overloading =E2=80=
=94 and ADL can be fragile when template arguments bring in overloads from =
various libraries. The common implementation is more usable because <font f=
ace=3D"Courier" class=3D"">std::</font> is guaranteed to work. I touch on t=
his in the paper, but perhaps should elaborate a little.</div><div class=3D=
""><br class=3D""></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" 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=_DD73C85C-EE70-440D-87F9-D43F4777FFC6--
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 10:34:58 +0800
Raw View
--Apple-Mail=_670EA219-0F26-4097-BF87-630474875AD6
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 9:30 AM, Vicente J. Botet Escriba <vice=
nte.botet@wanadoo.fr> wrote:
>=20
> As Andrey, I don't believe that we need to go too far. I don't see the ne=
ed to require anything on some TypeErase concept.=20
Also, to be sure, the benefits of the concept are already addressed in the =
paper, specifically the first two paragraphs of the rationale (with a littl=
e more at the end of paragraph 4). If you disagree with those points, then =
it=E2=80=99s better to mention them, but in any case please do read the act=
ual paper.
The concept provides added capabilities which are at present badly missing =
from any of the addressed classes. An argument against the concept should a=
ddress those capabilities.
--=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=_670EA219-0F26-4097-BF87-630474875AD6
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=9309=
=E2=80=9306, at 9:30 AM, Vicente J. Botet Escriba <<a href=3D"mailto:vic=
ente.botet@wanadoo.fr" class=3D"">vicente.botet@wanadoo.fr</a>> wrote:</=
div><br class=3D"Apple-interchange-newline"><div class=3D""><span style=3D"=
font-family: Helvetica; font-size: large; 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; background-color: rgb(255, 255, 255); float: none; display: inlin=
e !important;" class=3D"">As Andrey, I don't believe that we need to go too=
far. I don't see the need to require anything on some TypeErase concept.<s=
pan class=3D"Apple-converted-space"> </span></span><br style=3D"font-f=
amily: Helvetica; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; line-height: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""></=
div></blockquote></div><br class=3D""><div class=3D"">Also, to be sure, the=
benefits of the concept are already addressed in the paper, specifically t=
he first two paragraphs of the rationale (with a little more at the end of =
paragraph 4). If you disagree with those points, then it=E2=80=99s better t=
o mention them, but in any case please do read the actual paper.</div><div =
class=3D""><br class=3D""></div><div class=3D"">The concept provides added =
capabilities which are at present badly missing from any of the addressed c=
lasses. An argument against the concept should address those capabilities.<=
/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" 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=_670EA219-0F26-4097-BF87-630474875AD6--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 6 Sep 2015 10:58:31 +0300
Raw View
On 6 September 2015 at 03:21, David Krauss <potswa@gmail.com> wrote:
> My goal is not to =E2=80=9Cprovide a general facility to undo type erasur=
e=E2=80=9D and the
> proposal never says anything to that effect. You seem to be extrapolating
> from the title alone.
>
> What the paper says is =E2=80=9Canalogously handle erasure classes like
> std::function, any, and variant=E2=80=9D like dynamic_cast. Avoiding dupl=
ication of
> dynamic_cast semantics should be implicit, but I guess I should mention
> orthogonality in the rationale. Maybe add a new =E2=80=9Cusage=E2=80=9D s=
ection. If you want
> a dynamic_cast with your recover_cast, you need to write e.g. dynamic_cas=
t<
> derived * >( recover_cast< base * >( my_ptr_any ) ). I wouldn=E2=80=99t h=
ave it any
> other way.
>
> I welcome suggestions about alternate titles or bikeshedding, but let=E2=
=80=99s
> judge the proposal on semantic merits. I can=E2=80=99t really tell whethe=
r you=E2=80=99re
> ironically making a slippery slope argument about universality, or actual=
ly
> falling down that slippery slope.
Whether the proposed facility is generic or not seems very much like a "sem=
antic
merit" to me. Is this recover_cast extensible to user-defined 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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 16:34:01 +0800
Raw View
--Apple-Mail=_A9DD6272-A825-43D7-8053-F68DDDC5C376
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 3:58 PM, Ville Voutilainen <ville.vouti=
lainen@gmail.com> wrote:
>=20
> Whether the proposed facility is generic or not seems very much like a "s=
emantic
> merit" to me. Is this recover_cast extensible to user-defined types?
Yes, hence the Concept. I=E2=80=99ve added a =E2=80=9CSemantics=E2=80=9D se=
ction which should address most of your concerns.
I=E2=80=99m starting to think that maybe it shouldn=E2=80=99t be named with=
=E2=80=9C_cast.=E2=80=9D The built-in casts all have types identical to th=
e type-id argument, with references proxying value category. On the other h=
and, recover_cast behaves like get(tuple). Perhaps it should be called just=
recover, or something else.
--=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=_A9DD6272-A825-43D7-8053-F68DDDC5C376
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=9309=
=E2=80=9306, at 3:58 PM, Ville Voutilainen <<a href=3D"mailto:ville.vout=
ilainen@gmail.com" class=3D"">ville.voutilainen@gmail.com</a>> wrote:</d=
iv><br class=3D"Apple-interchange-newline"><div class=3D""><span style=3D"f=
ont-family: Helvetica; font-size: 12px; font-style: normal; font-variant: n=
ormal; font-weight: normal; letter-spacing: normal; line-height: normal; or=
phans: auto; text-align: start; text-indent: 0px; text-transform: none; whi=
te-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-widt=
h: 0px; float: none; display: inline !important;" class=3D"">Whether the pr=
oposed facility is generic or not seems very much like a "semantic</span><b=
r style=3D"font-family: Helvetica; font-size: 12px; font-style: normal; fon=
t-variant: normal; font-weight: normal; letter-spacing: normal; line-height=
: normal; orphans: auto; text-align: start; text-indent: 0px; text-transfor=
m: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text=
-stroke-width: 0px;" class=3D""><span 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: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; displa=
y: inline !important;" class=3D"">merit" to me. Is this recover_cast extens=
ible to user-defined types?</span><br 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: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""></div><=
/blockquote></div><br class=3D""><div class=3D"">Yes, hence the Concept. I=
=E2=80=99ve added a =E2=80=9CSemantics=E2=80=9D section which should addres=
s most of your concerns.</div><div class=3D""><br class=3D""></div><div cla=
ss=3D"">I=E2=80=99m starting to think that maybe it shouldn=E2=80=99t be na=
med with =E2=80=9C<font face=3D"Courier" class=3D"">_cast</font>.=E2=80=9D =
The built-in casts all have types identical to the type-id argument, with r=
eferences proxying value category. On the other hand, <font face=3D"Courier=
" class=3D"">recover_cast</font> behaves like <font face=3D"Courier" class=
=3D"">get(tuple)</font>. Perhaps it should be called just <font face=
=3D"Courier" class=3D"">recover</font>, or something else.</div><div class=
=3D""><br class=3D""></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" 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=_A9DD6272-A825-43D7-8053-F68DDDC5C376--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Sun, 6 Sep 2015 14:17:00 +0300
Raw View
On 06.09.2015 03:49, David Krauss wrote:
>
>> On 2015=E2=80=9309=E2=80=9306, at 2:07 AM, Andrey Semashev <andrey.semas=
hev@gmail.com
>> <mailto:andrey.semashev@gmail.com>> wrote:
>>
>> I can also add std::locale, which can be considered as a collection of
>> type erased facets.
>
> That problem is completely solved by use_facet (via facet ID=E2=80=99s an=
d
> dynamic_cast).
Well, there are specialized solutions for other eype erasure types as=20
well. If you aim for a generalized solution, you should probably think=20
of std::locale and similarly patterned types (i.e. those having multiple=20
embedded type erased objects) and offer if not the implementation then=20
interface and guidance.
>>> /Requires:/ ErasureClass is capable of erasing T. (Thus, T shall not be
>>> void. A class may not assign semantics to =E2=80=9Cerased values of typ=
e void,=E2=80=9D
>>> and the implementation should diagnose an attempt to use recover_cast<
>>> void >( & e ) as a substitute for static_cast< void * >( e ).)
>>
>> Why the special treatment of type void?
>
> Because it has no values, it can=E2=80=99t be the erased value. It=E2=80=
=99s already
> used by function and any to represent disengagement.
It can not represent a value, true, but void pointers can still be used=20
and be useful. For instance, one might want to pass a pointer to the=20
value stored in 'any' to a third party API without actually knowing the=20
type.
My point is that void should not be a special value for the tool or its=20
interface definition. There's no need for it anyway.
>> I didn't like that the protocol you described in pdf is intrusive
>> (i.e. requires support built into the type erasing type). I would very
>> much preferred it to be decoupled from the type erasing wrapper. This
>> would allow to support the tool in non-standard type erasing types.
>> Just remove the ErasureClass concept and use functional API, in the
>> std::begin/end style.
>
> None of the affected types support recover_cast without modification. It
> supports user-defined types that provide the two member functions.
One of which is a type conversion operator, which I find especially=20
troubling. To my mind type conversion operators are only justified when=20
the type can semantically be used interchangeably with another type. One=20
notable exception is conversion to bool, which incidentally is justified=20
only when the type can reasonably be used in conditional expressions.=20
Adding a conversion operator just to support recover_cast is too=20
encumbering on the type semantics.
> I don=E2=80=99t think it can be less intrusive, but please share any sugg=
estions.
Just define a free-standing function:
template< typename T, typename U >
T* recover_stored_object(U& e) noexcept
{
return nullptr;
}
- recover_stored_object returns non-null pointer iff e contains an=20
object which can be pointed to with T*.
- otherwise returns nullptr.
- [note: T may be void, in which case the returned pointer is non-null=20
if the stored object at all exists regardless of its type and nullptr=20
otherwise]
- the returned pointer shall remain valid as long as no modifiers are=20
called on e.
- recover_stored_object shall not throw.
- the default implementation always returns nullptr.
Then provide overloads found by ADL for all components supporting the=20
protocol. The details of how the pointer is extracted should be=20
recover_stored_object's and e's implementation detail.
recover_cast should be based on the recover_stored_object function (by=20
making unqualified calls to it) and the described above guarantees. In=20
particular, it should implement checks for nullptr and throw exceptions=20
where needed.
Also note that I deliberately made e in recover_stored_object=20
declaration a reference so that it is never null. This means that=20
recover_cast overload that takes a pointer should itself deal with the=20
null pointers on input.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Sun, 6 Sep 2015 21:58:36 +0800
Raw View
--Apple-Mail=_427807B9-1B23-48DD-BEF5-5866E80BB70E
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9306, at 7:17 PM, Andrey Semashev <andrey.semash=
ev@gmail.com> wrote:
>=20
> Well, there are specialized solutions for other eype erasure types as wel=
l. If you aim for a generalized solution, you should probably think of std:=
:locale and similarly patterned types (i.e. those having multiple embedded =
type erased objects) and offer if not the implementation then interface and=
guidance.
Perhaps someone will propose something like operator dynamic_cast, but it=
=E2=80=99s futile to try to encompass everything. The first step to general=
ization is to identify a pattern.
> It can not represent a value, true, but void pointers can still be used a=
nd be useful.
Retrieving a void* is different from retrieving a void value.
> For instance, one might want to pass a pointer to the value stored in 'an=
y' to a third party API without actually knowing the type.
Hence the void* accessor functionality =E2=80=94 which is missing from all =
the current classes, by the way.
> My point is that void should not be a special value for the tool or its i=
nterface definition. There's no need for it anyway.
That ship has sailed. As I mentioned, typeid(void) already represents disen=
gagement.
> One of which is a type conversion operator, which I find especially troub=
ling. To my mind type conversion operators are only justified when the type=
can semantically be used interchangeably with another type. One notable ex=
ception is conversion to bool, which incidentally is justified only when th=
e type can reasonably be used in conditional expressions. Adding a conversi=
on operator just to support recover_cast is too encumbering on the type sem=
antics.
Conversions to bool are now safe without any surprises or trickery because =
it can be made explicit. Same with conversion to void const*, except it=E2=
=80=99s even stricter. It won=E2=80=99t happen without an explicit cast exp=
ression.
The conversion to void const* has much lower complexity than recover, since=
it skips the type check. It=E2=80=99s a fast-track with different usage an=
d different behavior, hence a different name.
> Just define a free-standing function:
>=20
> template< typename T, typename U >
> T* recover_stored_object(U& e) noexcept
So, your solution is to only accept lvalues and only return pointers. And h=
ave each class reimplement the whole interface, not diverging from the stri=
ct, arbitrarily limiting spec. Very generic. And all the existing code expe=
cting rvalues can just decide whether or not to call move, I guess.
--=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=_427807B9-1B23-48DD-BEF5-5866E80BB70E
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=9309=
=E2=80=9306, at 7:17 PM, Andrey Semashev <<a href=3D"mailto:andrey.semas=
hev@gmail.com" class=3D"">andrey.semashev@gmail.com</a>> wrote:</div><br=
class=3D"Apple-interchange-newline"><div class=3D"">Well, there are specia=
lized solutions for other eype erasure types as well. If you aim for a gene=
ralized solution, you should probably think of std::locale and similarly pa=
tterned types (i.e. those having multiple embedded type erased objects) and=
offer if not the implementation then interface and guidance.<br class=3D""=
></div></blockquote><div><br class=3D""></div><div>Perhaps someone will pro=
pose something like <font face=3D"Courier" class=3D"">operator dynamic_cast=
</font>, but it=E2=80=99s futile to try to encompass everything. The first =
step to generalization is to identify a pattern.</div><br class=3D""><block=
quote type=3D"cite" class=3D""><div class=3D"">It can not represent a value=
, true, but void pointers can still be used and be useful.</div></blockquot=
e><div><br class=3D""></div>Retrieving a <font face=3D"Courier" class=
=3D"">void*</font> is different from retrieving a <font face=3D"C=
ourier" class=3D"">void</font> <i class=3D"">value</i>.</div><div clas=
s=3D""><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">=
For instance, one might want to pass a pointer to the value stored in 'any'=
to a third party API without actually knowing the type.<br class=3D""></di=
v></blockquote><div><br class=3D""></div><div>Hence the <font face=3D"Couri=
er" class=3D"">void*</font> accessor functionality =E2=80=94 which is missi=
ng from all the current classes, by the way.</div><div><br class=3D""></div=
><blockquote type=3D"cite" class=3D""><div class=3D"">My point is that void=
should not be a special value for the tool or its interface definition. Th=
ere's no need for it anyway.<br class=3D""></div></blockquote><div class=3D=
""><br class=3D""></div><div class=3D"">That ship has sailed. As I mentione=
d, <font face=3D"Courier" class=3D"">typeid(void)</font> already repre=
sents disengagement.</div><br class=3D""><blockquote type=3D"cite" class=3D=
""><div class=3D"">One of which is a type conversion operator, which I find=
especially troubling. To my mind type conversion operators are only justif=
ied when the type can semantically be used interchangeably with another typ=
e. One notable exception is conversion to bool, which incidentally is justi=
fied only when the type can reasonably be used in conditional expressions. =
Adding a conversion operator just to support recover_cast is too encumberin=
g on the type semantics.<br class=3D""></div></blockquote><div class=3D""><=
br class=3D""></div><div class=3D"">Conversions to <font face=3D"Courier" c=
lass=3D"">bool</font> are now safe without any surprises or trickery becaus=
e it can be made <font face=3D"Courier" class=3D"">explicit</font>. Sa=
me with conversion to <font face=3D"Courier" class=3D"">void const*</font>,=
except it=E2=80=99s even stricter. It won=E2=80=99t happen without an expl=
icit cast expression.</div><div class=3D""><br class=3D""></div><div class=
=3D"">The conversion to <font face=3D"Courier" class=3D"">void const*</font=
> has much lower complexity than <font face=3D"Courier" class=3D"">recover<=
/font>, since it skips the type check. It=E2=80=99s a fast-track with diffe=
rent usage and different behavior, hence a different name.</div><br class=
=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">Just define a fr=
ee-standing function:<br class=3D""><br class=3D""> template< type=
name T, typename U ><br class=3D""> T* recover_stored_object(U&=
; e) noexcept<br class=3D""></div></blockquote><div class=3D""><br class=3D=
""></div><div class=3D"">So, your solution is to only accept lvalues and on=
ly return pointers. And have each class reimplement the whole interface, no=
t diverging from the strict, arbitrarily limiting spec. Very generic. And a=
ll the existing code expecting rvalues can just decide whether or not to ca=
ll <font face=3D"Courier" class=3D"">move</font>, I guess.</div></div><br c=
lass=3D""></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" 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=_427807B9-1B23-48DD-BEF5-5866E80BB70E--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sun, 6 Sep 2015 16:17:56 +0200
Raw View
This is a multi-part message in MIME format.
--------------020707080000030902030801
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 06/09/15 04:34, David Krauss a =C3=A9crit :
>> On 2015=E2=80=9309=E2=80=9306, at 9:30 AM, Vicente J. Botet Escriba <vic=
ente.botet@wanadoo.fr> wrote:
>>
>> As Andrey, I don't believe that we need to go too far. I don't see the n=
eed to require anything on some TypeErase concept.
> Also, to be sure, the benefits of the concept are already addressed in th=
e paper, specifically the first two paragraphs of the rationale (with a lit=
tle more at the end of paragraph 4). If you disagree with those points, the=
n it=E2=80=99s better to mention them, but in any case please do read the a=
ctual paper.
Of course I did. It is not that I'm against the concept ErasureClass you=20
propose (I have not considered this yet), but I want the user to be able=20
to customize the cast on its own classes without relying on=20
ErasureClass, the function must be customizable by itself. If we agree=20
on this point we can discuss on how this can be done. Classes satisfying=20
your concept could take advantage of your common implementation.
> The concept provides added capabilities which are at present badly missin=
g from any of the addressed classes. An argument against the concept should=
address those capabilities.
>
I think that it is easier for the user to understand what recover_cast=20
do by defining it directly without any idea of ErasureClass concept than=20
by defining an implementation to your concept. I don't thing the=20
implementation of this cast is complex for any of the classes you have=20
mentioned.
I believe the major problem is that each class is providing an specific=20
interface. Once we decide to have the same for all of them the semantic=20
will be clearer. Could you share what were the difficulties you found=20
(if any) defining this recover_cast on these classes without requiring=20
them to be a model of your ErasureClass concept?
Besides the different approach, I don't like the concepts that requires=20
member function, I prefer concepts relying on free functions or on builtins=
..
I guess that the constrains are
e.operator void const *()
e.verify_type<T>()
e.verify_type<U>()
and not
v.operator void const *()
v.verify_type<T>()
v.verify_type<U>()
or I didn't understood the concept.
BTW, it seems tat there is a typo in
e.verify_type<void>() - Equal to true if o does not have any type-erased=20
value, else false
It should be e and not o.
Vicente
--=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/.
--------------020707080000030902030801
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 06/09/15 04:34, David Krauss a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:991C1206-8E03-4144-A718-CEBF15FE8690@gmail.com"
type=3D"cite">
<pre wrap=3D"">
</pre>
<blockquote type=3D"cite">
<pre wrap=3D"">On 2015=E2=80=9309=E2=80=9306, at 9:30 AM, Vicente J=
.. Botet Escriba <a class=3D"moz-txt-link-rfc2396E" href=3D"mailto:vicente.b=
otet@wanadoo.fr"><vicente.botet@wanadoo.fr></a> wrote:
As Andrey, I don't believe that we need to go too far. I don't see the need=
to require anything on some TypeErase concept.=20
</pre>
</blockquote>
<pre wrap=3D"">
Also, to be sure, the benefits of the concept are already addressed in the =
paper, specifically the first two paragraphs of the rationale (with a littl=
e more at the end of paragraph 4). If you disagree with those points, then =
it=E2=80=99s better to mention them, but in any case please do read the act=
ual paper.
</pre>
</blockquote>
Of course I did. It is not that I'm against the concept ErasureClass
you propose (I have not considered this yet), but I want the user to
be able to customize the cast on its own classes without relying on
ErasureClass, the function must be customizable by itself. If we
agree on this point we can discuss on how this can be done. Classes
satisfying your concept could take advantage of your common
implementation.<br>
<blockquote
cite=3D"mid:991C1206-8E03-4144-A718-CEBF15FE8690@gmail.com"
type=3D"cite">
<pre wrap=3D"">
The concept provides added capabilities which are at present badly missing =
from any of the addressed classes. An argument against the concept should a=
ddress those capabilities.
</pre>
</blockquote>
<br>
I think that it is easier for the user to understand what
recover_cast do by defining it directly without any idea of
ErasureClass concept than by defining an implementation to your
concept. I don't thing the implementation of this cast is complex
for any of the classes you have mentioned. <br>
I believe the major problem is that each class is providing an
specific interface. Once we decide to have the same for all of them
the semantic will be clearer.=C2=A0 Could you share what were the
difficulties you found (if any) defining this recover_cast on these
classes without requiring them to be a model of your ErasureClass
concept?=C2=A0 <br>
<br>
Besides the different approach, I don't like the concepts that
requires member function, I prefer concepts relying on free
functions or on builtins.<br>
<br>
I guess that the constrains are <br>
=C2=A0=C2=A0=C2=A0 e.operator void const *() <br>
=C2=A0=C2=A0=C2=A0 e.verify_type<T>()<br>
=C2=A0=C2=A0=C2=A0 e.verify_type<U>()<br>
<br>
and not=C2=A0 <br>
<br>
=C2=A0=C2=A0=C2=A0 v.operator void const *()<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
=C2=A0=C2=A0=C2=A0 v.verify_type<T>()<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
=C2=A0=C2=A0=C2=A0 v.verify_type<U>()<br>
<br>
or I didn't understood the concept.<br>
<br>
BTW, it seems tat there is a typo in <br>
<br>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
e.verify_type<void>() - Equal to true if o does not have any
type-erased value, else false<br>
<br>
It should be e and not o.<br>
<br>
Vicente<br>
</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" 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 />
--------------020707080000030902030801--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Sun, 06 Sep 2015 23:17:31 +0300
Raw View
On Sunday 06 September 2015 21:58:36 David Krauss wrote:
> > On 2015=E2=80=9309=E2=80=9306, at 7:17 PM, Andrey Semashev <andrey.sema=
shev@gmail.com>
> > wrote:
> >=20
> > It can not represent a value, true, but void pointers can still be used
> > and be useful.
> Retrieving a void* is different from retrieving a void value.
There are no void values, so I'm not sure what you mean here.
=20
> > For instance, one might want to pass a pointer to the value stored in
> > 'any' to a third party API without actually knowing the type.
> Hence the void* accessor functionality =E2=80=94 which is missing from al=
l the
> current classes, by the way.
> > My point is that void should not be a special value for the tool or its
> > interface definition. There's no need for it anyway.
> That ship has sailed. As I mentioned, typeid(void) already represents
> disengagement.
Not sure I follow here either. Could you elaborate, please?
> > One of which is a type conversion operator, which I find especially
> > troubling. To my mind type conversion operators are only justified when
> > the type can semantically be used interchangeably with another type. On=
e
> > notable exception is conversion to bool, which incidentally is justifie=
d
> > only when the type can reasonably be used in conditional expressions.
> > Adding a conversion operator just to support recover_cast is too
> > encumbering on the type semantics.
> Conversions to bool are now safe without any surprises or trickery becaus=
e
> it can be made explicit. Same with conversion to void const*, except it=
=E2=80=99s
> even stricter. It won=E2=80=99t happen without an explicit cast expressio=
n.
The semantic difference is not removed with explicit type conversion=20
operators, if that's what you mean.
> The conversion to void const* has much lower complexity than recover, sin=
ce
> it skips the type check. It=E2=80=99s a fast-track with different usage a=
nd
> different behavior, hence a different name.
The implementation of recover_stored_object is free to take any shortcuts=
=20
possible, I don't see the problem here. Also I don't see the point of havin=
g a=20
separate function for obtaining void*.
> > Just define a free-standing function:
> > template< typename T, typename U >
> > T* recover_stored_object(U& e) noexcept
>=20
> So, your solution is to only accept lvalues and only return pointers. And
> have each class reimplement the whole interface, not diverging from the
> strict, arbitrarily limiting spec. Very generic.
recover_stored_object doesn't implement the whole interface, only what I=20
described. Call it an extension API. I didn't describe recover_cast because=
=20
its interface (the actual public interface users will mostly use) is pretty=
=20
much what you initially described. I.e. it can support both pointers and=20
references (with exceptions).
> And all the existing code
> expecting rvalues can just decide whether or not to call move, I guess.
recover_cast could potentially support rvalues, although I don't see how th=
at=20
would be safe since the returned pointer would likely be dead as soon as th=
e=20
rvalue is destroyed. I'd say rvalues should be prohibited.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 7 Sep 2015 08:24:55 +0800
Raw View
--Apple-Mail=_D0F9B96D-503E-4B26-B4CF-7C16DCBAE2AA
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9307, at 4:17 AM, Andrey Semashev <andrey.semash=
ev@gmail.com> wrote:
>=20
>> Retrieving a void* is different from retrieving a void value.
>=20
> There are no void values, so I'm not sure what you mean here.
recover returns a reference to the current value, or fails. That=E2=80=99s =
the invariant. There are no void values.
>> That ship has sailed. As I mentioned, typeid(void) already represents
>> disengagement.
>=20
> Not sure I follow here either. Could you elaborate, please?
Already did, in this thread and in the paper.
> The semantic difference is not removed with explicit type conversion=20
> operators, if that's what you mean.
Conversion semantics are properly represented by the proposed conversion.
>> The conversion to void const* has much lower complexity than recover, si=
nce
>> it skips the type check. It=E2=80=99s a fast-track with different usage =
and
>> different behavior, hence a different name.
>=20
> The implementation of recover_stored_object is free to take any shortcuts=
=20
> possible, I don't see the problem here. Also I don't see the point of hav=
ing a=20
> separate function for obtaining void*.
recover checks whether there=E2=80=99s a type match. You=E2=80=99re suggest=
ing to disable type checking when the requested type is void. One specializ=
ation with very different semantics from the others.
Not a problem, I suppose, if what you want is a mix-and-match God conversio=
n with no guarantees on complexity or semantics, except that something goes=
in and something of type T comes out. If you want such a thing, I think it=
=E2=80=99s better to synthesize it from well-defined primitives.
>>> Just define a free-standing function:
>>> template< typename T, typename U >
>>> T* recover_stored_object(U& e) noexcept
>>=20
>> So, your solution is to only accept lvalues and only return pointers. An=
d
>> have each class reimplement the whole interface, not diverging from the
>> strict, arbitrarily limiting spec. Very generic.
>=20
> recover_stored_object doesn't implement the whole interface, only what I=
=20
> described. Call it an extension API. I didn't describe recover_cast becau=
se=20
> its interface (the actual public interface users will mostly use) is pret=
ty=20
> much what you initially described. I.e. it can support both pointers and=
=20
> references (with exceptions).
>=20
>> And all the existing code
>> expecting rvalues can just decide whether or not to call move, I guess.
>=20
> recover_cast could potentially support rvalues, although I don't see how =
that=20
> would be safe since the returned pointer would likely be dead as soon as =
the=20
> rvalue is destroyed. I'd say rvalues should be prohibited.
--=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=_D0F9B96D-503E-4B26-B4CF-7C16DCBAE2AA
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=9309=
=E2=80=9307, at 4:17 AM, Andrey Semashev <<a href=3D"mailto:andrey.semas=
hev@gmail.com" class=3D"">andrey.semashev@gmail.com</a>> wrote:</div><br=
class=3D"Apple-interchange-newline"><div class=3D""><blockquote type=3D"ci=
te" class=3D"">Retrieving a void* is different from retrieving a void value=
..<br class=3D""></blockquote><br class=3D"">There are no void values, so I'=
m not sure what you mean here.<br class=3D""></div></blockquote><div><br cl=
ass=3D""></div><div><font face=3D"Courier" class=3D"">recover</font> return=
s a reference to the current value, or fails. That=E2=80=99s the invariant.=
There are no void values.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D""><blockquote type=3D"cite" class=3D"">That ship has=
sailed. As I mentioned, typeid(void) already represents<br class=3D"">dise=
ngagement.<br class=3D""></blockquote><br class=3D"">Not sure I follow here=
either. Could you elaborate, please?<br class=3D""></div></blockquote><div=
><br class=3D""></div><div>Already did, in this thread and in the paper.</d=
iv><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">The =
semantic difference is not removed with explicit type conversion <br class=
=3D"">operators, if that's what you mean.<br class=3D""></div></blockquote>=
<div><br class=3D""></div><div>Conversion semantics are properly represente=
d by the proposed conversion.</div><br class=3D""><blockquote type=3D"cite"=
class=3D""><div class=3D""><blockquote type=3D"cite" class=3D"">The conver=
sion to void const* has much lower complexity than recover, since<br class=
=3D"">it skips the type check. It=E2=80=99s a fast-track with different usa=
ge and<br class=3D"">different behavior, hence a different name.<br class=
=3D""></blockquote><br class=3D"">The implementation of recover_stored_obje=
ct is free to take any shortcuts <br class=3D"">possible, I don't see the p=
roblem here. Also I don't see the point of having a <br class=3D"">separate=
function for obtaining void*.<br class=3D""></div></blockquote><div><br cl=
ass=3D""></div><div><font face=3D"Courier" class=3D"">recover</font> checks=
whether there=E2=80=99s a type match. You=E2=80=99re suggesting to disable=
type checking when the requested type is <font face=3D"Courier" class=3D""=
>void</font>. One specialization with very different semantics from the oth=
ers.</div><div><br class=3D""></div><div>Not a problem, I suppose, if what =
you want is a mix-and-match God conversion with no guarantees on complexity=
or semantics, except that something goes in and something of type T comes =
out. If you want such a thing, I think it=E2=80=99s better to synthesize it=
from well-defined primitives.</div><br class=3D""><blockquote type=3D"cite=
" class=3D""><div class=3D""><blockquote type=3D"cite" class=3D""><blockquo=
te type=3D"cite" class=3D"">Just define a free-standing function:<br class=
=3D""> template< typename T, typename U ><br class=3D""> T* recover_s=
tored_object(U& e) noexcept<br class=3D""></blockquote><br class=3D"">S=
o, your solution is to only accept lvalues and only return pointers. And<br=
class=3D"">have each class reimplement the whole interface, not diverging =
from the<br class=3D"">strict, arbitrarily limiting spec. Very generic.<br =
class=3D""></blockquote><br class=3D"">recover_stored_object doesn't implem=
ent the whole interface, only what I <br class=3D"">described. Call it an e=
xtension API. I didn't describe recover_cast because <br class=3D"">its int=
erface (the actual public interface users will mostly use) is pretty <br cl=
ass=3D"">much what you initially described. I.e. it can support both pointe=
rs and <br class=3D"">references (with exceptions).<br class=3D""><br class=
=3D""><blockquote type=3D"cite" class=3D"">And all the existing code<br cla=
ss=3D"">expecting rvalues can just decide whether or not to call move, I gu=
ess.<br class=3D""></blockquote><br class=3D"">recover_cast could potential=
ly support rvalues, although I don't see how that <br class=3D"">would be s=
afe since the returned pointer would likely be dead as soon as the <br clas=
s=3D"">rvalue is destroyed. I'd say rvalues should be prohibited.<br class=
=3D""></div></blockquote></div><br class=3D""></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" 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=_D0F9B96D-503E-4B26-B4CF-7C16DCBAE2AA--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Mon, 7 Sep 2015 13:53:59 +0300
Raw View
On 07.09.2015 03:24, David Krauss wrote:
>
>> On 2015=E2=80=9309=E2=80=9307, at 4:17 AM, Andrey Semashev <andrey.semas=
hev@gmail.com
>> <mailto:andrey.semashev@gmail.com>> wrote:
>>
>>> Retrieving a void* is different from retrieving a void value.
>>
>> There are no void values, so I'm not sure what you mean here.
>
> recover returns a reference to the current value, or fails. That=E2=80=99=
s the
> invariant. There are no void values.
It returns a reference in one version and a pointer in the other. You=20
can restrict void to only the pointer version.
>>> That ship has sailed. As I mentioned, typeid(void) already represents
>>> disengagement.
>>
>> Not sure I follow here either. Could you elaborate, please?
>
> Already did, in this thread and in the paper.
Sorry, I didn't find that in the paper. I did find you mentioning void=20
being used for disengagement for 'function' and 'any' but no mention of=20
typeid(void). So I'm still unsure what you mean.
I'm going to guess that you suggest that an empty state of 'any' or=20
'function' has a reference to typeid(void) attached to it somehow. If=20
that's the case then (a) that's not necessarilly so (in fact, I'd be=20
surprised by an implementation that does that) and (b) that's irrelevant=20
to the proposal.
>> The semantic difference is not removed with explicit type conversion
>> operators, if that's what you mean.
>
> Conversion semantics are properly represented by the proposed conversion.
You're either missing my point, or we're talking of different things=20
here. I'll try again, by adding a type conversion operator to a type=20
you're basically saying that objects of this type can be interchanged=20
with objects of another type. By adding 'operator void*' to, e.g. 'any'=20
you say that 'any' is basically some kind of pointer, which it is not.=20
This seems to be supported in your paper:
[quote]
An ErasureClass object behaves as a pointer when explicitly cast to
void const *, but otherwise it should behave as a proxy.
[/quote]
Again, 'any' is not a pointer and should not behave as one. Same for=20
'variant' and even 'optional', even though it provides 'operator->' as a=20
syntax sugar.
>>> The conversion to void const* has much lower complexity than recover,
>>> since
>>> it skips the type check. It=E2=80=99s a fast-track with different usage=
and
>>> different behavior, hence a different name.
>>
>> The implementation of recover_stored_object is free to take any shortcut=
s
>> possible, I don't see the problem here. Also I don't see the point of
>> having a
>> separate function for obtaining void*.
>
> recover checks whether there=E2=80=99s a type match. You=E2=80=99re sugge=
sting to
> disable type checking when the requested type is void. One
> specialization with very different semantics from the others.
The type check is an implementation detail. It is not important how=20
recover_stored_object effect is achieved, and the way I described the=20
effect the semantics wrt void is not any different.
You selected type void in your paper to embody special semantics of=20
checking whether the type erasing object contains a value (of any type).=20
I'm saying such distinction is not necessary if you say that the=20
function obtains a valid pointer to the stored value or null.
There's another point also. A two function interface like you proposed=20
can be suboptimal in some cases. Let's see 'any' for example (I'll be=20
using Boost.Any as a reference implementation; having its source at hand=20
may simplify understanding my further comment).
As I understand recover_cast can be implemented like this in your proposal:
template< typename T, typename U >
T* recover_cast(U* e) noexcept
{
if (e->template verify_type<T>())
return static_cast< T* >(static_cast< const void* >(*e));
return nullptr;
}
There are also reference-based versions and more cruft to propagate cv=20
qualification but that's not important now.
Assuming that U is 'any', 'any::verify_type' has to check for the type,=20
which in Boost.Any would result in a virtual call. Theoretically, it is=20
possible to avoid the virtual call by storing the reference to type_info=20
in the base class of the internal holder object for the value, but I=20
suppose this won't be done in order not to increase memory footprint.
Then, if the check succeeds, you call the 'operator void*'. It would be=20
problematic to implement in Boost.Any because you do not provide the=20
type of the value, and 'boost::any' implementation is no longer able to=20
upcast the pointer to the internal value holder (see how 'any_cast' is=20
implemented). There are two solutions to this problem: store the void*=20
pointer to the stored value in the base class of the holder or provide=20
another virtual function for obtaining it. The first solution, again,=20
increases memory footprint, so it is undesirable. The second one also=20
somewhat increases the footprint (due to growth of virtual function=20
tables) but what's more important it adds a runtime penalty of a virtual=20
call. Note that this penalty is not required for 'any_cast' or my=20
proposed 'recover_stored_object', which by the way can be implemented=20
through the same facilities 'any_cast' already uses.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 7 Sep 2015 22:20:29 +0800
Raw View
--Apple-Mail=_4F2EB7AD-061E-4E2B-8B83-4D8401355B19
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9309=E2=80=9307, at 6:53 PM, Andrey Semashev <andrey.semash=
ev@gmail.com> wrote:
>=20
> Sorry, I didn't find that in the paper. I did find you mentioning void be=
ing used for disengagement for 'function' and 'any' but no mention of typei=
d(void). So I'm still unsure what you mean.
typeid(void) is what function and any use for disengagement.
> I'm going to guess that you suggest that an empty state of 'any' or 'func=
tion' has a reference to typeid(void) attached to it somehow. If that's the=
case then (a) that's not necessarilly so (in fact, I'd be surprised by an =
implementation that does that) and (b) that's irrelevant to the proposal.
It appears to be so at the interface level, so if I tried to say differentl=
y it would create inconsistency. It may be so at the implementation level (=
in my implementation, there=E2=80=99s literally a typeid(void)), and confli=
cting with that could create implementation difficulties.
Besides that, insinuating the existence of a void value is just nonsense.
> Again, 'any' is not a pointer and should not behave as one. Same for 'var=
iant' and even 'optional', even though it provides 'operator->' as a syntax=
sugar.
The value of the void* has the same information content as the value of the=
any, except that the dynamic type info is stripped out.
> The type check is an implementation detail. It is not important how recov=
er_stored_object effect is achieved, and the way I described the effect the=
semantics wrt void is not any different.
No, the type check generates an observable failure route: throwing an excep=
tion or returning nullptr. You=E2=80=99re suggesting to change the purpose =
and behavior. Not implementation details.
> You selected type void in your paper to embody special semantics of check=
ing whether the type erasing object contains a value (of any type). I'm say=
ing such distinction is not necessary if you say that the function obtains =
a valid pointer to the stored value or null.
I selected verify_type<void> for disengagement because it allows all existi=
ng standardized or standard-tracked classes to be easily wrapped with the n=
ew interface. Since void represents the absence of a value, it seems quite =
a reasonable interface for function, any, and everything else.
Yes, I could define recover<void> to be unsafe. The point of recover is to =
be safe, so I went a different route.
> There's another point also. A two function interface like you proposed ca=
n be suboptimal in some cases. Let's see 'any' for example (I'll be using B=
oost.Any as a reference implementation; having its source at hand may simpl=
ify understanding my further comment).
>=20
> As I understand recover_cast can be implemented like this in your proposa=
l:
>=20
> template< typename T, typename U >
> T* recover_cast(U* e) noexcept
> {
> if (e->template verify_type<T>())
> return static_cast< T* >(static_cast< const void* >(*e));
> return nullptr;
> }
No, but close enough. I thought the proposal already provided a lot of pseu=
docode=E2=80=A6
> There are also reference-based versions and more cruft to propagate cv qu=
alification but that's not important now.
That attitude is exactly why a generic function in namespace std needs to b=
e the sole point of access.
> Assuming that U is 'any', 'any::verify_type' has to check for the type, w=
hich in Boost.Any would result in a virtual call. Theoretically, it is poss=
ible to avoid the virtual call by storing the reference to type_info in the=
base class of the internal holder object for the value, but I suppose this=
won't be done in order not to increase memory footprint.
>=20
> Then, if the check succeeds, you call the 'operator void*'. It would be p=
roblematic to implement in Boost.Any because you do not provide the type of=
the value, and 'boost::any' implementation is no longer able to upcast the=
pointer to the internal value holder (see how 'any_cast' is implemented).
>=20
> There are two solutions to this problem: store the void* pointer to the s=
tored value in the base class of the holder or provide another virtual func=
tion for obtaining it. The first solution, again, increases memory footprin=
t, so it is undesirable. The second one also somewhat increases the footpri=
nt (due to growth of virtual function tables) but what's more important it =
adds a runtime penalty of a virtual call.
Third solution (libstdc++ experimental::any and std::function model): use a=
single pointer-to-function taking various opcodes. Fourth solution (cxx_fu=
nction::function model): use a constexpr table of function pointers, which =
is slightly more efficient than a vtable. Anyway, in such libraries, the on=
ly possible storage locations are inside the wrapper and right after a poin=
ter in the wrapper. This pretty much holds true up to fancy pointers of cus=
tom allocators. You don=E2=80=99t really need an indirect dispatch to handl=
e just two cases; it=E2=80=99s easy to encode the access path in a global t=
able. (Solution #5.) This pretty much holds true up to fancy pointers of cu=
stom allocators. Sad fact is, most implementations aren=E2=80=99t completel=
y optimized.
Boost is a bit of an edge case, since it doesn=E2=80=99t implement any smal=
l-object optimization and the =E2=80=9Ccontrol=E2=80=9D info is actually pa=
rt of the erasure structure =E2=80=94 when it=E2=80=99s disengaged, it real=
ly knows nothing. Still, the held object is invariably just after the vtabl=
e of the polymorphic =E2=80=9Cholder,=E2=80=9D and calculating that address=
is good enough for gummint work. I admit, this does fail on highly-aligned=
types.
The benefit of the small object optimization outweighs any of the various c=
osts you mentioned. The Boost architecture is simple, but it would be surpr=
ising to see it elsewhere. Still, it can be adjusted to support ErasureClas=
s perfectly, no compromises: Point the internal content pointer at the eras=
ed object and store the vtable/global-table pointer in the preceding bytes.
> Note that this penalty is not required for 'any_cast' or my proposed 'rec=
over_stored_object', which by the way can be implemented through the same f=
acilities 'any_cast' already uses.
Passing void to boost::any won=E2=80=99t help it navigate its erasure, it=
=E2=80=99ll generate a template instantiation error because holder<void> wo=
uld have a member of type void.
--=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=_4F2EB7AD-061E-4E2B-8B83-4D8401355B19
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=9309=
=E2=80=9307, at 6:53 PM, Andrey Semashev <<a href=3D"mailto:andrey.semas=
hev@gmail.com" class=3D"">andrey.semashev@gmail.com</a>> wrote:</div><br=
class=3D"Apple-interchange-newline"><div class=3D"">Sorry, I didn't find t=
hat in the paper. I did find you mentioning void being used for disengageme=
nt for 'function' and 'any' but no mention of typeid(void). So I'm still un=
sure what you mean.</div></blockquote><div><br class=3D""></div><div><font =
face=3D"Courier" class=3D"">typeid(void)</font> is what function and any us=
e for disengagement.</div><br class=3D""><blockquote type=3D"cite" class=3D=
""><div class=3D"">I'm going to guess that you suggest that an empty state =
of 'any' or 'function' has a reference to typeid(void) attached to it someh=
ow. If that's the case then (a) that's not necessarilly so (in fact, I'd be=
surprised by an implementation that does that) and (b) that's irrelevant t=
o the proposal.<br class=3D""></div></blockquote><div><br class=3D""></div>=
<div>It appears to be so at the interface level, so if I tried to say diffe=
rently it would create inconsistency. It may be so at the implementation le=
vel (in my implementation, there=E2=80=99s literally a <font face=3D"Courie=
r" class=3D"">typeid(void)</font>), and conflicting with that could create =
implementation difficulties.</div><div><br class=3D""></div><div>Besides th=
at, insinuating the existence of a void value is just nonsense.</div><br cl=
ass=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">Again, 'any' =
is not a pointer and should not behave as one. Same for 'variant' and even =
'optional', even though it provides 'operator->' as a syntax sugar.<br c=
lass=3D""></div></blockquote><div><br class=3D""></div><div>The value of th=
e <font face=3D"Courier" class=3D"">void*</font> has the same informat=
ion content as the value of the <font face=3D"Courier" class=3D"">any<=
/font>, except that the dynamic type info is stripped out.</div><br class=
=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">The type check i=
s an implementation detail. It is not important how recover_stored_object e=
ffect is achieved, and the way I described the effect the semantics wrt voi=
d is not any different.<br class=3D""></div></blockquote><div><br class=3D"=
"></div><div>No, the type check generates an observable failure route: thro=
wing an exception or returning <font face=3D"Courier" class=3D"">nullptr</f=
ont>. You=E2=80=99re suggesting to change the purpose and behavior. Not imp=
lementation details.</div><br class=3D""><blockquote type=3D"cite" class=3D=
""><div class=3D"">You selected type void in your paper to embody special s=
emantics of checking whether the type erasing object contains a value (of a=
ny type). I'm saying such distinction is not necessary if you say that the =
function obtains a valid pointer to the stored value or null.<br class=3D""=
></div></blockquote><div><br class=3D""></div><div>I selected <font face=3D=
"Courier" class=3D"">verify_type<void></font> for disengagement =
because it allows all existing standardized or standard-tracked classes to =
be easily wrapped with the new interface. Since <span style=3D"font-fa=
mily: Courier;" class=3D"">void</span> represents the absence of a val=
ue, it seems quite a reasonable interface for <font face=3D"Courier" class=
=3D"">function</font>, <font face=3D"Courier" class=3D"">any</font>, and ev=
erything else.</div><div><br class=3D""></div><div>Yes, I could define <fon=
t face=3D"Courier" class=3D"">recover<void></font> to be unsafe. The =
point of <font face=3D"Courier" class=3D"">recover</font> is to be safe, so=
I went a different route.</div><br class=3D""><blockquote type=3D"cite" cl=
ass=3D""><div class=3D"">There's another point also. A two function interfa=
ce like you proposed can be suboptimal in some cases. Let's see 'any' for e=
xample (I'll be using Boost.Any as a reference implementation; having its s=
ource at hand may simplify understanding my further comment).<br class=3D""=
><br class=3D"">As I understand recover_cast can be implemented like this i=
n your proposal:<br class=3D""><br class=3D""> template< typename =
T, typename U ><br class=3D""> T* recover_cast(U* e) noexcept<br c=
lass=3D""> {<br class=3D""> if (e->template veri=
fy_type<T>())<br class=3D""> return sta=
tic_cast< T* >(static_cast< const void* >(*e));<br class=3D""> =
return nullptr;<br class=3D""> }<br class=3D""></di=
v></blockquote><div><br class=3D""></div><div>No, but close enough. I thoug=
ht the proposal already provided a lot of pseudocode=E2=80=A6</div><br clas=
s=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">There are also =
reference-based versions and more cruft to propagate cv qualification but t=
hat's not important now.<br class=3D""></div></blockquote><div><br class=3D=
""></div><div>That attitude is exactly why a generic function in <font face=
=3D"Courier" class=3D"">namespace std</font> needs to be the sole point of =
access.</div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=
=3D"">Assuming that U is 'any', 'any::verify_type' has to check for the typ=
e, which in Boost.Any would result in a virtual call. Theoretically, it is =
possible to avoid the virtual call by storing the reference to type_info in=
the base class of the internal holder object for the value, but I suppose =
this won't be done in order not to increase memory footprint.<br class=3D""=
><br class=3D"">Then, if the check succeeds, you call the 'operator void*'.=
It would be problematic to implement in Boost.Any because you do not provi=
de the type of the value, and 'boost::any' implementation is no longer able=
to upcast the pointer to the internal value holder (see how 'any_cast' is =
implemented). </div></blockquote><div><blockquote type=3D"cite" class=3D"">=
<br class=3D""></blockquote></div><blockquote type=3D"cite" class=3D""><div=
class=3D"">There are two solutions to this problem: store the void* pointe=
r to the stored value in the base class of the holder or provide another vi=
rtual function for obtaining it. The first solution, again, increases memor=
y footprint, so it is undesirable. The second one also somewhat increases t=
he footprint (due to growth of virtual function tables) but what's more imp=
ortant it adds a runtime penalty of a virtual call. </div></blockquote><div=
><br class=3D""></div><div>Third solution (libstdc++ <font face=3D"Courier"=
class=3D"">experimental::any</font> and <font face=3D"Courier" class=3D"">=
std::function</font> model): use a single pointer-to-function taking variou=
s opcodes. Fourth solution (<font face=3D"Courier" class=3D"">cxx_function:=
:function</font> model): use a constexpr table of function pointers, which =
is slightly more efficient than a vtable. Anyway, in such libraries, the on=
ly possible storage locations are inside the wrapper and right after a poin=
ter in the wrapper. This pretty much holds true up to fancy pointers of cus=
tom allocators. You don=E2=80=99t really need an indirect dispatch to handl=
e just two cases; it=E2=80=99s easy to encode the access path in a global t=
able. (Solution #5.) This pretty much holds true up to fancy pointers of cu=
stom allocators. Sad fact is, most implementations aren=E2=80=99t completel=
y optimized.</div><div><br class=3D""></div><div>Boost is a bit of an edge =
case, since it doesn=E2=80=99t implement any small-object optimization and =
the =E2=80=9Ccontrol=E2=80=9D info is actually part of the erasure structur=
e =E2=80=94 when it=E2=80=99s disengaged, it really knows nothing. Still, t=
he held object is invariably just after the vtable of the polymorphic =E2=
=80=9Cholder,=E2=80=9D and calculating that address is good enough for gumm=
int work. I admit, this does fail on highly-aligned types.</div><div><br cl=
ass=3D""></div><div>The benefit of the small object optimization outweighs =
any of the various costs you mentioned. The Boost architecture is simple, b=
ut it would be surprising to see it elsewhere. Still, it can be adjusted to=
support ErasureClass perfectly, no compromises: Point the internal <font f=
ace=3D"Courier" class=3D"">content</font> pointer at the erased object and =
store the vtable/global-table pointer in the preceding bytes.</div><div><br=
class=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D"">Note=
that this penalty is not required for 'any_cast' or my proposed 'recover_s=
tored_object', which by the way can be implemented through the same facilit=
ies 'any_cast' already uses.<br class=3D""></div></blockquote></div><div cl=
ass=3D""><br class=3D""></div><div class=3D"">Passing <font face=3D"Courier=
" class=3D"">void</font> to <font face=3D"Courier" class=3D"">boost::any</f=
ont> won=E2=80=99t help it navigate its erasure, it=E2=80=99ll generate a t=
emplate instantiation error because <font face=3D"Courier" class=3D"">holde=
r<void></font> would have a member of type <font face=3D"Courier" cla=
ss=3D"">void</font>.</div><div class=3D""><br class=3D""></div></body></htm=
l>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_4F2EB7AD-061E-4E2B-8B83-4D8401355B19--
.