Topic: Move destructor draft
Author: isocppgroup@denisbider.com
Date: Fri, 7 Aug 2015 13:47:13 -0700 (PDT)
Raw View
------=_Part_758_1083495404.1438980433169
Content-Type: multipart/alternative;
boundary="----=_Part_759_732086829.1438980433169"
------=_Part_759_732086829.1438980433169
Content-Type: text/plain; charset=UTF-8
Hello everyone,
I believe the destructive move Jesus is upon us!
I have uploaded the following draft:
http://www.denisbider.com/MoveDestructor.pdf
@Matthew:
> What if doing a memcpy is *wrong*? Now you've wasted a
> bunch of work copying data that isn't useful.
True. I have addressed this in the above draft.
@Edward:
> How does that deal with composition?
Same way constructors deal with composition. I invite you to check out the
above draft.
@Matthew:
> IMO the implicit behavior should definitely be the boring behavior,
> i.e. invoke a copy/move ctor and the regular dtor.
I disagree with this very passionately. This is a similar kind
of default-bundling as getting IE with Windows.
Move destructor invoking copy/move ctor:
- Prevents the move destructor from being able to always provide the
noexcept guarantee.
- Takes choice away from the user. The user may want to use destructive
move if it's available; but otherwise, something else.
- Provides trifling convenience than can be trivially provided with a
template along the lines of move_if_noexcept.
If you check out the draft, feedback would be appreciated.
On Friday, August 7, 2015 at 10:08:05 AM UTC-6, Matthew Woehlke wrote:
> On 2015-08-07 11:42, isocp...@denisbider.com <javascript:> wrote:
> > StringType* StringType::~StringType(void* d, StringType* s, std::size_t
> n=1);
> >
> > This would perform the destructive move of one or more objects as a
> > transaction, just like invoking keywords new or delete is a transaction.
>
> The "one *or more*" (emphasis added) part would be a significant
> departure from the current language rules. I'm having a hard time seeing
> the justification.
>
> The closest we have currently is delete[], which still calls each
> object's dtor individually.
>
> If nothing else, 'this' makes no sense in such a context, i.e. you are
> at least missing a 'static'.
>
> > It makes most sense to me that the implementation of this transactional
> > move concept performs the equivalent of memcpy for an object before
> calling
> > the move destructor. It makes things a lot simpler.
>
> ...and far less generic.
>
> What if doing a memcpy is *wrong*? Now you've wasted a bunch of work
> copying data that isn't useful.
>
> Having something like a cting-dtor has obvious benefit (don't waste work
> maintaining the old object in a valid state when it's about to be
> destroyed anyway). Having a cting-dtor *that can be trivial* has
> *enormous* obvious value; many, many objects can be trivially
> "relocated"... and indeed libraries already do this despite that it is
> UB; having a way to "bless" such operation has obvious benefit.
>
> I'm less convinced that there is significant benefit to optimizing
> corner cases. The *only* benefit, AFAICT, to e.g. the std::string case
> is merging the memcpy's for an array of such objects into a larger memcpy.
>
> Do you have benchmarks showing that this is a significant improvement?
> Keep in mind that the small memcpy will most likely be inlined, and that
> there is at least a branch per object in either case in addition to
> whatever memcpy(s) happen. (If the patch-up operator isn't inlined,
> that's probably going to swamp the memcpy(s).)
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_759_732086829.1438980433169
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hello everyone,</div><div><br></div><div>I believe th=
e destructive move Jesus is upon us!</div><div><br></div><div>=C2=A0I have =
uploaded the following draft:</div><div><br></div><div><a href=3D"http://ww=
w.denisbider.com/MoveDestructor.pdf">http://www.denisbider.com/MoveDestruct=
or.pdf</a></div><div><br></div><div><br></div><div>@Matthew:</div><div><br>=
</div><div>> What if doing a memcpy is *wrong*? Now you've wasted a =
</div><div>> bunch of work=C2=A0copying data that isn't useful. </di=
v><div><br></div><div>True. I have addressed this in the above draft.</div>=
<div><br></div><div><br></div><div>@Edward:</div><div><br></div><div>> H=
ow does that deal with composition?</div><div><br></div><div>Same way const=
ructors deal with composition. I invite you to check out the above draft.</=
div><div><br></div><div><br></div><div>@Matthew:</div><div><br></div><div>&=
gt; IMO the implicit behavior should definitely be the boring behavior,</di=
v><div>> i.e. invoke a copy/move ctor and the regular dtor.<br></div><di=
v><br></div><div>I disagree with this very passionately. This is a similar =
kind of=C2=A0default-bundling as getting IE with Windows.</div><div><br></d=
iv><div>Move destructor=C2=A0invoking copy/move ctor:</div><div><br></div><=
div>- Prevents the move destructor from being able to always provide the no=
except guarantee.</div><div><br></div><div>- Takes choice away from the use=
r. The user may want to use destructive move if it's available; but oth=
erwise, something else.</div><div><br></div><div>- Provides=C2=A0trifling c=
onvenience than can be trivially provided with a template along the lines o=
f <font face=3D"courier new,monospace">move_if_noexcept</font>.</div><div><=
br></div><div><br></div><div>If you=C2=A0check out the draft,=C2=A0feedback=
would be appreciated.</div><div><br><br>On Friday, August 7, 2015 at 10:08=
:05 AM UTC-6, Matthew Woehlke wrote:</div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: =
rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">On 2=
015-08-07 11:42, <a onmousedown=3D"this.href=3D'javascript:';return=
true;" onclick=3D"this.href=3D'javascript:';return true;" href=3D"=
javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"BE=
MXzlvXEAAJ">isocp...@denisbider.com</a> wrote:
<br>> StringType* StringType::~StringType(void* d, StringType* s, std::s=
ize_t n=3D1);
<br>>=20
<br>> This would perform the destructive move of one or more objects as =
a=20
<br>> transaction, just like invoking keywords new or delete is a transa=
ction.
<br>
<br>The "one *or more*" (emphasis added) part would be a signific=
ant
<br>departure from the current language rules. I'm having a hard time s=
eeing
<br>the justification.
<br>
<br>The closest we have currently is delete[], which still calls each
<br>object's dtor individually.
<br>
<br>If nothing else, 'this' makes no sense in such a context, i.e. =
you are
<br>at least missing a 'static'.
<br>
<br>> It makes most sense to me that the implementation of this transact=
ional=20
<br>> move concept performs the equivalent of memcpy for an object befor=
e calling=20
<br>> the move destructor. It makes things a lot simpler.
<br>
<br>...and far less generic.
<br>
<br>What if doing a memcpy is *wrong*? Now you've wasted a bunch of wor=
k
<br>copying data that isn't useful.
<br>
<br>Having something like a cting-dtor has obvious benefit (don't waste=
work
<br>maintaining the old object in a valid state when it's about to be
<br>destroyed anyway). Having a cting-dtor *that can be trivial* has
<br>*enormous* obvious value; many, many objects can be trivially
<br>"relocated"... and indeed libraries already do this despite t=
hat it is
<br>UB; having a way to "bless" such operation has obvious benefi=
t.
<br>
<br>I'm less convinced that there is significant benefit to optimizing
<br>corner cases. The *only* benefit, AFAICT, to e.g. the std::string case
<br>is merging the memcpy's for an array of such objects into a larger =
memcpy.
<br>
<br>Do you have benchmarks showing that this is a significant improvement?
<br>Keep in mind that the small memcpy will most likely be inlined, and tha=
t
<br>there is at least a branch per object in either case in addition to
<br>whatever memcpy(s) happen. (If the patch-up operator isn't inlined,
<br>that's probably going to swamp the memcpy(s).)
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_759_732086829.1438980433169--
------=_Part_758_1083495404.1438980433169--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 07 Aug 2015 17:32:23 -0400
Raw View
On 2015-08-07 16:47, isocppgroup@denisbider.com wrote:
> I believe the destructive move Jesus is upon us!
>
> I have uploaded the following draft:
>
> http://www.denisbider.com/MoveDestructor.pdf
Editorial comments:
- Might want to explain "destructive move" in the opening paragraph.
- Might want to mention std::unique_ptr? This is a really simple example
of a class that is trivially relocatable but has an "interesting" move
constructor and "interesting" destructor.
Nits:
- In the defaulted example, s.b. ~int(int&). That is, define the default
behavior as cting-dtor for ALL members, and explain elsewhere when a
cting-dtor is trivial (i.e. for POD types; the "consists of trivially
relocatable members" case seems sufficiently covered) and that trivial
means to just copy the bits. (Also, it's expected that the compiler will
combine trivial cting-dtors of adjacent members into a single memcpy.)
At least, I'd do that... seems cleaner. (Shouldn't actually change
anything.)
Not-so-nits:
- The multiple object helper should work on overlapping memory. I
imagine you intended this, but I don't see any wording to that effect;
it seems to me that such wording may be important.
- Should(n't) the cting-dtor be implicit-default if the class has a) a
*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
not such are declared?
- I feel fairly strongly that there should be a cutoff point for which
we can use the same syntax to relocate objects that can't be simply
relocated. I proposed that there is *always* a cting-dtor (except for
objects that explicitly delete it, or can't be copied/moved and/or
destroyed at all, i.e. the fallback implementation would be ill-formed),
but at any rate, I think the helpers should work regardless.
- I'm not entirely confident that the composition case is solved. As
worded, the class members are relocated after the base class has been
destroyed (moveover, the derived class itself is technically "destroyed"
after the base class has been destroyed), which seems like it could
present problems... :-( Unfortunately I don't have any suggestions here.
I do hope that this won't kill the proposal though.
Comments:
- It took me a minute or two to understand the invocation helpers, but
now that I do, I like! IIUC what these mean is that instead of libraries
having to check a type trait and write a memmove themselves, the
compiler will do so. Cool!
Bikesheds (JFTR):
- ~A(A&) vs. ~A(A*) vs. ~A(void*).
- "cting-dtor" vs. "move-dtor" ;-).
- Type trait names.
Thanks for sticking with this!
--
Matthew
--
---
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: isocppgroup@denisbider.com
Date: Fri, 7 Aug 2015 14:51:41 -0700 (PDT)
Raw View
------=_Part_2612_1336311938.1438984301341
Content-Type: multipart/alternative;
boundary="----=_Part_2613_54457857.1438984301341"
------=_Part_2613_54457857.1438984301341
Content-Type: text/plain; charset=UTF-8
Great responses! Thank you!
I urgently have to sleep, but I've had the following idea:
Do you think we should approach this from the opposite direction - a
destructing constructor?
I went with constructing destructor because it's easy to extend syntax for
it in an unambiguous way. However,
If we're willing to introduce an explicit reference type for xvalues, we
could have this, which could arguably be *more* general:
struct A : B {
A(A~& x) : B(x), c(std::xref(x.c)), i(x.i) {}
C c;
int i;};
Pros:
- everything is like move constructor - except this takes xvalue reference
instead of rvalue reference, and relies on std::xref instead of std::move
- fully recognizes xvalues, gives them a reference type (~&)
- naturally interacts with copy/move constructors
- allows for xvalue assignment operator - maybe useful for returns from
functions when assigned to pre-existing object?
Cons:
- fully recognizes xvalues - yet another reference type...
- naturally interacts with copy/move constructors - easy to slip up and
forget std::xref, resulting in a deep copy
- allows for xvalue assignment operator - yet another special member...
Thoughts?
On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
> On 2015-08-07 16:47, isocp...@denisbider.com <javascript:> wrote:
> > I believe the destructive move Jesus is upon us!
> >
> > I have uploaded the following draft:
> >
> > http://www.denisbider.com/MoveDestructor.pdf
>
> Editorial comments:
>
> - Might want to explain "destructive move" in the opening paragraph.
>
> - Might want to mention std::unique_ptr? This is a really simple example
> of a class that is trivially relocatable but has an "interesting" move
> constructor and "interesting" destructor.
>
>
> Nits:
>
> - In the defaulted example, s.b. ~int(int&). That is, define the default
> behavior as cting-dtor for ALL members, and explain elsewhere when a
> cting-dtor is trivial (i.e. for POD types; the "consists of trivially
> relocatable members" case seems sufficiently covered) and that trivial
> means to just copy the bits. (Also, it's expected that the compiler will
> combine trivial cting-dtors of adjacent members into a single memcpy.)
> At least, I'd do that... seems cleaner. (Shouldn't actually change
> anything.)
>
>
> Not-so-nits:
>
> - The multiple object helper should work on overlapping memory. I
> imagine you intended this, but I don't see any wording to that effect;
> it seems to me that such wording may be important.
>
> - Should(n't) the cting-dtor be implicit-default if the class has a) a
> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
> not such are declared?
>
> - I feel fairly strongly that there should be a cutoff point for which
> we can use the same syntax to relocate objects that can't be simply
> relocated. I proposed that there is *always* a cting-dtor (except for
> objects that explicitly delete it, or can't be copied/moved and/or
> destroyed at all, i.e. the fallback implementation would be ill-formed),
> but at any rate, I think the helpers should work regardless.
>
> - I'm not entirely confident that the composition case is solved. As
> worded, the class members are relocated after the base class has been
> destroyed (moveover, the derived class itself is technically "destroyed"
> after the base class has been destroyed), which seems like it could
> present problems... :-( Unfortunately I don't have any suggestions here.
> I do hope that this won't kill the proposal though.
>
>
> Comments:
>
> - It took me a minute or two to understand the invocation helpers, but
> now that I do, I like! IIUC what these mean is that instead of libraries
> having to check a type trait and write a memmove themselves, the
> compiler will do so. Cool!
>
>
> Bikesheds (JFTR):
>
> - ~A(A&) vs. ~A(A*) vs. ~A(void*).
>
> - "cting-dtor" vs. "move-dtor" ;-).
>
> - Type trait names.
>
>
> Thanks for sticking with this!
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2613_54457857.1438984301341
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Great responses! Thank you!</div><div><br></div><div>=
I urgently have to sleep, but I've had the following idea:</div><div><b=
r></div><div>Do you think we should approach this from the opposite directi=
on - a destructing constructor?</div><div><br></div><div>I went with constr=
ucting destructor because it's easy to extend syntax for it in an unamb=
iguous way. However,</div><div><br></div><div>If we're willing to intro=
duce an explicit reference type for xvalues, we could have this, which coul=
d arguably be <em>more</em> general:</div><div><br></div><pre style=3D"back=
ground: rgb(246, 248, 255); color: rgb(0, 0, 32);"><span style=3D"color: rg=
b(32, 0, 128); font-weight: bold;">struct</span> A <span style=3D"color: rg=
b(64, 96, 128);">:</span> B <span style=3D"color: rgb(64, 96, 128);">{</spa=
n>
A<span style=3D"color: rgb(48, 128, 128);">(</span>A<span style=3D"color:=
rgb(48, 128, 128);">~</span><span style=3D"color: rgb(48, 128, 128);">&=
;</span> x<span style=3D"color: rgb(48, 128, 128);">)</span> <span style=3D=
"color: rgb(64, 96, 128);">:</span> B<span style=3D"color: rgb(48, 128, 128=
);">(</span>x<span style=3D"color: rgb(48, 128, 128);">)</span><span style=
=3D"color: rgb(48, 128, 128);">,</span> c<span style=3D"color: rgb(48, 128,=
128);">(</span><span style=3D"color: rgb(0, 102, 238);">std</span><span st=
yle=3D"color: rgb(64, 96, 128);">::</span>xref<span style=3D"color: rgb(48,=
128, 128);">(</span>x<span style=3D"color: rgb(48, 128, 128);">.</span>c<s=
pan style=3D"color: rgb(48, 128, 128);">)</span><span style=3D"color: rgb(4=
8, 128, 128);">)</span><span style=3D"color: rgb(48, 128, 128);">,</span> i=
<span style=3D"color: rgb(48, 128, 128);">(</span>x<span style=3D"color: rg=
b(48, 128, 128);">.</span>i<span style=3D"color: rgb(48, 128, 128);">)</spa=
n> <span style=3D"color: rgb(64, 96, 128);">{</span><span style=3D"color: r=
gb(64, 96, 128);">}</span>
C c<span style=3D"color: rgb(64, 96, 128);">;</span>
<span style=3D"color: rgb(32, 0, 128); font-weight: bold;">int</span> i<s=
pan style=3D"color: rgb(64, 96, 128);">;</span>
<span style=3D"color: rgb(64, 96, 128);">}</span><span style=3D"color: rgb(=
64, 96, 128);">;</span>
</pre><p><br></p><div>Pros:</div><div><br></div><div>- everything is like m=
ove constructor=C2=A0-=C2=A0except this takes xvalue reference instead of r=
value reference, and relies on std::xref instead of std::move</div><div><br=
></div><div>- fully recognizes xvalues, gives them a reference type (<span =
style=3D"color: rgb(48, 128, 128);">~</span><span style=3D"color: rgb(48, 1=
28, 128);">&</span>)</div><div><br></div><div>- naturally interacts wit=
h copy/move constructors</div><div><br></div><div>- allows for xvalue assig=
nment operator - maybe useful for returns from functions when assigned to p=
re-existing object?</div><div><br></div><div>Cons:</div><div><br></div><div=
>- fully recognizes xvalues - yet another reference type...</div><div><br><=
/div><div>- naturally interacts with copy/move constructors - easy to slip =
up and forget std::xref, resulting in a deep copy</div><div><br></div><div>=
- allows for xvalue assignment operator - yet another special member...<br>=
</div><div><br></div><div>Thoughts?</div><div><br></div><div><br>On Friday,=
August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1=
ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-l=
eft-style: solid;">On 2015-08-07 16:47, <a onmousedown=3D"this.href=3D'=
javascript:';return true;" onclick=3D"this.href=3D'javascript:'=
;return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-=
obfuscated-mailto=3D"oCmuyhTpEAAJ">isocp...@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_2613_54457857.1438984301341--
------=_Part_2612_1336311938.1438984301341--
.
Author: isocppgroup@denisbider.com
Date: Fri, 7 Aug 2015 14:54:27 -0700 (PDT)
Raw View
------=_Part_2548_1499900910.1438984467831
Content-Type: multipart/alternative;
boundary="----=_Part_2549_921098360.1438984467832"
------=_Part_2549_921098360.1438984467832
Content-Type: text/plain; charset=UTF-8
> - naturally interacts with copy/move constructors -
> easy to slip up and forget std::xref, resulting in a deep copy
And there we go, I did exactly that in the example:
A(A~& x) : B(x), c(std::xref(x.c)), i(x.i) {}
Should be:
A(A~& x) : B(std::xref(x)), c(std::xref(x.c)), i(x.i) {}
Arguably, we have the same problem with move constructors...
And arguably - it might be better if we didn't... :)
On Friday, August 7, 2015 at 3:51:41 PM UTC-6, isocp...@denisbider.com
wrote:
> Great responses! Thank you!
>
> I urgently have to sleep, but I've had the following idea:
>
> Do you think we should approach this from the opposite direction - a
> destructing constructor?
>
> I went with constructing destructor because it's easy to extend syntax for
> it in an unambiguous way. However,
>
> If we're willing to introduce an explicit reference type for xvalues, we
> could have this, which could arguably be *more* general:
>
> struct A : B {
> A(A~& x) : B(x), c(std::xref(x.c)), i(x.i) {}
> C c;
> int i;};
>
>
> Pros:
>
> - everything is like move constructor - except this takes xvalue reference
> instead of rvalue reference, and relies on std::xref instead of std::move
>
> - fully recognizes xvalues, gives them a reference type (~&)
>
> - naturally interacts with copy/move constructors
>
> - allows for xvalue assignment operator - maybe useful for returns from
> functions when assigned to pre-existing object?
>
> Cons:
>
> - fully recognizes xvalues - yet another reference type...
>
> - naturally interacts with copy/move constructors - easy to slip up and
> forget std::xref, resulting in a deep copy
>
> - allows for xvalue assignment operator - yet another special member...
>
> Thoughts?
>
>
> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>
>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:
>> > I believe the destructive move Jesus is upon us!
>> >
>> > I have uploaded the following draft:
>> >
>> > http://www.denisbider.com/MoveDestructor.pdf
>>
>> Editorial comments:
>>
>> - Might want to explain "destructive move" in the opening paragraph.
>>
>> - Might want to mention std::unique_ptr? This is a really simple example
>> of a class that is trivially relocatable but has an "interesting" move
>> constructor and "interesting" destructor.
>>
>>
>> Nits:
>>
>> - In the defaulted example, s.b. ~int(int&). That is, define the default
>> behavior as cting-dtor for ALL members, and explain elsewhere when a
>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially
>> relocatable members" case seems sufficiently covered) and that trivial
>> means to just copy the bits. (Also, it's expected that the compiler will
>> combine trivial cting-dtors of adjacent members into a single memcpy.)
>> At least, I'd do that... seems cleaner. (Shouldn't actually change
>> anything.)
>>
>>
>> Not-so-nits:
>>
>> - The multiple object helper should work on overlapping memory. I
>> imagine you intended this, but I don't see any wording to that effect;
>> it seems to me that such wording may be important.
>>
>> - Should(n't) the cting-dtor be implicit-default if the class has a) a
>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
>> not such are declared?
>>
>> - I feel fairly strongly that there should be a cutoff point for which
>> we can use the same syntax to relocate objects that can't be simply
>> relocated. I proposed that there is *always* a cting-dtor (except for
>> objects that explicitly delete it, or can't be copied/moved and/or
>> destroyed at all, i.e. the fallback implementation would be ill-formed),
>> but at any rate, I think the helpers should work regardless.
>>
>> - I'm not entirely confident that the composition case is solved. As
>> worded, the class members are relocated after the base class has been
>> destroyed (moveover, the derived class itself is technically "destroyed"
>> after the base class has been destroyed), which seems like it could
>> present problems... :-( Unfortunately I don't have any suggestions here.
>> I do hope that this won't kill the proposal though.
>>
>>
>> Comments:
>>
>> - It took me a minute or two to understand the invocation helpers, but
>> now that I do, I like! IIUC what these mean is that instead of libraries
>> having to check a type trait and write a memmove themselves, the
>> compiler will do so. Cool!
>>
>>
>> Bikesheds (JFTR):
>>
>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).
>>
>> - "cting-dtor" vs. "move-dtor" ;-).
>>
>> - Type trait names.
>>
>>
>> Thanks for sticking with this!
>>
>> --
>> Matthew
>>
>>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2549_921098360.1438984467832
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>> - naturally interacts with copy/move constructor=
s -</div><div>> easy to slip up and forget std::xref, resulting in a dee=
p copy</div><div><br></div><div>And there we go, I did exactly that in the =
example:</div><div><br></div><div><pre style=3D"background: rgb(246, 248, 2=
55); color: rgb(0, 0, 32);"><br></pre><pre style=3D"background: rgb(246, 24=
8, 255); color: rgb(0, 0, 32);"> A<span style=3D"color: rgb(48, 128, 128);=
">(</span>A<span style=3D"color: rgb(48, 128, 128);">~</span><span style=3D=
"color: rgb(48, 128, 128);">&</span> x<span style=3D"color: rgb(48, 128=
, 128);">)</span> <span style=3D"color: rgb(64, 96, 128);">:</span> B<span =
style=3D"color: rgb(48, 128, 128);">(</span>x<span style=3D"color: rgb(48, =
128, 128);">)</span><span style=3D"color: rgb(48, 128, 128);">,</span> c<sp=
an style=3D"color: rgb(48, 128, 128);">(</span><span style=3D"color: rgb(0,=
102, 238);">std</span><span style=3D"color: rgb(64, 96, 128);">::</span>xr=
ef<span style=3D"color: rgb(48, 128, 128);">(</span>x<span style=3D"color: =
rgb(48, 128, 128);">.</span>c<span style=3D"color: rgb(48, 128, 128);">)</s=
pan><span style=3D"color: rgb(48, 128, 128);">)</span><span style=3D"color:=
rgb(48, 128, 128);">,</span> i<span style=3D"color: rgb(48, 128, 128);">(<=
/span>x<span style=3D"color: rgb(48, 128, 128);">.</span>i<span style=3D"co=
lor: rgb(48, 128, 128);">)</span> <span style=3D"color: rgb(64, 96, 128);">=
{</span><span style=3D"color: rgb(64, 96, 128);">}</span>
</pre></div><div><br></div><div>Should be:</div><div><br></div><div><pre st=
yle=3D"background: rgb(246, 248, 255); color: rgb(0, 0, 32);"><br></pre><pr=
e style=3D"background: rgb(246, 248, 255); color: rgb(0, 0, 32);"> A<span =
style=3D"color: rgb(48, 128, 128);">(</span>A<span style=3D"color: rgb(48, =
128, 128);">~</span><span style=3D"color: rgb(48, 128, 128);">&</span> =
x<span style=3D"color: rgb(48, 128, 128);">)</span> <span style=3D"color: r=
gb(64, 96, 128);">:</span> B<span style=3D"color: rgb(48, 128, 128);">(<spa=
n style=3D"color: rgb(0, 102, 238);">std</span><span style=3D"color: rgb(64=
, 96, 128);">::</span><font color=3D"#000020">xref</font><span style=3D"col=
or: rgb(48, 128, 128);">(</span></span>x)<span style=3D"color: rgb(48, 128,=
128);">)</span><span style=3D"color: rgb(48, 128, 128);">,</span> c<span s=
tyle=3D"color: rgb(48, 128, 128);">(</span><span style=3D"color: rgb(0, 102=
, 238);">std</span><span style=3D"color: rgb(64, 96, 128);">::</span>xref<s=
pan style=3D"color: rgb(48, 128, 128);">(</span>x<span style=3D"color: rgb(=
48, 128, 128);">.</span>c<span style=3D"color: rgb(48, 128, 128);">)</span>=
<span style=3D"color: rgb(48, 128, 128);">)</span><span style=3D"color: rgb=
(48, 128, 128);">,</span> i<span style=3D"color: rgb(48, 128, 128);">(</spa=
n>x<span style=3D"color: rgb(48, 128, 128);">.</span>i<span style=3D"color:=
rgb(48, 128, 128);">)</span> <span style=3D"color: rgb(64, 96, 128);">{</s=
pan><span style=3D"color: rgb(64, 96, 128);">}</span>
</pre></div><p><br></p><div>Arguably, we have the same problem with move co=
nstructors...</div><div><br></div><div>And arguably - it might be better if=
we didn't... :)</div><div><br><br>On Friday, August 7, 2015 at 3:51:41=
PM UTC-6, isocp...@denisbider.com wrote:</div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-co=
lor: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"=
><div dir=3D"ltr"><div>Great responses! Thank you!</div><div><br></div><div=
>I urgently have to sleep, but I've had the following idea:</div><div><=
br></div><div>Do you think we should approach this from the opposite direct=
ion - a destructing constructor?</div><div><br></div><div>I went with const=
ructing destructor because it's easy to extend syntax for it in an unam=
biguous way. However,</div><div><br></div><div>If we're willing to intr=
oduce an explicit reference type for xvalues, we could have this, which cou=
ld arguably be <em>more</em> general:</div><div><br></div><pre style=3D"bac=
kground: rgb(246, 248, 255); color: rgb(0, 0, 32);"><span style=3D"color: r=
gb(32, 0, 128); font-weight: bold;">struct</span> A <span style=3D"color: r=
gb(64, 96, 128);">:</span> B <span style=3D"color: rgb(64, 96, 128);">{</sp=
an>
A<span style=3D"color: rgb(48, 128, 128);">(</span>A<span style=3D"color:=
rgb(48, 128, 128);">~</span><span style=3D"color: rgb(48, 128, 128);">&=
;</span> x<span style=3D"color: rgb(48, 128, 128);">)</span> <span style=3D=
"color: rgb(64, 96, 128);">:</span> B<span style=3D"color: rgb(48, 128, 128=
);">(</span>x<span style=3D"color: rgb(48, 128, 128);">)</span><span style=
=3D"color: rgb(48, 128, 128);">,</span> c<span style=3D"color: rgb(48, 128,=
128);">(</span><span style=3D"color: rgb(0, 102, 238);">std</span><span st=
yle=3D"color: rgb(64, 96, 128);">::</span>xref<span style=3D"color: rgb(48,=
128, 128);">(</span>x<span style=3D"color: rgb(48, 128, 128);">.</span>c<s=
pan style=3D"color: rgb(48, 128, 128);">)</span><span style=3D"color: rgb(4=
8, 128, 128);">)</span><span style=3D"color: rgb(48, 128, 128);">,</span> i=
<span style=3D"color: rgb(48, 128, 128);">(</span>x<span style=3D"color: rg=
b(48, 128, 128);">.</span>i<span style=3D"color: rgb(48, 128, 128);">)</spa=
n> <span style=3D"color: rgb(64, 96, 128);">{</span><span style=3D"color: r=
gb(64, 96, 128);">}</span>
C c<span style=3D"color: rgb(64, 96, 128);">;</span>
<span style=3D"color: rgb(32, 0, 128); font-weight: bold;">int</span> i<s=
pan style=3D"color: rgb(64, 96, 128);">;</span>
<span style=3D"color: rgb(64, 96, 128);">}</span><span style=3D"color: rgb(=
64, 96, 128);">;</span>
</pre><p><br></p><div>Pros:</div><div><br></div><div>- everything is like m=
ove constructor=C2=A0-=C2=A0except this takes xvalue reference instead of r=
value reference, and relies on std::xref instead of std::move</div><div><br=
></div><div>- fully recognizes xvalues, gives them a reference type (<span =
style=3D"color: rgb(48, 128, 128);">~</span><span style=3D"color: rgb(48, 1=
28, 128);">&</span>)</div><div><br></div><div>- naturally interacts wit=
h copy/move constructors</div><div><br></div><div>- allows for xvalue assig=
nment operator - maybe useful for returns from functions when assigned to p=
re-existing object?</div><div><br></div><div>Cons:</div><div><br></div><div=
>- fully recognizes xvalues - yet another reference type...</div><div><br><=
/div><div>- naturally interacts with copy/move constructors - easy to slip =
up and forget std::xref, resulting in a deep copy</div><div><br></div><div>=
- allows for xvalue assignment operator - yet another special member...<br>=
</div><div><br></div><div>Thoughts?</div><div><br></div><div><br>On Friday,=
August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1=
ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-l=
eft-style: solid;">On 2015-08-07 16:47, <a rel=3D"nofollow">isocp...@denisb=
ider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div></blockquote></div>
<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 />
------=_Part_2549_921098360.1438984467832--
------=_Part_2548_1499900910.1438984467831--
.
Author: isocppgroup@denisbider.com
Date: Sat, 8 Aug 2015 01:37:38 -0700 (PDT)
Raw View
------=_Part_2804_1060189493.1439023058148
Content-Type: multipart/alternative;
boundary="----=_Part_2805_1144825882.1439023058149"
------=_Part_2805_1144825882.1439023058149
Content-Type: text/plain; charset=UTF-8
I have published an updated draft:
http://www.denisbider.com/Relocator.pdf
I have consistently renamed move destructor -> relocator and move
destruction -> relocation. Reason is explained in a new section,
Rationales, on last page.
Comments:
> Might want to explain "destructive move"
> in the opening paragraph.
Very good, done.
> - Might want to mention std::unique_ptr?
> This is a really simple example of a class that is
> trivially relocatable but has an "interesting" move
> constructor and "interesting" destructor.
I've spent a fair amount of time thinking about this, but I cannot think of
a container scenario involving unique_ptr that's worse than string.
unique_ptr already has nothrow move construction; and has nothrow
destruction as long as the object has nothrow destruction; and in any case,
it will not throw after a move. I'm having some trouble conjuring a
situation where the lack of relocation for unique_ptr does not result in
strictly a performance penalty for having to execute a non-trivial
destructor.
Did you have a specific scenario involving unique_ptr in mind?
> In the defaulted example, s.b. ~int(int&).
Good point, done that.
> explain elsewhere when a cting-dtor is trivial
Edited text where trait types are defined in an attempt to better explain
this.
> The multiple object helper should work
> on overlapping memory.
It should indeed. :) Fixed!
> Should(n't) the cting-dtor be implicit-default if the
> class has a) a *default* move ctor *or copy ctor*,
> *and* b) a default dtor, whether or not such are declared?
Hmm. I wouldn't necessarily mind, but current rules for move constructor
wouldn't implicitly declare one if a copy constructor or destructor, or
any other special member, is user-declared. The way I read 12.8, para 9,
the following:
struct A {
A(A const&) = default;
};
would result in a move constructor NOT being implicitly declared.
As far as I can test right now, this is the case. If A inherits from B,
which implements both move and copy construction, I can observe that trying
to move A actually results in copy construction of B. I need add:
struct A : B {
A(A const&) = default;
A(A&&) = default;
};
.... in order for B(B&&) to be called.
For consistency as well as safety, it would make sense to me to use the
same rules for the relocator.
> I feel fairly strongly that there should be a cutoff point
> for which we can use the same syntax to relocate
> objects that can't be simply relocated.
I agree, but I think it should be at a level above this. I have added a
discussion in the Rationales section.
> I'm not entirely confident that the composition case is
> solved. As worded, the class members are relocated
> after the base class has been destroyed
The relocator performs the tasks of both a constructor and a destructor, so
one of the two orders have to be chosen. I have added a section for this in
the Rationales section.
I hope also that calling the special member a "relocator"; expressing its
duality and impartiality, rather than a bias toward construction or
destruction; might also help alleviate this concern.
On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
> On 2015-08-07 16:47, isocp...@denisbider.com <javascript:> wrote:
> > I believe the destructive move Jesus is upon us!
> >
> > I have uploaded the following draft:
> >
> > http://www.denisbider.com/MoveDestructor.pdf
>
> Editorial comments:
>
> - Might want to explain "destructive move" in the opening paragraph.
>
> - Might want to mention std::unique_ptr? This is a really simple example
> of a class that is trivially relocatable but has an "interesting" move
> constructor and "interesting" destructor.
>
>
> Nits:
>
> - In the defaulted example, s.b. ~int(int&). That is, define the default
> behavior as cting-dtor for ALL members, and explain elsewhere when a
> cting-dtor is trivial (i.e. for POD types; the "consists of trivially
> relocatable members" case seems sufficiently covered) and that trivial
> means to just copy the bits. (Also, it's expected that the compiler will
> combine trivial cting-dtors of adjacent members into a single memcpy.)
> At least, I'd do that... seems cleaner. (Shouldn't actually change
> anything.)
>
>
> Not-so-nits:
>
> - The multiple object helper should work on overlapping memory. I
> imagine you intended this, but I don't see any wording to that effect;
> it seems to me that such wording may be important.
>
> - Should(n't) the cting-dtor be implicit-default if the class has a) a
> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
> not such are declared?
>
> - I feel fairly strongly that there should be a cutoff point for which
> we can use the same syntax to relocate objects that can't be simply
> relocated. I proposed that there is *always* a cting-dtor (except for
> objects that explicitly delete it, or can't be copied/moved and/or
> destroyed at all, i.e. the fallback implementation would be ill-formed),
> but at any rate, I think the helpers should work regardless.
>
> - I'm not entirely confident that the composition case is solved. As
> worded, the class members are relocated after the base class has been
> destroyed (moveover, the derived class itself is technically "destroyed"
> after the base class has been destroyed), which seems like it could
> present problems... :-( Unfortunately I don't have any suggestions here.
> I do hope that this won't kill the proposal though.
>
>
> Comments:
>
> - It took me a minute or two to understand the invocation helpers, but
> now that I do, I like! IIUC what these mean is that instead of libraries
> having to check a type trait and write a memmove themselves, the
> compiler will do so. Cool!
>
>
> Bikesheds (JFTR):
>
> - ~A(A&) vs. ~A(A*) vs. ~A(void*).
>
> - "cting-dtor" vs. "move-dtor" ;-).
>
> - Type trait names.
>
>
> Thanks for sticking with this!
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2805_1144825882.1439023058149
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>I have published an updated draft:</div><div><br></di=
v><div><a href=3D"http://www.denisbider.com/Relocator.pdf">http://www.denis=
bider.com/Relocator.pdf</a><br></div><div><br></div><div>I have consistentl=
y renamed move destructor -> relocator and move destruction -> reloca=
tion.=C2=A0Reason is=C2=A0explained in a new section, Rationales, on last p=
age.</div><div><br></div><div><br></div><div>Comments:</div><div><br></div>=
<div>> Might want to explain "destructive move"</div><div>>=
in the opening paragraph. </div><div><br></div><div>Very good, done.</div>=
<div><br></div><div><br></div><div>> - Might want to mention std::unique=
_ptr?</div><div>> This is a really simple example=C2=A0 of a class that =
is</div><div>> trivially relocatable but has an "interesting" =
move <br>> constructor and "interesting" destructor. <br></div=
><div><br></div><div>I've spent a fair amount of time thinking about th=
is, but I cannot think of a container scenario involving unique_ptr that=
9;s worse than string. unique_ptr already has nothrow move construction; an=
d has nothrow destruction as long as the object has nothrow destruction; an=
d in any case, it=C2=A0will not throw after a move. I'm having some tro=
uble conjuring a situation where the lack of relocation for unique_ptr does=
not result in strictly a performance penalty for having to execute a non-t=
rivial destructor.</div><div><br>Did you have a specific scenario involving=
unique_ptr in mind?</div><div><br></div><div><br></div><div>> In the de=
faulted example, s.b. ~int(int&).</div><div><br></div><div>Good point, =
done that.<br></div><div><br></div><div><br></div><div>> explain elsewhe=
re when a cting-dtor is trivial</div><div><br></div><div>Edited text where =
trait types are defined in an attempt to better explain this.</div><div><br=
></div><div><br></div><div>> The multiple object helper should work</div=
><div>> on overlapping memory.</div><div><br></div><div>It should indeed=
.. :) Fixed!</div><div><br></div><div><br></div><div>> Should(n't) th=
e cting-dtor be implicit-default if the</div><div>> class has a) a=C2=A0=
*default* move ctor *or copy ctor*,</div><div>> *and* b) a default dtor,=
whether or=C2=A0not such are declared?</div><div><br></div><div>Hmm. I wou=
ldn't necessarily mind, but current rules for move constructor wouldn&#=
39;t implicitly declare one if a copy constructor or destructor, or any=C2=
=A0other special member, is user-declared.=C2=A0The way I read 12.8, para 9=
, the following:</div><div><br></div><div><font face=3D"courier new,monospa=
ce">struct A {</font></div><div><font face=3D"courier new,monospace">=C2=A0=
A(A const&) =3D default;</font></div><div><font face=3D"courier new,mo=
nospace">};</font></div><div><br></div><div>would result in a move construc=
tor NOT being implicitly declared.</div><div><br></div><div>As far as I can=
test right now, this is the case. If A inherits from B, which implements=
=C2=A0both move=C2=A0and copy construction,=C2=A0I can observe that trying =
to move A actually results in copy construction of B. I need add:</div><div=
><br></div><div><div><font face=3D"courier new,monospace">struct A : B=C2=
=A0{</font></div><div><div><font face=3D"courier new,monospace">=C2=A0 A(A =
const&) =3D default;</font></div><font face=3D"courier new,monospace">=
=C2=A0 A(A&&) =3D default;</font></div><div><font face=3D"courier n=
ew,monospace">};</font></div><div><br></div><div>... in order for B(B&&=
amp;) to be called.</div><div><br></div><div>For consistency as well as saf=
ety, it would make sense to me to use the same rules for the relocator.</di=
v><div><br></div><div><br></div><div>> I feel fairly strongly that there=
should be a cutoff point</div><div>> for which we can use the same synt=
ax to relocate</div><div>> objects that can't be simply relocated.</=
div><div><br></div><div>I agree, but I think it should be at a level above =
this. I have added a discussion in the Rationales section.</div><div><br></=
div><div><br></div><div>> I'm not entirely confident that the compos=
ition case is</div><div>> solved. As worded, the class members are reloc=
ated</div><div>> after the base class has been destroyed</div><div><br><=
/div><div>The relocator performs the tasks of both a constructor and a dest=
ructor, so one of the two orders have to be chosen. I have added a section =
for this in the Rationales section.</div><div><br></div><div>I hope also th=
at calling the special member a "relocator"; expressing its duali=
ty and impartiality, rather than a bias toward construction or destruction;=
=C2=A0might also help alleviate this concern.</div><div><br></div><div><br>=
</div></div><div><br>On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew=
Woehlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px=
0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); b=
order-left-width: 1px; border-left-style: solid;">On 2015-08-07 16:47, <a o=
nmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"th=
is.href=3D'javascript:';return true;" href=3D"javascript:" target=
=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"oCmuyhTpEAAJ">isocp..=
..@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_2805_1144825882.1439023058149--
------=_Part_2804_1060189493.1439023058148--
.
Author: Vitali Lovich <vlovich@gmail.com>
Date: Sat, 8 Aug 2015 15:27:12 -0700
Raw View
--Apple-Mail=_48B25B6A-D234-4E2E-86B0-5F69F0D63830
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
I like many things about this proposal & thank you for trying to tackle thi=
s. Apologies if already covered, but can you clarify why there is a distin=
ction between the multiple & single relocators? Am I correct in guessing t=
hat it=E2=80=99s to try & avoid the loop overhead when you only have a sing=
le object? Some other reason?
The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contradicto=
ry to the terminology being used to frame the solution. If construction or=
der is indeed more appropriate (which I think you are correct on), doesn=E2=
=80=99t it speak that this is more naturally thought of as a destructive mo=
ve constructor? Beyond just semantics, I think users writing their own may=
easily get confused about which order they need to destroy/construct & bug=
s in this area will be very subtle, hard-to-find & particularly nasty.
nitpicks:
The static keyword preceding the function A::~A seems out-of-place no? I c=
ould be mistaken, but the static keyword is illegal in this context & can o=
nly be there on free-standing functions or on functions as part of the clas=
s declaration; it cannot be used for external class function definition. I=
s the static keyword in this place new to this proposal or C++17?
While discussion relocation, there is what amounts to a footnote mentioning=
realloc. Is it correct that this is the language proposal that would comp=
lement any eventual library features that would enable the use of realloc w=
ithin containers? I think that could do with some clarification to properl=
y frame the discussion; it sounds like this is trying to solve the memcpy p=
roblem but it seems like it solves both that & realloc, no?
I=E2=80=99m not very familiar with the standardese terminology, so apologie=
s for the silly question, but In the "Implicit relocator=E2=80=9D section, =
does "user-declared=E2=80=9D also cover declarations that are "=3D default=
=E2=80=9D?
Thanks,
Vitali
> On Aug 8, 2015, at 1:37 AM, isocppgroup@denisbider.com wrote:
>=20
> I have published an updated draft:
>=20
> http://www.denisbider.com/Relocator.pdf <http://www.denisbider.com/Reloca=
tor.pdf>
>=20
> I have consistently renamed move destructor -> relocator and move destruc=
tion -> relocation. Reason is explained in a new section, Rationales, on la=
st page.
>=20
>=20
> Comments:
>=20
> > Might want to explain "destructive move"
> > in the opening paragraph.
>=20
> Very good, done.
>=20
>=20
> > - Might want to mention std::unique_ptr?
> > This is a really simple example of a class that is
> > trivially relocatable but has an "interesting" move=20
> > constructor and "interesting" destructor.=20
>=20
> I've spent a fair amount of time thinking about this, but I cannot think =
of a container scenario involving unique_ptr that's worse than string. uniq=
ue_ptr already has nothrow move construction; and has nothrow destruction a=
s long as the object has nothrow destruction; and in any case, it will not =
throw after a move. I'm having some trouble conjuring a situation where the=
lack of relocation for unique_ptr does not result in strictly a performanc=
e penalty for having to execute a non-trivial destructor.
>=20
> Did you have a specific scenario involving unique_ptr in mind?
>=20
>=20
> > In the defaulted example, s.b. ~int(int&).
>=20
> Good point, done that.
>=20
>=20
> > explain elsewhere when a cting-dtor is trivial
>=20
> Edited text where trait types are defined in an attempt to better explain=
this.
>=20
>=20
> > The multiple object helper should work
> > on overlapping memory.
>=20
> It should indeed. :) Fixed!
>=20
>=20
> > Should(n't) the cting-dtor be implicit-default if the
> > class has a) a *default* move ctor *or copy ctor*,
> > *and* b) a default dtor, whether or not such are declared?
>=20
> Hmm. I wouldn't necessarily mind, but current rules for move constructor =
wouldn't implicitly declare one if a copy constructor or destructor, or any=
other special member, is user-declared. The way I read 12.8, para 9, the f=
ollowing:
>=20
> struct A {
> A(A const&) =3D default;
> };
>=20
> would result in a move constructor NOT being implicitly declared.
>=20
> As far as I can test right now, this is the case. If A inherits from B, w=
hich implements both move and copy construction, I can observe that trying =
to move A actually results in copy construction of B. I need add:
>=20
> struct A : B {
> A(A const&) =3D default;
> A(A&&) =3D default;
> };
>=20
> ... in order for B(B&&) to be called.
>=20
> For consistency as well as safety, it would make sense to me to use the s=
ame rules for the relocator.
>=20
>=20
> > I feel fairly strongly that there should be a cutoff point
> > for which we can use the same syntax to relocate
> > objects that can't be simply relocated.
>=20
> I agree, but I think it should be at a level above this. I have added a d=
iscussion in the Rationales section.
>=20
>=20
> > I'm not entirely confident that the composition case is
> > solved. As worded, the class members are relocated
> > after the base class has been destroyed
>=20
> The relocator performs the tasks of both a constructor and a destructor, =
so one of the two orders have to be chosen. I have added a section for this=
in the Rationales section.
>=20
> I hope also that calling the special member a "relocator"; expressing its=
duality and impartiality, rather than a bias toward construction or destru=
ction; might also help alleviate this concern.
>=20
>=20
>=20
> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
> On 2015-08-07 16:47, isocp...@denisbider.com <javascript:> wrote:=20
> > I believe the destructive move Jesus is upon us!=20
> >=20
> > I have uploaded the following draft:=20
> >=20
> > http://www.denisbider.com/MoveDestructor.pdf <http://www.denisbider.com=
/MoveDestructor.pdf>=20
>=20
> Editorial comments:=20
>=20
> - Might want to explain "destructive move" in the opening paragraph.=20
>=20
> - Might want to mention std::unique_ptr? This is a really simple example=
=20
> of a class that is trivially relocatable but has an "interesting" move=20
> constructor and "interesting" destructor.=20
>=20
>=20
> Nits:=20
>=20
> - In the defaulted example, s.b. ~int(int&). That is, define the default=
=20
> behavior as cting-dtor for ALL members, and explain elsewhere when a=20
> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=20
> relocatable members" case seems sufficiently covered) and that trivial=20
> means to just copy the bits. (Also, it's expected that the compiler will=
=20
> combine trivial cting-dtors of adjacent members into a single memcpy.)=20
> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
> anything.)=20
>=20
>=20
> Not-so-nits:=20
>=20
> - The multiple object helper should work on overlapping memory. I=20
> imagine you intended this, but I don't see any wording to that effect;=20
> it seems to me that such wording may be important.=20
>=20
> - Should(n't) the cting-dtor be implicit-default if the class has a) a=20
> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or=
=20
> not such are declared?=20
>=20
> - I feel fairly strongly that there should be a cutoff point for which=20
> we can use the same syntax to relocate objects that can't be simply=20
> relocated. I proposed that there is *always* a cting-dtor (except for=20
> objects that explicitly delete it, or can't be copied/moved and/or=20
> destroyed at all, i.e. the fallback implementation would be ill-formed),=
=20
> but at any rate, I think the helpers should work regardless.=20
>=20
> - I'm not entirely confident that the composition case is solved. As=20
> worded, the class members are relocated after the base class has been=20
> destroyed (moveover, the derived class itself is technically "destroyed"=
=20
> after the base class has been destroyed), which seems like it could=20
> present problems... :-( Unfortunately I don't have any suggestions here.=
=20
> I do hope that this won't kill the proposal though.=20
>=20
>=20
> Comments:=20
>=20
> - It took me a minute or two to understand the invocation helpers, but=20
> now that I do, I like! IIUC what these mean is that instead of libraries=
=20
> having to check a type trait and write a memmove themselves, the=20
> compiler will do so. Cool!=20
>=20
>=20
> Bikesheds (JFTR):=20
>=20
> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>=20
> - "cting-dtor" vs. "move-dtor" ;-).=20
>=20
> - Type trait names.=20
>=20
>=20
> Thanks for sticking with this!=20
>=20
> --=20
> Matthew=20
>=20
>=20
> --=20
>=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=
email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-propo=
sals/ <http://groups.google.com/a/isocpp.org/group/std-proposals/>.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_48B25B6A-D234-4E2E-86B0-5F69F0D63830
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"">I like many things=
about this proposal & thank you for trying to tackle this. Apolo=
gies if already covered, but can you clarify why there is a distinction bet=
ween the multiple & single relocators? Am I correct in guessing t=
hat it=E2=80=99s to try & avoid the loop overhead when you only have a =
single object? Some other reason?<div class=3D""><br class=3D""></div=
><div class=3D"">The =E2=80=9Ccomposition=E2=80=9D section seems to read ki=
nd of contradictory to the terminology being used to frame the solution. &n=
bsp;If construction order is indeed more appropriate (which I think you are=
correct on), doesn=E2=80=99t it speak that this is more naturally thought =
of as a destructive move constructor? Beyond just semantics, I think =
users writing their own may easily get confused about which order they need=
to destroy/construct & bugs in this area will be very subtle, hard-to-=
find & particularly nasty.</div><div class=3D""><br class=3D""></div><d=
iv class=3D"">nitpicks:</div><div class=3D""><br class=3D""></div><div clas=
s=3D"">The static keyword preceding the function A::~A seems out-of-pl=
ace no? I could be mistaken, but the static keyword is illegal in thi=
s context & can only be there on free-standing functions or on function=
s as part of the class declaration; it cannot be used for external class fu=
nction definition. Is the static keyword in this place new to this pr=
oposal or C++17?</div><div class=3D""><br class=3D""></div><div class=3D"">=
<div class=3D"">While discussion relocation, there is what amounts to a foo=
tnote mentioning realloc. Is it correct that this is the language pro=
posal that would complement any eventual library features that would enable=
the use of realloc within containers? I think that could do with som=
e clarification to properly frame the discussion; it sounds like this is tr=
ying to solve the memcpy problem but it seems like it solves both that &=
; realloc, no?</div><div class=3D""><br class=3D""></div></div><div class=
=3D"">I=E2=80=99m not very familiar with the standardese terminology, so ap=
ologies for the silly question, but In the "Implicit relocator=E2=80=9D sec=
tion, does "user-declared=E2=80=9D also cover declarations that are "=3D de=
fault=E2=80=9D?</div><div class=3D""><br class=3D""></div><div class=3D"">T=
hanks,</div><div class=3D"">Vitali</div><div class=3D""><br class=3D""></di=
v><div class=3D""><br class=3D""><div class=3D""><div><blockquote type=3D"c=
ite" class=3D""><div class=3D"">On Aug 8, 2015, at 1:37 AM, <a href=3D"mail=
to:isocppgroup@denisbider.com" class=3D"">isocppgroup@denisbider.com</a> wr=
ote:</div><br class=3D"Apple-interchange-newline"><div class=3D""><div dir=
=3D"ltr" class=3D""><div class=3D"">I have published an updated draft:</div=
><div class=3D""><br class=3D""></div><div class=3D""><a href=3D"http://www=
..denisbider.com/Relocator.pdf" class=3D"">http://www.denisbider.com/Relocat=
or.pdf</a><br class=3D""></div><div class=3D""><br class=3D""></div><div cl=
ass=3D"">I have consistently renamed move destructor -> relocator and mo=
ve destruction -> relocation. Reason is explained in a new sec=
tion, Rationales, on last page.</div><div class=3D""><br class=3D""></div><=
div class=3D""><br class=3D""></div><div class=3D"">Comments:</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">> Might want to explain "de=
structive move"</div><div class=3D"">> in the opening paragraph. </div><=
div class=3D""><br class=3D""></div><div class=3D"">Very good, done.</div><=
div class=3D""><br class=3D""></div><div class=3D""><br class=3D""></div><d=
iv class=3D"">> - Might want to mention std::unique_ptr?</div><div class=
=3D"">> This is a really simple example of a class that is</div><d=
iv class=3D"">> trivially relocatable but has an "interesting" move <br =
class=3D"">> constructor and "interesting" destructor. <br class=3D""></=
div><div class=3D""><br class=3D""></div><div class=3D"">I've spent a fair =
amount of time thinking about this, but I cannot think of a container scena=
rio involving unique_ptr that's worse than string. unique_ptr already has n=
othrow move construction; and has nothrow destruction as long as the object=
has nothrow destruction; and in any case, it will not throw after a m=
ove. I'm having some trouble conjuring a situation where the lack of reloca=
tion for unique_ptr does not result in strictly a performance penalty for h=
aving to execute a non-trivial destructor.</div><div class=3D""><br class=
=3D"">Did you have a specific scenario involving unique_ptr in mind?</div><=
div class=3D""><br class=3D""></div><div class=3D""><br class=3D""></div><d=
iv class=3D"">> In the defaulted example, s.b. ~int(int&).</div><div=
class=3D""><br class=3D""></div><div class=3D"">Good point, done that.<br =
class=3D""></div><div class=3D""><br class=3D""></div><div class=3D""><br c=
lass=3D""></div><div class=3D"">> explain elsewhere when a cting-dtor is=
trivial</div><div class=3D""><br class=3D""></div><div class=3D"">Edited t=
ext where trait types are defined in an attempt to better explain this.</di=
v><div class=3D""><br class=3D""></div><div class=3D""><br class=3D""></div=
><div class=3D"">> The multiple object helper should work</div><div clas=
s=3D"">> on overlapping memory.</div><div class=3D""><br class=3D""></di=
v><div class=3D"">It should indeed. :) Fixed!</div><div class=3D""><br clas=
s=3D""></div><div class=3D""><br class=3D""></div><div class=3D"">> Shou=
ld(n't) the cting-dtor be implicit-default if the</div><div class=3D"">>=
class has a) a *default* move ctor *or copy ctor*,</div><div class=3D=
"">> *and* b) a default dtor, whether or not such are declared?</di=
v><div class=3D""><br class=3D""></div><div class=3D"">Hmm. I wouldn't nece=
ssarily mind, but current rules for move constructor wouldn't implicitly de=
clare one if a copy constructor or destructor, or any other special me=
mber, is user-declared. The way I read 12.8, para 9, the following:</d=
iv><div class=3D""><br class=3D""></div><div class=3D""><font face=3D"couri=
er new,monospace" class=3D"">struct A {</font></div><div class=3D""><font f=
ace=3D"courier new,monospace" class=3D""> A(A const&) =3D default=
;</font></div><div class=3D""><font face=3D"courier new,monospace" class=3D=
"">};</font></div><div class=3D""><br class=3D""></div><div class=3D"">woul=
d result in a move constructor NOT being implicitly declared.</div><div cla=
ss=3D""><br class=3D""></div><div class=3D"">As far as I can test right now=
, this is the case. If A inherits from B, which implements both move&n=
bsp;and copy construction, I can observe that trying to move A actuall=
y results in copy construction of B. I need add:</div><div class=3D""><br c=
lass=3D""></div><div class=3D""><div class=3D""><font face=3D"courier new,m=
onospace" class=3D"">struct A : B {</font></div><div class=3D""><div c=
lass=3D""><font face=3D"courier new,monospace" class=3D""> A(A const&=
amp;) =3D default;</font></div><font face=3D"courier new,monospace" class=
=3D""> A(A&&) =3D default;</font></div><div class=3D""><font =
face=3D"courier new,monospace" class=3D"">};</font></div><div class=3D""><b=
r class=3D""></div><div class=3D"">... in order for B(B&&) to be ca=
lled.</div><div class=3D""><br class=3D""></div><div class=3D"">For consist=
ency as well as safety, it would make sense to me to use the same rules for=
the relocator.</div><div class=3D""><br class=3D""></div><div class=3D""><=
br class=3D""></div><div class=3D"">> I feel fairly strongly that there =
should be a cutoff point</div><div class=3D"">> for which we can use the=
same syntax to relocate</div><div class=3D"">> objects that can't be si=
mply relocated.</div><div class=3D""><br class=3D""></div><div class=3D"">I=
agree, but I think it should be at a level above this. I have added a disc=
ussion in the Rationales section.</div><div class=3D""><br class=3D""></div=
><div class=3D""><br class=3D""></div><div class=3D"">> I'm not entirely=
confident that the composition case is</div><div class=3D"">> solved. A=
s worded, the class members are relocated</div><div class=3D"">> after t=
he base class has been destroyed</div><div class=3D""><br class=3D""></div>=
<div class=3D"">The relocator performs the tasks of both a constructor and =
a destructor, so one of the two orders have to be chosen. I have added a se=
ction for this in the Rationales section.</div><div class=3D""><br class=3D=
""></div><div class=3D"">I hope also that calling the special member a "rel=
ocator"; expressing its duality and impartiality, rather than a bias toward=
construction or destruction; might also help alleviate this concern.<=
/div><div class=3D""><br class=3D""></div><div class=3D""><br class=3D""></=
div></div><div class=3D""><br class=3D"">On Friday, August 7, 2015 at 3:32:=
51 PM UTC-6, Matthew Woehlke wrote:</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: r=
gb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">On 20=
15-08-07 16:47, <a onmousedown=3D"this.href=3D'javascript:';return true;" o=
nclick=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" targ=
et=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"oCmuyhTpEAAJ" class=
=3D"">isocp...@denisbider.com</a> wrote:
<br class=3D"">> I believe the destructive move Jesus is upon us!
<br class=3D"">>=20
<br class=3D"">> I have uploaded the following draft:
<br class=3D"">>=20
<br class=3D"">> <a onmousedown=3D"this.href=3D'http://www.google.com/ur=
l?q\75http%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\=
0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2=
FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQp=
9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestructor.pd=
f" target=3D"_blank" rel=3D"nofollow" class=3D"">http://www.denisbider.com/=
<wbr class=3D"">MoveDestructor.pdf</a>
<br class=3D"">
<br class=3D"">Editorial comments:
<br class=3D"">
<br class=3D"">- Might want to explain "destructive move" in the opening pa=
ragraph.
<br class=3D"">
<br class=3D"">- Might want to mention std::unique_ptr? This is a really si=
mple example
<br class=3D"">of a class that is trivially relocatable but has an "interes=
ting" move
<br class=3D"">constructor and "interesting" destructor.
<br class=3D"">
<br class=3D"">
<br class=3D"">Nits:
<br class=3D"">
<br class=3D"">- In the defaulted example, s.b. ~int(int&). That is, de=
fine the default
<br class=3D"">behavior as cting-dtor for ALL members, and explain elsewher=
e when a
<br class=3D"">cting-dtor is trivial (i.e. for POD types; the "consists of =
trivially
<br class=3D"">relocatable members" case seems sufficiently covered) and th=
at trivial
<br class=3D"">means to just copy the bits. (Also, it's expected that the c=
ompiler will
<br class=3D"">combine trivial cting-dtors of adjacent members into a singl=
e memcpy.)
<br class=3D"">At least, I'd do that... seems cleaner. (Shouldn't actually =
change
<br class=3D"">anything.)
<br class=3D"">
<br class=3D"">
<br class=3D"">Not-so-nits:
<br class=3D"">
<br class=3D"">- The multiple object helper should work on overlapping memo=
ry. I
<br class=3D"">imagine you intended this, but I don't see any wording to th=
at effect;
<br class=3D"">it seems to me that such wording may be important.
<br class=3D"">
<br class=3D"">- Should(n't) the cting-dtor be implicit-default if the clas=
s has a) a
<br class=3D"">*default* move ctor *or copy ctor*, *and* b) a default dtor,=
whether or
<br class=3D"">not such are declared?
<br class=3D"">
<br class=3D"">- I feel fairly strongly that there should be a cutoff point=
for which
<br class=3D"">we can use the same syntax to relocate objects that can't be=
simply
<br class=3D"">relocated. I proposed that there is *always* a cting-dtor (e=
xcept for
<br class=3D"">objects that explicitly delete it, or can't be copied/moved =
and/or
<br class=3D"">destroyed at all, i.e. the fallback implementation would be =
ill-formed),
<br class=3D"">but at any rate, I think the helpers should work regardless.
<br class=3D"">
<br class=3D"">- I'm not entirely confident that the composition case is so=
lved. As
<br class=3D"">worded, the class members are relocated after the base class=
has been
<br class=3D"">destroyed (moveover, the derived class itself is technically=
"destroyed"
<br class=3D"">after the base class has been destroyed), which seems like i=
t could
<br class=3D"">present problems... :-( Unfortunately I don't have any sugge=
stions here.
<br class=3D"">I do hope that this won't kill the proposal though.
<br class=3D"">
<br class=3D"">
<br class=3D"">Comments:
<br class=3D"">
<br class=3D"">- It took me a minute or two to understand the invocation he=
lpers, but
<br class=3D"">now that I do, I like! IIUC what these mean is that instead =
of libraries
<br class=3D"">having to check a type trait and write a memmove themselves,=
the
<br class=3D"">compiler will do so. Cool!
<br class=3D"">
<br class=3D"">
<br class=3D"">Bikesheds (JFTR):
<br class=3D"">
<br class=3D"">- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br class=3D"">
<br class=3D"">- "cting-dtor" vs. "move-dtor" ;-).
<br class=3D"">
<br class=3D"">- Type trait names.
<br class=3D"">
<br class=3D"">
<br class=3D"">Thanks for sticking with this!
<br class=3D"">
<br class=3D"">--=20
<br class=3D"">Matthew
<br class=3D"">
<br class=3D""></blockquote></div><div class=3D""><br class=3D"webkit-block=
-placeholder"></div>
-- <br class=3D"">
<br class=3D"">
--- <br class=3D"">
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br class=3D"">
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" class=3D"">=
std-proposals+unsubscribe@isocpp.org</a>.<br class=3D"">
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" class=3D"">std-proposals@isocpp.org</a>.<br class=3D"">
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" class=3D"">http://groups.google.com/a/isocpp.org/group/std-=
proposals/</a>.<br class=3D"">
</div></blockquote></div><br class=3D""></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=_48B25B6A-D234-4E2E-86B0-5F69F0D63830--
.
Author: isocppgroup@denisbider.com
Date: Sun, 9 Aug 2015 03:57:09 -0700 (PDT)
Raw View
------=_Part_3543_1715180924.1439117829563
Content-Type: multipart/alternative;
boundary="----=_Part_3544_663496519.1439117829564"
------=_Part_3544_663496519.1439117829564
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
> If construction order is indeed more appropriate (which I
> think you are correct on), doesn=E2=80=99t it speak that this is
> more naturally thought of as a destructive move constructor?
Yes, I think you're very right!
I have updated the proposal with an annex that presents an alternate=20
constructor-like syntax, and discusses the merits and demerits of the two=
=20
approaches:
http://denisbider.com/Relocator.pdf
It seems to me that the constructor-like approach may in fact be superior;=
=20
no more complex, yet more intuitive; and potentially more extensible, if=20
needed.
If folks like this, I'm leaning to promote constructor-like syntax from the=
=20
annex, and place it in the center of the proposal.
> distinction between the multiple & single relocators?
Yes - it's just a formal distinction to emphasize cost-less optimization of=
=20
the single-object case. I have added to the text to make this clearer.
> The static keyword preceding the function A::~A
> seems out-of-place no?
It is illegal in the definition, yes. It's okay in the declaration.
I have changed the definition to put "static" into C-style comments. I'm=20
still keeping it, to make it clear that the wrappers are invoked as static=
=20
members.
> it sounds like this is trying to solve the memcpy problem
> but it seems like it solves both that & realloc, no?
To properly solve the realloc problem, it would be necessary to have the=20
equivalent of realloc_in_place.
If realloc_in_place or equivalent fails:
- The equivalent of malloc needs to be used to allocate new memory, while=
=20
keeping old memory.
- The static relocator needs to be called to move objects from old location=
=20
to new. This could be as trivial as memcpy, or may require fix-ups.
- The old memory is freed.
In the absence of realloc_in_place; and for trivially relocatable objects=
=20
only; it would work for a container to call realloc, also.
To permit use with realloc with non-trivially relocatable objects, the=20
relocator would have to:
- use constructor-like syntax (the old location is gone when it is called);
- accept a ptrdiff_t instead of reference to the old location.
The ptrdiff_t would be the offset between the old location and the new one,=
=20
and would allow the relocator to perform any patch-ups.=20
The drawback of this approach is that, if you have a small object; e.g.=20
libc++ std::string, which is just one pointer in size; and this object=20
requires a patch-up during relocation; it's twice as costly to execute=20
realloc + patch-up, than to execute a relocator that performs the copy as=
=20
part of its process.
Basically, the lack of a realloc_in_place or equivalent is the=20
deficiency. A feature such as relocation should not be designed around a=20
library deficiency that should relatively trivial to solve.
> does "user-declared=E2=80=9D also cover declarations that are "=3D defaul=
t=E2=80=9D?
Yes, it does. For example, if you have this:
struct B {
B(B const&) { ... }
B(B&&) { ... }
};
struct A : B {
A(A const&) =3D default;
};
The user declaration of A(A const&) - even as default - blocks an implicit=
=20
declaration of a move constructor for A. To get an implicitly defined move=
=20
constructor, one must use either this:
struct A : B {
};
or this:
struct A : B {
A(A const&) =3D default;
A(A&&) =3D default;
};
On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:
> I like many things about this proposal & thank you for trying to tackle=
=20
> this. Apologies if already covered, but can you clarify why there is a=
=20
> distinction between the multiple & single relocators? Am I correct in=20
> guessing that it=E2=80=99s to try & avoid the loop overhead when you only=
have a=20
> single object? Some other reason?
>
> The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contradic=
tory to the=20
> terminology being used to frame the solution. If construction order is=
=20
> indeed more appropriate (which I think you are correct on), doesn=E2=80=
=99t it=20
> speak that this is more naturally thought of as a destructive move=20
> constructor? Beyond just semantics, I think users writing their own may=
=20
> easily get confused about which order they need to destroy/construct & bu=
gs=20
> in this area will be very subtle, hard-to-find & particularly nasty.
>
> nitpicks:
>
> The static keyword preceding the function A::~A seems out-of-place no? I=
=20
> could be mistaken, but the static keyword is illegal in this context & ca=
n=20
> only be there on free-standing functions or on functions as part of the=
=20
> class declaration; it cannot be used for external class function=20
> definition. Is the static keyword in this place new to this proposal or=
=20
> C++17?
>
> While discussion relocation, there is what amounts to a footnote=20
> mentioning realloc. Is it correct that this is the language proposal tha=
t=20
> would complement any eventual library features that would enable the use =
of=20
> realloc within containers? I think that could do with some clarification=
=20
> to properly frame the discussion; it sounds like this is trying to solve=
=20
> the memcpy problem but it seems like it solves both that & realloc, no?
>
> I=E2=80=99m not very familiar with the standardese terminology, so apolog=
ies for=20
> the silly question, but In the "Implicit relocator=E2=80=9D section, does=
=20
> "user-declared=E2=80=9D also cover declarations that are "=3D default=E2=
=80=9D?
>
> Thanks,
> Vitali
>
>
> On Aug 8, 2015, at 1:37 AM, isocp...@denisbider.com <javascript:> wrote:
>
> I have published an updated draft:
>
> http://www.denisbider.com/Relocator.pdf
>
> I have consistently renamed move destructor -> relocator and move=20
> destruction -> relocation. Reason is explained in a new section,=20
> Rationales, on last page.
>
>
> Comments:
>
> > Might want to explain "destructive move"
> > in the opening paragraph.=20
>
> Very good, done.
>
>
> > - Might want to mention std::unique_ptr?
> > This is a really simple example of a class that is
> > trivially relocatable but has an "interesting" move=20
> > constructor and "interesting" destructor.=20
>
> I've spent a fair amount of time thinking about this, but I cannot think=
=20
> of a container scenario involving unique_ptr that's worse than string.=20
> unique_ptr already has nothrow move construction; and has nothrow=20
> destruction as long as the object has nothrow destruction; and in any cas=
e,=20
> it will not throw after a move. I'm having some trouble conjuring a=20
> situation where the lack of relocation for unique_ptr does not result in=
=20
> strictly a performance penalty for having to execute a non-trivial=20
> destructor.
>
> Did you have a specific scenario involving unique_ptr in mind?
>
>
> > In the defaulted example, s.b. ~int(int&).
>
> Good point, done that.
>
>
> > explain elsewhere when a cting-dtor is trivial
>
> Edited text where trait types are defined in an attempt to better explain=
=20
> this.
>
>
> > The multiple object helper should work
> > on overlapping memory.
>
> It should indeed. :) Fixed!
>
>
> > Should(n't) the cting-dtor be implicit-default if the
> > class has a) a *default* move ctor *or copy ctor*,
> > *and* b) a default dtor, whether or not such are declared?
>
> Hmm. I wouldn't necessarily mind, but current rules for move constructor=
=20
> wouldn't implicitly declare one if a copy constructor or destructor, or=
=20
> any other special member, is user-declared. The way I read 12.8, para 9,=
=20
> the following:
>
> struct A {
> A(A const&) =3D default;
> };
>
> would result in a move constructor NOT being implicitly declared.
>
> As far as I can test right now, this is the case. If A inherits from B,=
=20
> which implements both move and copy construction, I can observe that tryi=
ng=20
> to move A actually results in copy construction of B. I need add:
>
> struct A : B {
> A(A const&) =3D default;
> A(A&&) =3D default;
> };
>
> ... in order for B(B&&) to be called.
>
> For consistency as well as safety, it would make sense to me to use the=
=20
> same rules for the relocator.
>
>
> > I feel fairly strongly that there should be a cutoff point
> > for which we can use the same syntax to relocate
> > objects that can't be simply relocated.
>
> I agree, but I think it should be at a level above this. I have added a=
=20
> discussion in the Rationales section.
>
>
> > I'm not entirely confident that the composition case is
> > solved. As worded, the class members are relocated
> > after the base class has been destroyed
>
> The relocator performs the tasks of both a constructor and a destructor,=
=20
> so one of the two orders have to be chosen. I have added a section for th=
is=20
> in the Rationales section.
>
> I hope also that calling the special member a "relocator"; expressing its=
=20
> duality and impartiality, rather than a bias toward construction or=20
> destruction; might also help alleviate this concern.
>
>
>
> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>
>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:=20
>> > I believe the destructive move Jesus is upon us!=20
>> >=20
>> > I have uploaded the following draft:=20
>> >=20
>> > http://www.denisbider.com/MoveDestructor.pdf=20
>>
>> Editorial comments:=20
>>
>> - Might want to explain "destructive move" in the opening paragraph.=20
>>
>> - Might want to mention std::unique_ptr? This is a really simple example=
=20
>> of a class that is trivially relocatable but has an "interesting" move=
=20
>> constructor and "interesting" destructor.=20
>>
>>
>> Nits:=20
>>
>> - In the defaulted example, s.b. ~int(int&). That is, define the default=
=20
>> behavior as cting-dtor for ALL members, and explain elsewhere when a=20
>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=20
>> relocatable members" case seems sufficiently covered) and that trivial=
=20
>> means to just copy the bits. (Also, it's expected that the compiler will=
=20
>> combine trivial cting-dtors of adjacent members into a single memcpy.)=
=20
>> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
>> anything.)=20
>>
>>
>> Not-so-nits:=20
>>
>> - The multiple object helper should work on overlapping memory. I=20
>> imagine you intended this, but I don't see any wording to that effect;=
=20
>> it seems to me that such wording may be important.=20
>>
>> - Should(n't) the cting-dtor be implicit-default if the class has a) a=
=20
>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or=
=20
>> not such are declared?=20
>>
>> - I feel fairly strongly that there should be a cutoff point for which=
=20
>> we can use the same syntax to relocate objects that can't be simply=20
>> relocated. I proposed that there is *always* a cting-dtor (except for=20
>> objects that explicitly delete it, or can't be copied/moved and/or=20
>> destroyed at all, i.e. the fallback implementation would be ill-formed),=
=20
>> but at any rate, I think the helpers should work regardless.=20
>>
>> - I'm not entirely confident that the composition case is solved. As=20
>> worded, the class members are relocated after the base class has been=20
>> destroyed (moveover, the derived class itself is technically "destroyed"=
=20
>> after the base class has been destroyed), which seems like it could=20
>> present problems... :-( Unfortunately I don't have any suggestions here.=
=20
>> I do hope that this won't kill the proposal though.=20
>>
>>
>> Comments:=20
>>
>> - It took me a minute or two to understand the invocation helpers, but=
=20
>> now that I do, I like! IIUC what these mean is that instead of libraries=
=20
>> having to check a type trait and write a memmove themselves, the=20
>> compiler will do so. Cool!=20
>>
>>
>> Bikesheds (JFTR):=20
>>
>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>>
>> - "cting-dtor" vs. "move-dtor" ;-).=20
>>
>> - Type trait names.=20
>>
>>
>> Thanks for sticking with this!=20
>>
>> --=20
>> Matthew=20
>>
>>
> --=20
>
> ---=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3544_663496519.1439117829564
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>> If construction order is indeed more appropriate=
(which I<br>> think you are correct on), doesn=E2=80=99t it speak that =
this is<br>> more naturally thought of as a destructive move constructor=
?</div><div><br></div><div>Yes,=C2=A0I think you're=C2=A0very right!</d=
iv><div><br></div><div>I have updated the proposal with an annex that prese=
nts an alternate constructor-like syntax, and discusses the merits and deme=
rits of the two approaches:</div><div><br></div><div><a href=3D"http://deni=
sbider.com/Relocator.pdf">http://denisbider.com/Relocator.pdf</a><br></div>=
<div><br></div><div>It seems to me that the constructor-like approach may i=
n fact be superior; no more complex,=C2=A0yet more intuitive; and potential=
ly more extensible, if needed.</div><div><br></div><div>If folks like this,=
I'm leaning to=C2=A0promote constructor-like syntax=C2=A0from the anne=
x, and=C2=A0place it in the center of the proposal.</div><div><br></div><di=
v><br></div><div>> distinction between the multiple & single relocat=
ors?</div><div><br></div><div>Yes - it's just a formal distinction to=
=C2=A0emphasize cost-less optimization of the single-object case. I have ad=
ded=C2=A0to the text=C2=A0to make this clearer.</div><div><br></div><div><b=
r></div><div>> The static keyword preceding the function=C2=A0A::~A</div=
><div>> seems out-of-place no?</div><div><br></div><div>It is illegal in=
the definition, yes. It's okay in the declaration.</div><div><br></div=
><div>I have changed the definition to put "static" into C-style =
comments. I'm still keeping it, to=C2=A0make it clear that the wrappers=
are=C2=A0invoked as static members.</div><div><br></div><div><br></div><di=
v>> it sounds like this is trying to solve the memcpy problem</div><div>=
> but it seems like it solves both that & realloc, no?</div><div><br=
></div><div>To properly solve the <font face=3D"courier new,monospace">real=
loc</font> problem, it would be necessary to have=C2=A0the equivalent of=C2=
=A0<font face=3D"courier new,monospace">realloc_in_place</font>.</div><div>=
<br></div><div>If <font face=3D"courier new,monospace">realloc_in_place</fo=
nt> or equivalent fails:</div><div><br></div><div>- The equivalent of mallo=
c needs to be used to allocate new memory, while keeping old memory.</div><=
div><br></div><div>- The static relocator needs to be called to move object=
s from old location to new. This could be as trivial as memcpy, or may requ=
ire fix-ups.</div><div><br></div><div>- The old memory is freed.</div><div>=
<br></div><div>In the absence of <font face=3D"courier new,monospace">reall=
oc_in_place</font>; and for trivially relocatable objects only; it would wo=
rk for a container to call <font face=3D"courier new,monospace">realloc</fo=
nt>, also.</div><div><br></div><div>To permit use with <font face=3D"courie=
r new,monospace">realloc</font> with=C2=A0non-trivially relocatable=C2=A0ob=
jects, the relocator would have to:</div><div><br></div><div>- use construc=
tor-like syntax (the old location is gone when it is called);</div><div><br=
></div><div>- accept a <font face=3D"courier new,monospace">ptrdiff_t</font=
> instead of reference to the old location.</div><div><br></div><div>The <f=
ont face=3D"courier new,monospace">ptrdiff_t</font> would be the offset bet=
ween the old location and the new one, and would allow the relocator to=C2=
=A0perform any patch-ups.=C2=A0</div><div><br></div><div>The drawback of th=
is approach is that, if you have a small object; e.g. libc++ std::string, w=
hich is just=C2=A0one pointer=C2=A0in size; and this object requires a patc=
h-up during relocation; it's twice as costly to execute realloc + patch=
-up, than to execute a relocator that performs the copy as part of its proc=
ess.</div><div><br></div><div>Basically, the lack of a <font face=3D"courie=
r new,monospace">realloc_in_place</font> or equivalent is the deficiency.=
=C2=A0A feature such as relocation should not be designed around a library =
deficiency that should=C2=A0relatively trivial to solve.</div><div><br></di=
v><div><br></div><div>> does "user-declared=E2=80=9D also cover dec=
larations that are "=3D default=E2=80=9D?</div><div><br></div><div>Yes=
, it does. For example, if you have this:</div><div><br></div><div><font fa=
ce=3D"courier new,monospace">=C2=A0 struct B {</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 =C2=A0 B(B const&) { ... }</font></di=
v><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 B(B&&) { =
.... }</font></div><div><font face=3D"courier new,monospace">=C2=A0 };</font=
></div><div><font face=3D"courier new,monospace"><br></font></div><div><fon=
t face=3D"courier new,monospace">=C2=A0 struct A : B {</font></div><div><fo=
nt face=3D"courier new,monospace">=C2=A0 =C2=A0 A(A const&) =3D default=
;</font></div><div><font face=3D"courier new,monospace">=C2=A0 };</font></d=
iv><div><br></div><div>The user declaration of A(A const&) -=C2=A0even =
as default -=C2=A0blocks an implicit declaration of a=C2=A0move constructor=
for A. To get an implicitly defined move constructor, one must use either =
this:</div><div><br></div><div><font face=3D"courier new,monospace">=C2=A0 =
struct A : B {</font></div><div><font face=3D"courier new,monospace">=C2=A0=
};</font></div><div><br></div><div>or this:</div><div><br></div><div><div>=
<font face=3D"courier new,monospace">=C2=A0 struct A : B {</font></div><div=
><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 A(A const&) =
=3D default;</font></div><div><font face=3D"courier new,monospace">=C2=A0=
=C2=A0 =C2=A0A(A&&) =3D default;</font></div><font face=3D"courier =
new,monospace">=C2=A0 };</font></div></div><div><br><br>On Saturday, August=
8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left=
-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: soli=
d;"><div style=3D"-ms-word-wrap: break-word;">I like many things about this=
proposal & thank you for trying to tackle this. =C2=A0Apologies if alr=
eady covered, but can you clarify why there is a distinction between the mu=
ltiple & single relocators? =C2=A0Am I correct in guessing that it=E2=
=80=99s to try & avoid the loop overhead when you only have a single ob=
ject? =C2=A0Some other reason?<div><br></div><div>The =E2=80=9Ccomposition=
=E2=80=9D section seems to read kind of contradictory to the terminology be=
ing used to frame the solution. =C2=A0If construction order is indeed more =
appropriate (which I think you are correct on), doesn=E2=80=99t it speak th=
at this is more naturally thought of as a destructive move constructor? =C2=
=A0Beyond just semantics, I think users writing their own may easily get co=
nfused about which order they need to destroy/construct & bugs in this =
area will be very subtle, hard-to-find & particularly nasty.</div><div>=
<br></div><div>nitpicks:</div><div><br></div><div>The static keyword preced=
ing the function=C2=A0A::~A seems out-of-place no? =C2=A0I could be mistake=
n, but the static keyword is illegal in this context & can only be ther=
e on free-standing functions or on functions as part of the class declarati=
on; it cannot be used for external class function definition. =C2=A0Is the =
static keyword in this place new to this proposal or C++17?</div><div><br><=
/div><div><div>While discussion relocation, there is what amounts to a foot=
note mentioning realloc. =C2=A0Is it correct that this is the language prop=
osal that would complement any eventual library features that would enable =
the use of realloc within containers? =C2=A0I think that could do with some=
clarification to properly frame the discussion; it sounds like this is try=
ing to solve the memcpy problem but it seems like it solves both that &=
realloc, no?</div><div><br></div></div><div>I=E2=80=99m not very familiar =
with the standardese terminology, so apologies for the silly question, but =
In the "Implicit relocator=E2=80=9D section, does "user-declared=
=E2=80=9D also cover declarations that are "=3D default=E2=80=9D?</div=
><div><br></div><div>Thanks,</div><div>Vitali</div><div><br></div><div><br>=
<div><div><blockquote type=3D"cite"><div>On Aug 8, 2015, at 1:37 AM, <a onm=
ousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this=
..href=3D'javascript:';return true;" href=3D"javascript:" target=3D"=
_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"1ZLY4ZvsAAAJ">isocp...@de=
nisbider.com</a> wrote:</div><br><div><div dir=3D"ltr"><div>I have publishe=
d an updated draft:</div><div><br></div><div><a onmousedown=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FReloca=
tor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ'=
;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;" href=3D"http://www.d=
enisbider.com/Relocator.pdf" target=3D"_blank" rel=3D"nofollow">http://www.=
denisbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><div>I have c=
onsistently renamed move destructor -> relocator and move destruction -&=
gt; relocation.=C2=A0Reason is=C2=A0explained in a new section, Rationales,=
on last page.</div><div><br></div><div><br></div><div>Comments:</div><div>=
<br></div><div>> Might want to explain "destructive move"</div=
><div>> in the opening paragraph. </div><div><br></div><div>Very good, d=
one.</div><div><br></div><div><br></div><div>> - Might want to mention s=
td::unique_ptr?</div><div>> This is a really simple example=C2=A0 of a c=
lass that is</div><div>> trivially relocatable but has an "interest=
ing" move <br>> constructor and "interesting" destructor.=
<br></div><div><br></div><div>I've spent a fair amount of time thinkin=
g about this, but I cannot think of a container scenario involving unique_p=
tr that's worse than string. unique_ptr already has nothrow move constr=
uction; and has nothrow destruction as long as the object has nothrow destr=
uction; and in any case, it=C2=A0will not throw after a move. I'm havin=
g some trouble conjuring a situation where the lack of relocation for uniqu=
e_ptr does not result in strictly a performance penalty for having to execu=
te a non-trivial destructor.</div><div><br>Did you have a specific scenario=
involving unique_ptr in mind?</div><div><br></div><div><br></div><div>>=
In the defaulted example, s.b. ~int(int&).</div><div><br></div><div>Go=
od point, done that.<br></div><div><br></div><div><br></div><div>> expla=
in elsewhere when a cting-dtor is trivial</div><div><br></div><div>Edited t=
ext where trait types are defined in an attempt to better explain this.</di=
v><div><br></div><div><br></div><div>> The multiple object helper should=
work</div><div>> on overlapping memory.</div><div><br></div><div>It sho=
uld indeed. :) Fixed!</div><div><br></div><div><br></div><div>> Should(n=
't) the cting-dtor be implicit-default if the</div><div>> class has =
a) a=C2=A0*default* move ctor *or copy ctor*,</div><div>> *and* b) a def=
ault dtor, whether or=C2=A0not such are declared?</div><div><br></div><div>=
Hmm. I wouldn't necessarily mind, but current rules for move constructo=
r wouldn't implicitly declare one if a copy constructor or destructor, =
or any=C2=A0other special member, is user-declared.=C2=A0The way I read 12.=
8, para 9, the following:</div><div><br></div><div><font face=3D"courier ne=
w,monospace">struct A {</font></div><div><font face=3D"courier new,monospac=
e">=C2=A0 A(A const&) =3D default;</font></div><div><font face=3D"couri=
er new,monospace">};</font></div><div><br></div><div>would result in a move=
constructor NOT being implicitly declared.</div><div><br></div><div>As far=
as I can test right now, this is the case. If A inherits from B, which imp=
lements=C2=A0both move=C2=A0and copy construction,=C2=A0I can observe that =
trying to move A actually results in copy construction of B. I need add:</d=
iv><div><br></div><div><div><font face=3D"courier new,monospace">struct A :=
B=C2=A0{</font></div><div><div><font face=3D"courier new,monospace">=C2=A0=
A(A const&) =3D default;</font></div><font face=3D"courier new,monospa=
ce">=C2=A0 A(A&&) =3D default;</font></div><div><font face=3D"couri=
er new,monospace">};</font></div><div><br></div><div>... in order for B(B&a=
mp;&) to be called.</div><div><br></div><div>For consistency as well as=
safety, it would make sense to me to use the same rules for the relocator.=
</div><div><br></div><div><br></div><div>> I feel fairly strongly that t=
here should be a cutoff point</div><div>> for which we can use the same =
syntax to relocate</div><div>> objects that can't be simply relocate=
d.</div><div><br></div><div>I agree, but I think it should be at a level ab=
ove this. I have added a discussion in the Rationales section.</div><div><b=
r></div><div><br></div><div>> I'm not entirely confident that the co=
mposition case is</div><div>> solved. As worded, the class members are r=
elocated</div><div>> after the base class has been destroyed</div><div><=
br></div><div>The relocator performs the tasks of both a constructor and a =
destructor, so one of the two orders have to be chosen. I have added a sect=
ion for this in the Rationales section.</div><div><br></div><div>I hope als=
o that calling the special member a "relocator"; expressing its d=
uality and impartiality, rather than a bias toward construction or destruct=
ion;=C2=A0might also help alleviate this concern.</div><div><br></div><div>=
<br></div></div><div><br>On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Mat=
thew Woehlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204=
); border-left-width: 1px; border-left-style: solid;">On 2015-08-07 16:47, =
<a rel=3D"nofollow">isocp...@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div><div><br></div>
-- <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 onmousedown=3D"this.href=3D'javascript:';return true;" o=
nclick=3D"this.href=3D'javascript:';return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"1ZLY4ZvsAAA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"1ZLY4ZvsAAAJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google=
..com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.h=
ref=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></div></blockquote></div>
<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 />
------=_Part_3544_663496519.1439117829564--
------=_Part_3543_1715180924.1439117829563--
.
Author: isocppgroup@denisbider.com
Date: Sun, 9 Aug 2015 05:00:49 -0700 (PDT)
Raw View
------=_Part_3511_1342032902.1439121649394
Content-Type: multipart/alternative;
boundary="----=_Part_3512_938554273.1439121649395"
------=_Part_3512_938554273.1439121649395
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
In fact - I am sufficiently convinced that constructor-like syntax is more=
=20
intuitive, that I have gone ahead and converted the proposal. It now puts=
=20
constructor-like syntax front and center.
Just in case, I still have the previous version. But I think this will be=
=20
more intuitive.
On Sunday, August 9, 2015 at 4:57:09 AM UTC-6, isocp...@denisbider.com=20
wrote:
> > If construction order is indeed more appropriate (which I
> > think you are correct on), doesn=E2=80=99t it speak that this is
> > more naturally thought of as a destructive move constructor?
>
> Yes, I think you're very right!
>
> I have updated the proposal with an annex that presents an alternate=20
> constructor-like syntax, and discusses the merits and demerits of the two=
=20
> approaches:
>
> http://denisbider.com/Relocator.pdf
>
> It seems to me that the constructor-like approach may in fact be superior=
;=20
> no more complex, yet more intuitive; and potentially more extensible, if=
=20
> needed.
>
> If folks like this, I'm leaning to promote constructor-like syntax from=
=20
> the annex, and place it in the center of the proposal.
>
>
> > distinction between the multiple & single relocators?
>
> Yes - it's just a formal distinction to emphasize cost-less optimization=
=20
> of the single-object case. I have added to the text to make this clearer.
>
>
> > The static keyword preceding the function A::~A
> > seems out-of-place no?
>
> It is illegal in the definition, yes. It's okay in the declaration.
>
> I have changed the definition to put "static" into C-style comments. I'm=
=20
> still keeping it, to make it clear that the wrappers are invoked as stati=
c=20
> members.
>
>
> > it sounds like this is trying to solve the memcpy problem
> > but it seems like it solves both that & realloc, no?
>
> To properly solve the realloc problem, it would be necessary to have the=
=20
> equivalent of realloc_in_place.
>
> If realloc_in_place or equivalent fails:
>
> - The equivalent of malloc needs to be used to allocate new memory, while=
=20
> keeping old memory.
>
> - The static relocator needs to be called to move objects from old=20
> location to new. This could be as trivial as memcpy, or may require fix-u=
ps.
>
> - The old memory is freed.
>
> In the absence of realloc_in_place; and for trivially relocatable objects=
=20
> only; it would work for a container to call realloc, also.
>
> To permit use with realloc with non-trivially relocatable objects, the=20
> relocator would have to:
>
> - use constructor-like syntax (the old location is gone when it is called=
);
>
> - accept a ptrdiff_t instead of reference to the old location.
>
> The ptrdiff_t would be the offset between the old location and the new=20
> one, and would allow the relocator to perform any patch-ups.=20
>
> The drawback of this approach is that, if you have a small object; e.g.=
=20
> libc++ std::string, which is just one pointer in size; and this object=20
> requires a patch-up during relocation; it's twice as costly to execute=20
> realloc + patch-up, than to execute a relocator that performs the copy as=
=20
> part of its process.
>
> Basically, the lack of a realloc_in_place or equivalent is the=20
> deficiency. A feature such as relocation should not be designed around a=
=20
> library deficiency that should relatively trivial to solve.
>
>
> > does "user-declared=E2=80=9D also cover declarations that are "=3D defa=
ult=E2=80=9D?
>
> Yes, it does. For example, if you have this:
>
> struct B {
> B(B const&) { ... }
> B(B&&) { ... }
> };
>
> struct A : B {
> A(A const&) =3D default;
> };
>
> The user declaration of A(A const&) - even as default - blocks an implici=
t=20
> declaration of a move constructor for A. To get an implicitly defined mov=
e=20
> constructor, one must use either this:
>
> struct A : B {
> };
>
> or this:
>
> struct A : B {
> A(A const&) =3D default;
> A(A&&) =3D default;
> };
>
>
> On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:
>
>> I like many things about this proposal & thank you for trying to tackle=
=20
>> this. Apologies if already covered, but can you clarify why there is a=
=20
>> distinction between the multiple & single relocators? Am I correct in=
=20
>> guessing that it=E2=80=99s to try & avoid the loop overhead when you onl=
y have a=20
>> single object? Some other reason?
>>
>> The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contradi=
ctory to the=20
>> terminology being used to frame the solution. If construction order is=
=20
>> indeed more appropriate (which I think you are correct on), doesn=E2=80=
=99t it=20
>> speak that this is more naturally thought of as a destructive move=20
>> constructor? Beyond just semantics, I think users writing their own may=
=20
>> easily get confused about which order they need to destroy/construct & b=
ugs=20
>> in this area will be very subtle, hard-to-find & particularly nasty.
>>
>> nitpicks:
>>
>> The static keyword preceding the function A::~A seems out-of-place no? =
I=20
>> could be mistaken, but the static keyword is illegal in this context & c=
an=20
>> only be there on free-standing functions or on functions as part of the=
=20
>> class declaration; it cannot be used for external class function=20
>> definition. Is the static keyword in this place new to this proposal or=
=20
>> C++17?
>>
>> While discussion relocation, there is what amounts to a footnote=20
>> mentioning realloc. Is it correct that this is the language proposal th=
at=20
>> would complement any eventual library features that would enable the use=
of=20
>> realloc within containers? I think that could do with some clarificatio=
n=20
>> to properly frame the discussion; it sounds like this is trying to solve=
=20
>> the memcpy problem but it seems like it solves both that & realloc, no?
>>
>> I=E2=80=99m not very familiar with the standardese terminology, so apolo=
gies for=20
>> the silly question, but In the "Implicit relocator=E2=80=9D section, doe=
s=20
>> "user-declared=E2=80=9D also cover declarations that are "=3D default=E2=
=80=9D?
>>
>> Thanks,
>> Vitali
>>
>>
>> On Aug 8, 2015, at 1:37 AM, isocp...@denisbider.com wrote:
>>
>> I have published an updated draft:
>>
>> http://www.denisbider.com/Relocator.pdf
>>
>> I have consistently renamed move destructor -> relocator and move=20
>> destruction -> relocation. Reason is explained in a new section,=20
>> Rationales, on last page.
>>
>>
>> Comments:
>>
>> > Might want to explain "destructive move"
>> > in the opening paragraph.=20
>>
>> Very good, done.
>>
>>
>> > - Might want to mention std::unique_ptr?
>> > This is a really simple example of a class that is
>> > trivially relocatable but has an "interesting" move=20
>> > constructor and "interesting" destructor.=20
>>
>> I've spent a fair amount of time thinking about this, but I cannot think=
=20
>> of a container scenario involving unique_ptr that's worse than string.=
=20
>> unique_ptr already has nothrow move construction; and has nothrow=20
>> destruction as long as the object has nothrow destruction; and in any ca=
se,=20
>> it will not throw after a move. I'm having some trouble conjuring a=20
>> situation where the lack of relocation for unique_ptr does not result in=
=20
>> strictly a performance penalty for having to execute a non-trivial=20
>> destructor.
>>
>> Did you have a specific scenario involving unique_ptr in mind?
>>
>>
>> > In the defaulted example, s.b. ~int(int&).
>>
>> Good point, done that.
>>
>>
>> > explain elsewhere when a cting-dtor is trivial
>>
>> Edited text where trait types are defined in an attempt to better explai=
n=20
>> this.
>>
>>
>> > The multiple object helper should work
>> > on overlapping memory.
>>
>> It should indeed. :) Fixed!
>>
>>
>> > Should(n't) the cting-dtor be implicit-default if the
>> > class has a) a *default* move ctor *or copy ctor*,
>> > *and* b) a default dtor, whether or not such are declared?
>>
>> Hmm. I wouldn't necessarily mind, but current rules for move constructor=
=20
>> wouldn't implicitly declare one if a copy constructor or destructor, or=
=20
>> any other special member, is user-declared. The way I read 12.8, para 9,=
=20
>> the following:
>>
>> struct A {
>> A(A const&) =3D default;
>> };
>>
>> would result in a move constructor NOT being implicitly declared.
>>
>> As far as I can test right now, this is the case. If A inherits from B,=
=20
>> which implements both move and copy construction, I can observe that try=
ing=20
>> to move A actually results in copy construction of B. I need add:
>>
>> struct A : B {
>> A(A const&) =3D default;
>> A(A&&) =3D default;
>> };
>>
>> ... in order for B(B&&) to be called.
>>
>> For consistency as well as safety, it would make sense to me to use the=
=20
>> same rules for the relocator.
>>
>>
>> > I feel fairly strongly that there should be a cutoff point
>> > for which we can use the same syntax to relocate
>> > objects that can't be simply relocated.
>>
>> I agree, but I think it should be at a level above this. I have added a=
=20
>> discussion in the Rationales section.
>>
>>
>> > I'm not entirely confident that the composition case is
>> > solved. As worded, the class members are relocated
>> > after the base class has been destroyed
>>
>> The relocator performs the tasks of both a constructor and a destructor,=
=20
>> so one of the two orders have to be chosen. I have added a section for t=
his=20
>> in the Rationales section.
>>
>> I hope also that calling the special member a "relocator"; expressing it=
s=20
>> duality and impartiality, rather than a bias toward construction or=20
>> destruction; might also help alleviate this concern.
>>
>>
>>
>> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>>
>>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:=20
>>> > I believe the destructive move Jesus is upon us!=20
>>> >=20
>>> > I have uploaded the following draft:=20
>>> >=20
>>> > http://www.denisbider.com/MoveDestructor.pdf=20
>>>
>>> Editorial comments:=20
>>>
>>> - Might want to explain "destructive move" in the opening paragraph.=20
>>>
>>> - Might want to mention std::unique_ptr? This is a really simple exampl=
e=20
>>> of a class that is trivially relocatable but has an "interesting" move=
=20
>>> constructor and "interesting" destructor.=20
>>>
>>>
>>> Nits:=20
>>>
>>> - In the defaulted example, s.b. ~int(int&). That is, define the defaul=
t=20
>>> behavior as cting-dtor for ALL members, and explain elsewhere when a=20
>>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=
=20
>>> relocatable members" case seems sufficiently covered) and that trivial=
=20
>>> means to just copy the bits. (Also, it's expected that the compiler wil=
l=20
>>> combine trivial cting-dtors of adjacent members into a single memcpy.)=
=20
>>> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
>>> anything.)=20
>>>
>>>
>>> Not-so-nits:=20
>>>
>>> - The multiple object helper should work on overlapping memory. I=20
>>> imagine you intended this, but I don't see any wording to that effect;=
=20
>>> it seems to me that such wording may be important.=20
>>>
>>> - Should(n't) the cting-dtor be implicit-default if the class has a) a=
=20
>>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or=
=20
>>> not such are declared?=20
>>>
>>> - I feel fairly strongly that there should be a cutoff point for which=
=20
>>> we can use the same syntax to relocate objects that can't be simply=20
>>> relocated. I proposed that there is *always* a cting-dtor (except for=
=20
>>> objects that explicitly delete it, or can't be copied/moved and/or=20
>>> destroyed at all, i.e. the fallback implementation would be ill-formed)=
,=20
>>> but at any rate, I think the helpers should work regardless.=20
>>>
>>> - I'm not entirely confident that the composition case is solved. As=20
>>> worded, the class members are relocated after the base class has been=
=20
>>> destroyed (moveover, the derived class itself is technically "destroyed=
"=20
>>> after the base class has been destroyed), which seems like it could=20
>>> present problems... :-( Unfortunately I don't have any suggestions here=
..=20
>>> I do hope that this won't kill the proposal though.=20
>>>
>>>
>>> Comments:=20
>>>
>>> - It took me a minute or two to understand the invocation helpers, but=
=20
>>> now that I do, I like! IIUC what these mean is that instead of librarie=
s=20
>>> having to check a type trait and write a memmove themselves, the=20
>>> compiler will do so. Cool!=20
>>>
>>>
>>> Bikesheds (JFTR):=20
>>>
>>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>>>
>>> - "cting-dtor" vs. "move-dtor" ;-).=20
>>>
>>> - Type trait names.=20
>>>
>>>
>>> Thanks for sticking with this!=20
>>>
>>> --=20
>>> Matthew=20
>>>
>>>
>> --=20
>>
>> ---=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>> Visit this group at=20
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>>
>>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3512_938554273.1439121649395
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>In fact - I am sufficiently convinced that constructo=
r-like syntax is more intuitive, that I have gone ahead and converted the p=
roposal. It now puts constructor-like syntax front and center.</div><div><b=
r></div><div>Just in case, I still have the previous version. But I think t=
his will be more intuitive.</div><div><br></div><div><br>On Sunday, August =
9, 2015 at 4:57:09 AM UTC-6, isocp...@denisbider.com wrote:</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1=
ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-l=
eft-style: solid;"><div dir=3D"ltr"><div>> If construction order is inde=
ed more appropriate (which I<br>> think you are correct on), doesn=E2=80=
=99t it speak that this is<br>> more naturally thought of as a destructi=
ve move constructor?</div><div><br></div><div>Yes,=C2=A0I think you're=
=C2=A0very right!</div><div><br></div><div>I have updated the proposal with=
an annex that presents an alternate constructor-like syntax, and discusses=
the merits and demerits of the two approaches:</div><div><br></div><div><a=
onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2=
Fdenisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGRaVpviw=
tOSXhpXtDNRASkBLXVYw';return true;" onclick=3D"this.href=3D'http://=
www.google.com/url?q\75http%3A%2F%2Fdenisbider.com%2FRelocator.pdf\46sa\75D=
\46sntz\0751\46usg\75AFQjCNGRaVpviwtOSXhpXtDNRASkBLXVYw';return true;" =
href=3D"http://denisbider.com/Relocator.pdf" target=3D"_blank" rel=3D"nofol=
low">http://denisbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><=
div>It seems to me that the constructor-like approach may in fact be superi=
or; no more complex,=C2=A0yet more intuitive; and potentially more extensib=
le, if needed.</div><div><br></div><div>If folks like this, I'm leaning=
to=C2=A0promote constructor-like syntax=C2=A0from the annex, and=C2=A0plac=
e it in the center of the proposal.</div><div><br></div><div><br></div><div=
>> distinction between the multiple & single relocators?</div><div><=
br></div><div>Yes - it's just a formal distinction to=C2=A0emphasize co=
st-less optimization of the single-object case. I have added=C2=A0to the te=
xt=C2=A0to make this clearer.</div><div><br></div><div><br></div><div>> =
The static keyword preceding the function=C2=A0A::~A</div><div>> seems o=
ut-of-place no?</div><div><br></div><div>It is illegal in the definition, y=
es. It's okay in the declaration.</div><div><br></div><div>I have chang=
ed the definition to put "static" into C-style comments. I'm =
still keeping it, to=C2=A0make it clear that the wrappers are=C2=A0invoked =
as static members.</div><div><br></div><div><br></div><div>> it sounds l=
ike this is trying to solve the memcpy problem</div><div>> but it seems =
like it solves both that & realloc, no?</div><div><br></div><div>To pro=
perly solve the <font face=3D"courier new,monospace">realloc</font> problem=
, it would be necessary to have=C2=A0the equivalent of=C2=A0<font face=3D"c=
ourier new,monospace">realloc_in_place</font>.</div><div><br></div><div>If =
<font face=3D"courier new,monospace">realloc_in_place</font> or equivalent =
fails:</div><div><br></div><div>- The equivalent of malloc needs to be used=
to allocate new memory, while keeping old memory.</div><div><br></div><div=
>- The static relocator needs to be called to move objects from old locatio=
n to new. This could be as trivial as memcpy, or may require fix-ups.</div>=
<div><br></div><div>- The old memory is freed.</div><div><br></div><div>In =
the absence of <font face=3D"courier new,monospace">realloc_in_place</font>=
; and for trivially relocatable objects only; it would work for a container=
to call <font face=3D"courier new,monospace">realloc</font>, also.</div><d=
iv><br></div><div>To permit use with <font face=3D"courier new,monospace">r=
ealloc</font> with=C2=A0non-trivially relocatable=C2=A0objects, the relocat=
or would have to:</div><div><br></div><div>- use constructor-like syntax (t=
he old location is gone when it is called);</div><div><br></div><div>- acce=
pt a <font face=3D"courier new,monospace">ptrdiff_t</font> instead of refer=
ence to the old location.</div><div><br></div><div>The <font face=3D"courie=
r new,monospace">ptrdiff_t</font> would be the offset between the old locat=
ion and the new one, and would allow the relocator to=C2=A0perform any patc=
h-ups.=C2=A0</div><div><br></div><div>The drawback of this approach is that=
, if you have a small object; e.g. libc++ std::string, which is just=C2=A0o=
ne pointer=C2=A0in size; and this object requires a patch-up during relocat=
ion; it's twice as costly to execute realloc + patch-up, than to execut=
e a relocator that performs the copy as part of its process.</div><div><br>=
</div><div>Basically, the lack of a <font face=3D"courier new,monospace">re=
alloc_in_place</font> or equivalent is the deficiency.=C2=A0A feature such =
as relocation should not be designed around a library deficiency that shoul=
d=C2=A0relatively trivial to solve.</div><div><br></div><div><br></div><div=
>> does "user-declared=E2=80=9D also cover declarations that are &q=
uot;=3D default=E2=80=9D?</div><div><br></div><div>Yes, it does. For exampl=
e, if you have this:</div><div><br></div><div><font face=3D"courier new,mon=
ospace">=C2=A0 struct B {</font></div><div><font face=3D"courier new,monosp=
ace">=C2=A0 =C2=A0 B(B const&) { ... }</font></div><div><font face=3D"c=
ourier new,monospace">=C2=A0 =C2=A0 B(B&&) { ... }</font></div><div=
><font face=3D"courier new,monospace">=C2=A0 };</font></div><div><font face=
=3D"courier new,monospace"><br></font></div><div><font face=3D"courier new,=
monospace">=C2=A0 struct A : B {</font></div><div><font face=3D"courier new=
,monospace">=C2=A0 =C2=A0 A(A const&) =3D default;</font></div><div><fo=
nt face=3D"courier new,monospace">=C2=A0 };</font></div><div><br></div><div=
>The user declaration of A(A const&) -=C2=A0even as default -=C2=A0bloc=
ks an implicit declaration of a=C2=A0move constructor for A. To get an impl=
icitly defined move constructor, one must use either this:</div><div><br></=
div><div><font face=3D"courier new,monospace">=C2=A0 struct A : B {</font><=
/div><div><font face=3D"courier new,monospace">=C2=A0 };</font></div><div><=
br></div><div>or this:</div><div><br></div><div><div><font face=3D"courier =
new,monospace">=C2=A0 struct A : B {</font></div><div><div><font face=3D"co=
urier new,monospace">=C2=A0 =C2=A0 A(A const&) =3D default;</font></div=
><div><font face=3D"courier new,monospace">=C2=A0=C2=A0 =C2=A0A(A&&=
) =3D default;</font></div><font face=3D"courier new,monospace">=C2=A0 };</=
font></div></div><div><br><br>On Saturday, August 8, 2015 at 4:27:16 PM UTC=
-6, vlovich wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: =
0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204)=
; border-left-width: 1px; border-left-style: solid;"><div>I like many thing=
s about this proposal & thank you for trying to tackle this. =C2=A0Apol=
ogies if already covered, but can you clarify why there is a distinction be=
tween the multiple & single relocators? =C2=A0Am I correct in guessing =
that it=E2=80=99s to try & avoid the loop overhead when you only have a=
single object? =C2=A0Some other reason?<div><br></div><div>The =E2=80=9Cco=
mposition=E2=80=9D section seems to read kind of contradictory to the termi=
nology being used to frame the solution. =C2=A0If construction order is ind=
eed more appropriate (which I think you are correct on), doesn=E2=80=99t it=
speak that this is more naturally thought of as a destructive move constru=
ctor? =C2=A0Beyond just semantics, I think users writing their own may easi=
ly get confused about which order they need to destroy/construct & bugs=
in this area will be very subtle, hard-to-find & particularly nasty.</=
div><div><br></div><div>nitpicks:</div><div><br></div><div>The static keywo=
rd preceding the function=C2=A0A::~A seems out-of-place no? =C2=A0I could b=
e mistaken, but the static keyword is illegal in this context & can onl=
y be there on free-standing functions or on functions as part of the class =
declaration; it cannot be used for external class function definition. =C2=
=A0Is the static keyword in this place new to this proposal or C++17?</div>=
<div><br></div><div><div>While discussion relocation, there is what amounts=
to a footnote mentioning realloc. =C2=A0Is it correct that this is the lan=
guage proposal that would complement any eventual library features that wou=
ld enable the use of realloc within containers? =C2=A0I think that could do=
with some clarification to properly frame the discussion; it sounds like t=
his is trying to solve the memcpy problem but it seems like it solves both =
that & realloc, no?</div><div><br></div></div><div>I=E2=80=99m not very=
familiar with the standardese terminology, so apologies for the silly ques=
tion, but In the "Implicit relocator=E2=80=9D section, does "user=
-declared=E2=80=9D also cover declarations that are "=3D default=E2=80=
=9D?</div><div><br></div><div>Thanks,</div><div>Vitali</div><div><br></div>=
<div><br><div><div><blockquote type=3D"cite"><div>On Aug 8, 2015, at 1:37 A=
M, <a rel=3D"nofollow">isocp...@denisbider.com</a> wrote:</div><br><div><di=
v dir=3D"ltr"><div>I have published an updated draft:</div><div><br></div><=
div><a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3=
A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQj=
CNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;" onclick=3D"this.href=3D&#=
39;http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FRelocato=
r.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';=
return true;" href=3D"http://www.denisbider.com/Relocator.pdf" target=3D"_b=
lank" rel=3D"nofollow">http://www.denisbider.com/<wbr>Relocator.pdf</a><br>=
</div><div><br></div><div>I have consistently renamed move destructor ->=
relocator and move destruction -> relocation.=C2=A0Reason is=C2=A0expla=
ined in a new section, Rationales, on last page.</div><div><br></div><div><=
br></div><div>Comments:</div><div><br></div><div>> Might want to explain=
"destructive move"</div><div>> in the opening paragraph. </di=
v><div><br></div><div>Very good, done.</div><div><br></div><div><br></div><=
div>> - Might want to mention std::unique_ptr?</div><div>> This is a =
really simple example=C2=A0 of a class that is</div><div>> trivially rel=
ocatable but has an "interesting" move <br>> constructor and &=
quot;interesting" destructor. <br></div><div><br></div><div>I've s=
pent a fair amount of time thinking about this, but I cannot think of a con=
tainer scenario involving unique_ptr that's worse than string. unique_p=
tr already has nothrow move construction; and has nothrow destruction as lo=
ng as the object has nothrow destruction; and in any case, it=C2=A0will not=
throw after a move. I'm having some trouble conjuring a situation wher=
e the lack of relocation for unique_ptr does not result in strictly a perfo=
rmance penalty for having to execute a non-trivial destructor.</div><div><b=
r>Did you have a specific scenario involving unique_ptr in mind?</div><div>=
<br></div><div><br></div><div>> In the defaulted example, s.b. ~int(int&=
amp;).</div><div><br></div><div>Good point, done that.<br></div><div><br></=
div><div><br></div><div>> explain elsewhere when a cting-dtor is trivial=
</div><div><br></div><div>Edited text where trait types are defined in an a=
ttempt to better explain this.</div><div><br></div><div><br></div><div>>=
The multiple object helper should work</div><div>> on overlapping memor=
y.</div><div><br></div><div>It should indeed. :) Fixed!</div><div><br></div=
><div><br></div><div>> Should(n't) the cting-dtor be implicit-defaul=
t if the</div><div>> class has a) a=C2=A0*default* move ctor *or copy ct=
or*,</div><div>> *and* b) a default dtor, whether or=C2=A0not such are d=
eclared?</div><div><br></div><div>Hmm. I wouldn't necessarily mind, but=
current rules for move constructor wouldn't implicitly declare one if =
a copy constructor or destructor, or any=C2=A0other special member, is user=
-declared.=C2=A0The way I read 12.8, para 9, the following:</div><div><br><=
/div><div><font face=3D"courier new,monospace">struct A {</font></div><div>=
<font face=3D"courier new,monospace">=C2=A0 A(A const&) =3D default;</f=
ont></div><div><font face=3D"courier new,monospace">};</font></div><div><br=
></div><div>would result in a move constructor NOT being implicitly declare=
d.</div><div><br></div><div>As far as I can test right now, this is the cas=
e. If A inherits from B, which implements=C2=A0both move=C2=A0and copy cons=
truction,=C2=A0I can observe that trying to move A actually results in copy=
construction of B. I need add:</div><div><br></div><div><div><font face=3D=
"courier new,monospace">struct A : B=C2=A0{</font></div><div><div><font fac=
e=3D"courier new,monospace">=C2=A0 A(A const&) =3D default;</font></div=
><font face=3D"courier new,monospace">=C2=A0 A(A&&) =3D default;</f=
ont></div><div><font face=3D"courier new,monospace">};</font></div><div><br=
></div><div>... in order for B(B&&) to be called.</div><div><br></d=
iv><div>For consistency as well as safety, it would make sense to me to use=
the same rules for the relocator.</div><div><br></div><div><br></div><div>=
> I feel fairly strongly that there should be a cutoff point</div><div>&=
gt; for which we can use the same syntax to relocate</div><div>> objects=
that can't be simply relocated.</div><div><br></div><div>I agree, but =
I think it should be at a level above this. I have added a discussion in th=
e Rationales section.</div><div><br></div><div><br></div><div>> I'm =
not entirely confident that the composition case is</div><div>> solved. =
As worded, the class members are relocated</div><div>> after the base cl=
ass has been destroyed</div><div><br></div><div>The relocator performs the =
tasks of both a constructor and a destructor, so one of the two orders have=
to be chosen. I have added a section for this in the Rationales section.</=
div><div><br></div><div>I hope also that calling the special member a "=
;relocator"; expressing its duality and impartiality, rather than a bi=
as toward construction or destruction;=C2=A0might also help alleviate this =
concern.</div><div><br></div><div><br></div></div><div><br>On Friday, Augus=
t 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bo=
rder-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-st=
yle: solid;">On 2015-08-07 16:47, <a rel=3D"nofollow">isocp...@denisbider.c=
om</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div><div><br></div>
-- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google=
..com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.h=
ref=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></div></blockquote></div></blockqu=
ote></div>
<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 />
------=_Part_3512_938554273.1439121649395--
------=_Part_3511_1342032902.1439121649394--
.
Author: jgottman6@gmail.com
Date: Sun, 9 Aug 2015 18:14:18 -0700 (PDT)
Raw View
------=_Part_3989_1001969736.1439169258973
Content-Type: multipart/alternative;
boundary="----=_Part_3990_1045747249.1439169258974"
------=_Part_3990_1045747249.1439169258974
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Very nice, but I have one question. How do you handle member variables=20
that might or might not be self-references? For instance, in your example,=
=20
if the variable a is guaranteed to be either equal to this or a pointer to=
=20
an object allocated with new, how would you write the relocator function? =
=20
Most other members of class A could have code like
if (a =3D=3D this) {
//do something
} else {
//do something else
}
but in the case of the relocator function, by the time we get to the a=20
variable half the object has been relocated and it's not at all obvious=20
what needs to be tested.
Joe Gottman
On Sunday, August 9, 2015 at 8:00:49 AM UTC-4, isocp...@denisbider.com=20
wrote:
>
> In fact - I am sufficiently convinced that constructor-like syntax is mor=
e=20
> intuitive, that I have gone ahead and converted the proposal. It now puts=
=20
> constructor-like syntax front and center.
>
> Just in case, I still have the previous version. But I think this will be=
=20
> more intuitive.
>
>
> On Sunday, August 9, 2015 at 4:57:09 AM UTC-6, isocp...@denisbider.com=20
> wrote:
>
>> > If construction order is indeed more appropriate (which I
>> > think you are correct on), doesn=E2=80=99t it speak that this is
>> > more naturally thought of as a destructive move constructor?
>>
>> Yes, I think you're very right!
>>
>> I have updated the proposal with an annex that presents an alternate=20
>> constructor-like syntax, and discusses the merits and demerits of the tw=
o=20
>> approaches:
>>
>> http://denisbider.com/Relocator.pdf
>>
>> It seems to me that the constructor-like approach may in fact be=20
>> superior; no more complex, yet more intuitive; and potentially more=20
>> extensible, if needed.
>>
>> If folks like this, I'm leaning to promote constructor-like syntax from=
=20
>> the annex, and place it in the center of the proposal.
>>
>>
>> > distinction between the multiple & single relocators?
>>
>> Yes - it's just a formal distinction to emphasize cost-less optimization=
=20
>> of the single-object case. I have added to the text to make this clearer=
..
>>
>>
>> > The static keyword preceding the function A::~A
>> > seems out-of-place no?
>>
>> It is illegal in the definition, yes. It's okay in the declaration.
>>
>> I have changed the definition to put "static" into C-style comments. I'm=
=20
>> still keeping it, to make it clear that the wrappers are invoked as stat=
ic=20
>> members.
>>
>>
>> > it sounds like this is trying to solve the memcpy problem
>> > but it seems like it solves both that & realloc, no?
>>
>> To properly solve the realloc problem, it would be necessary to have the=
=20
>> equivalent of realloc_in_place.
>>
>> If realloc_in_place or equivalent fails:
>>
>> - The equivalent of malloc needs to be used to allocate new memory, whil=
e=20
>> keeping old memory.
>>
>> - The static relocator needs to be called to move objects from old=20
>> location to new. This could be as trivial as memcpy, or may require fix-=
ups.
>>
>> - The old memory is freed.
>>
>> In the absence of realloc_in_place; and for trivially relocatable=20
>> objects only; it would work for a container to call realloc, also.
>>
>> To permit use with realloc with non-trivially relocatable objects, the=
=20
>> relocator would have to:
>>
>> - use constructor-like syntax (the old location is gone when it is=20
>> called);
>>
>> - accept a ptrdiff_t instead of reference to the old location.
>>
>> The ptrdiff_t would be the offset between the old location and the new=
=20
>> one, and would allow the relocator to perform any patch-ups.=20
>>
>> The drawback of this approach is that, if you have a small object; e.g.=
=20
>> libc++ std::string, which is just one pointer in size; and this object=
=20
>> requires a patch-up during relocation; it's twice as costly to execute=
=20
>> realloc + patch-up, than to execute a relocator that performs the copy a=
s=20
>> part of its process.
>>
>> Basically, the lack of a realloc_in_place or equivalent is the=20
>> deficiency. A feature such as relocation should not be designed around a=
=20
>> library deficiency that should relatively trivial to solve.
>>
>>
>> > does "user-declared=E2=80=9D also cover declarations that are "=3D def=
ault=E2=80=9D?
>>
>> Yes, it does. For example, if you have this:
>>
>> struct B {
>> B(B const&) { ... }
>> B(B&&) { ... }
>> };
>>
>> struct A : B {
>> A(A const&) =3D default;
>> };
>>
>> The user declaration of A(A const&) - even as default - blocks an=20
>> implicit declaration of a move constructor for A. To get an implicitly=
=20
>> defined move constructor, one must use either this:
>>
>> struct A : B {
>> };
>>
>> or this:
>>
>> struct A : B {
>> A(A const&) =3D default;
>> A(A&&) =3D default;
>> };
>>
>>
>> On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:
>>
>>> I like many things about this proposal & thank you for trying to tackle=
=20
>>> this. Apologies if already covered, but can you clarify why there is a=
=20
>>> distinction between the multiple & single relocators? Am I correct in=
=20
>>> guessing that it=E2=80=99s to try & avoid the loop overhead when you on=
ly have a=20
>>> single object? Some other reason?
>>>
>>> The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contrad=
ictory to the=20
>>> terminology being used to frame the solution. If construction order is=
=20
>>> indeed more appropriate (which I think you are correct on), doesn=E2=80=
=99t it=20
>>> speak that this is more naturally thought of as a destructive move=20
>>> constructor? Beyond just semantics, I think users writing their own ma=
y=20
>>> easily get confused about which order they need to destroy/construct & =
bugs=20
>>> in this area will be very subtle, hard-to-find & particularly nasty.
>>>
>>> nitpicks:
>>>
>>> The static keyword preceding the function A::~A seems out-of-place no?=
=20
>>> I could be mistaken, but the static keyword is illegal in this context=
&=20
>>> can only be there on free-standing functions or on functions as part of=
the=20
>>> class declaration; it cannot be used for external class function=20
>>> definition. Is the static keyword in this place new to this proposal o=
r=20
>>> C++17?
>>>
>>> While discussion relocation, there is what amounts to a footnote=20
>>> mentioning realloc. Is it correct that this is the language proposal t=
hat=20
>>> would complement any eventual library features that would enable the us=
e of=20
>>> realloc within containers? I think that could do with some clarificati=
on=20
>>> to properly frame the discussion; it sounds like this is trying to solv=
e=20
>>> the memcpy problem but it seems like it solves both that & realloc, no?
>>>
>>> I=E2=80=99m not very familiar with the standardese terminology, so apol=
ogies for=20
>>> the silly question, but In the "Implicit relocator=E2=80=9D section, do=
es=20
>>> "user-declared=E2=80=9D also cover declarations that are "=3D default=
=E2=80=9D?
>>>
>>> Thanks,
>>> Vitali
>>>
>>>
>>> On Aug 8, 2015, at 1:37 AM, isocp...@denisbider.com wrote:
>>>
>>> I have published an updated draft:
>>>
>>> http://www.denisbider.com/Relocator.pdf
>>>
>>> I have consistently renamed move destructor -> relocator and move=20
>>> destruction -> relocation. Reason is explained in a new section,=20
>>> Rationales, on last page.
>>>
>>>
>>> Comments:
>>>
>>> > Might want to explain "destructive move"
>>> > in the opening paragraph.=20
>>>
>>> Very good, done.
>>>
>>>
>>> > - Might want to mention std::unique_ptr?
>>> > This is a really simple example of a class that is
>>> > trivially relocatable but has an "interesting" move=20
>>> > constructor and "interesting" destructor.=20
>>>
>>> I've spent a fair amount of time thinking about this, but I cannot thin=
k=20
>>> of a container scenario involving unique_ptr that's worse than string.=
=20
>>> unique_ptr already has nothrow move construction; and has nothrow=20
>>> destruction as long as the object has nothrow destruction; and in any c=
ase,=20
>>> it will not throw after a move. I'm having some trouble conjuring a=20
>>> situation where the lack of relocation for unique_ptr does not result i=
n=20
>>> strictly a performance penalty for having to execute a non-trivial=20
>>> destructor.
>>>
>>> Did you have a specific scenario involving unique_ptr in mind?
>>>
>>>
>>> > In the defaulted example, s.b. ~int(int&).
>>>
>>> Good point, done that.
>>>
>>>
>>> > explain elsewhere when a cting-dtor is trivial
>>>
>>> Edited text where trait types are defined in an attempt to better=20
>>> explain this.
>>>
>>>
>>> > The multiple object helper should work
>>> > on overlapping memory.
>>>
>>> It should indeed. :) Fixed!
>>>
>>>
>>> > Should(n't) the cting-dtor be implicit-default if the
>>> > class has a) a *default* move ctor *or copy ctor*,
>>> > *and* b) a default dtor, whether or not such are declared?
>>>
>>> Hmm. I wouldn't necessarily mind, but current rules for move constructo=
r=20
>>> wouldn't implicitly declare one if a copy constructor or destructor, or=
=20
>>> any other special member, is user-declared. The way I read 12.8, para 9=
,=20
>>> the following:
>>>
>>> struct A {
>>> A(A const&) =3D default;
>>> };
>>>
>>> would result in a move constructor NOT being implicitly declared.
>>>
>>> As far as I can test right now, this is the case. If A inherits from B,=
=20
>>> which implements both move and copy construction, I can observe that tr=
ying=20
>>> to move A actually results in copy construction of B. I need add:
>>>
>>> struct A : B {
>>> A(A const&) =3D default;
>>> A(A&&) =3D default;
>>> };
>>>
>>> ... in order for B(B&&) to be called.
>>>
>>> For consistency as well as safety, it would make sense to me to use the=
=20
>>> same rules for the relocator.
>>>
>>>
>>> > I feel fairly strongly that there should be a cutoff point
>>> > for which we can use the same syntax to relocate
>>> > objects that can't be simply relocated.
>>>
>>> I agree, but I think it should be at a level above this. I have added a=
=20
>>> discussion in the Rationales section.
>>>
>>>
>>> > I'm not entirely confident that the composition case is
>>> > solved. As worded, the class members are relocated
>>> > after the base class has been destroyed
>>>
>>> The relocator performs the tasks of both a constructor and a destructor=
,=20
>>> so one of the two orders have to be chosen. I have added a section for =
this=20
>>> in the Rationales section.
>>>
>>> I hope also that calling the special member a "relocator"; expressing=
=20
>>> its duality and impartiality, rather than a bias toward construction or=
=20
>>> destruction; might also help alleviate this concern.
>>>
>>>
>>>
>>> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>>>
>>>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:=20
>>>> > I believe the destructive move Jesus is upon us!=20
>>>> >=20
>>>> > I have uploaded the following draft:=20
>>>> >=20
>>>> > http://www.denisbider.com/MoveDestructor.pdf=20
>>>>
>>>> Editorial comments:=20
>>>>
>>>> - Might want to explain "destructive move" in the opening paragraph.=
=20
>>>>
>>>> - Might want to mention std::unique_ptr? This is a really simple=20
>>>> example=20
>>>> of a class that is trivially relocatable but has an "interesting" move=
=20
>>>> constructor and "interesting" destructor.=20
>>>>
>>>>
>>>> Nits:=20
>>>>
>>>> - In the defaulted example, s.b. ~int(int&). That is, define the=20
>>>> default=20
>>>> behavior as cting-dtor for ALL members, and explain elsewhere when a=
=20
>>>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=
=20
>>>> relocatable members" case seems sufficiently covered) and that trivial=
=20
>>>> means to just copy the bits. (Also, it's expected that the compiler=20
>>>> will=20
>>>> combine trivial cting-dtors of adjacent members into a single memcpy.)=
=20
>>>> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
>>>> anything.)=20
>>>>
>>>>
>>>> Not-so-nits:=20
>>>>
>>>> - The multiple object helper should work on overlapping memory. I=20
>>>> imagine you intended this, but I don't see any wording to that effect;=
=20
>>>> it seems to me that such wording may be important.=20
>>>>
>>>> - Should(n't) the cting-dtor be implicit-default if the class has a) a=
=20
>>>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether o=
r=20
>>>> not such are declared?=20
>>>>
>>>> - I feel fairly strongly that there should be a cutoff point for which=
=20
>>>> we can use the same syntax to relocate objects that can't be simply=20
>>>> relocated. I proposed that there is *always* a cting-dtor (except for=
=20
>>>> objects that explicitly delete it, or can't be copied/moved and/or=20
>>>> destroyed at all, i.e. the fallback implementation would be=20
>>>> ill-formed),=20
>>>> but at any rate, I think the helpers should work regardless.=20
>>>>
>>>> - I'm not entirely confident that the composition case is solved. As=
=20
>>>> worded, the class members are relocated after the base class has been=
=20
>>>> destroyed (moveover, the derived class itself is technically=20
>>>> "destroyed"=20
>>>> after the base class has been destroyed), which seems like it could=20
>>>> present problems... :-( Unfortunately I don't have any suggestions=20
>>>> here.=20
>>>> I do hope that this won't kill the proposal though.=20
>>>>
>>>>
>>>> Comments:=20
>>>>
>>>> - It took me a minute or two to understand the invocation helpers, but=
=20
>>>> now that I do, I like! IIUC what these mean is that instead of=20
>>>> libraries=20
>>>> having to check a type trait and write a memmove themselves, the=20
>>>> compiler will do so. Cool!=20
>>>>
>>>>
>>>> Bikesheds (JFTR):=20
>>>>
>>>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>>>>
>>>> - "cting-dtor" vs. "move-dtor" ;-).=20
>>>>
>>>> - Type trait names.=20
>>>>
>>>>
>>>> Thanks for sticking with this!=20
>>>>
>>>> --=20
>>>> Matthew=20
>>>>
>>>>
>>> --=20
>>>
>>> ---=20
>>> You received this message because you are subscribed to the Google=20
>>> Groups "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send=
=20
>>> an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at=20
>>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>>
>>>
>>>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3990_1045747249.1439169258974
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><code></code>Very nice, but I have one question.=C2=A0 How=
do you handle member variables that might or might not be self-references?=
=C2=A0 For instance, in your example, if the variable <code>a is guaranteed=
to be either equal to this or a pointer to an object allocated with new, h=
ow would you write the relocator function?=C2=A0 Most other members of clas=
s A could have code like<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">this</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//do something</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">else</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0<=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">//do someth=
ing else</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div>=
</code></div><br>but in the case of the relocator function, by the time we =
get to the a variable half the object has been relocated and it's not a=
t all obvious what needs to be tested.<br><br>Joe Gottman<br><br></code><br=
><br>On Sunday, August 9, 2015 at 8:00:49 AM UTC-4, isocp...@denisbider.com=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>I=
n fact - I am sufficiently convinced that constructor-like syntax is more i=
ntuitive, that I have gone ahead and converted the proposal. It now puts co=
nstructor-like syntax front and center.</div><div><br></div><div>Just in ca=
se, I still have the previous version. But I think this will be more intuit=
ive.</div><div><br></div><div><br>On Sunday, August 9, 2015 at 4:57:09 AM U=
TC-6, <a>isocp...@denisbider.com</a> wrote:</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-colo=
r:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div dir=
=3D"ltr"><div>> If construction order is indeed more appropriate (which =
I<br>> think you are correct on), doesn=E2=80=99t it speak that this is<=
br>> more naturally thought of as a destructive move constructor?</div><=
div><br></div><div>Yes,=C2=A0I think you're=C2=A0very right!</div><div>=
<br></div><div>I have updated the proposal with an annex that presents an a=
lternate constructor-like syntax, and discusses the merits and demerits of =
the two approaches:</div><div><br></div><div><a href=3D"http://denisbider.c=
om/Relocator.pdf" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fdenisbider.com%2FReloc=
ator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGRaVpviwtOSXhpXtDNRASkBLXVYw=
9;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75=
http%3A%2F%2Fdenisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AF=
QjCNGRaVpviwtOSXhpXtDNRASkBLXVYw';return true;">http://denisbider.com/<=
wbr>Relocator.pdf</a><br></div><div><br></div><div>It seems to me that the =
constructor-like approach may in fact be superior; no more complex,=C2=A0ye=
t more intuitive; and potentially more extensible, if needed.</div><div><br=
></div><div>If folks like this, I'm leaning to=C2=A0promote constructor=
-like syntax=C2=A0from the annex, and=C2=A0place it in the center of the pr=
oposal.</div><div><br></div><div><br></div><div>> distinction between th=
e multiple & single relocators?</div><div><br></div><div>Yes - it's=
just a formal distinction to=C2=A0emphasize cost-less optimization of the =
single-object case. I have added=C2=A0to the text=C2=A0to make this clearer=
..</div><div><br></div><div><br></div><div>> The static keyword preceding=
the function=C2=A0A::~A</div><div>> seems out-of-place no?</div><div><b=
r></div><div>It is illegal in the definition, yes. It's okay in the dec=
laration.</div><div><br></div><div>I have changed the definition to put &qu=
ot;static" into C-style comments. I'm still keeping it, to=C2=A0ma=
ke it clear that the wrappers are=C2=A0invoked as static members.</div><div=
><br></div><div><br></div><div>> it sounds like this is trying to solve =
the memcpy problem</div><div>> but it seems like it solves both that &am=
p; realloc, no?</div><div><br></div><div>To properly solve the <font face=
=3D"courier new,monospace">realloc</font> problem, it would be necessary to=
have=C2=A0the equivalent of=C2=A0<font face=3D"courier new,monospace">real=
loc_in_place</font>.</div><div><br></div><div>If <font face=3D"courier new,=
monospace">realloc_in_place</font> or equivalent fails:</div><div><br></div=
><div>- The equivalent of malloc needs to be used to allocate new memory, w=
hile keeping old memory.</div><div><br></div><div>- The static relocator ne=
eds to be called to move objects from old location to new. This could be as=
trivial as memcpy, or may require fix-ups.</div><div><br></div><div>- The =
old memory is freed.</div><div><br></div><div>In the absence of <font face=
=3D"courier new,monospace">realloc_in_place</font>; and for trivially reloc=
atable objects only; it would work for a container to call <font face=3D"co=
urier new,monospace">realloc</font>, also.</div><div><br></div><div>To perm=
it use with <font face=3D"courier new,monospace">realloc</font> with=C2=A0n=
on-trivially relocatable=C2=A0objects, the relocator would have to:</div><d=
iv><br></div><div>- use constructor-like syntax (the old location is gone w=
hen it is called);</div><div><br></div><div>- accept a <font face=3D"courie=
r new,monospace">ptrdiff_t</font> instead of reference to the old location.=
</div><div><br></div><div>The <font face=3D"courier new,monospace">ptrdiff_=
t</font> would be the offset between the old location and the new one, and =
would allow the relocator to=C2=A0perform any patch-ups.=C2=A0</div><div><b=
r></div><div>The drawback of this approach is that, if you have a small obj=
ect; e.g. libc++ std::string, which is just=C2=A0one pointer=C2=A0in size; =
and this object requires a patch-up during relocation; it's twice as co=
stly to execute realloc + patch-up, than to execute a relocator that perfor=
ms the copy as part of its process.</div><div><br></div><div>Basically, the=
lack of a <font face=3D"courier new,monospace">realloc_in_place</font> or =
equivalent is the deficiency.=C2=A0A feature such as relocation should not =
be designed around a library deficiency that should=C2=A0relatively trivial=
to solve.</div><div><br></div><div><br></div><div>> does "user-dec=
lared=E2=80=9D also cover declarations that are "=3D default=E2=80=9D?=
</div><div><br></div><div>Yes, it does. For example, if you have this:</div=
><div><br></div><div><font face=3D"courier new,monospace">=C2=A0 struct B {=
</font></div><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 B(B co=
nst&) { ... }</font></div><div><font face=3D"courier new,monospace">=C2=
=A0 =C2=A0 B(B&&) { ... }</font></div><div><font face=3D"courier ne=
w,monospace">=C2=A0 };</font></div><div><font face=3D"courier new,monospace=
"><br></font></div><div><font face=3D"courier new,monospace">=C2=A0 struct =
A : B {</font></div><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0=
A(A const&) =3D default;</font></div><div><font face=3D"courier new,mo=
nospace">=C2=A0 };</font></div><div><br></div><div>The user declaration of =
A(A const&) -=C2=A0even as default -=C2=A0blocks an implicit declaratio=
n of a=C2=A0move constructor for A. To get an implicitly defined move const=
ructor, one must use either this:</div><div><br></div><div><font face=3D"co=
urier new,monospace">=C2=A0 struct A : B {</font></div><div><font face=3D"c=
ourier new,monospace">=C2=A0 };</font></div><div><br></div><div>or this:</d=
iv><div><br></div><div><div><font face=3D"courier new,monospace">=C2=A0 str=
uct A : B {</font></div><div><div><font face=3D"courier new,monospace">=C2=
=A0 =C2=A0 A(A const&) =3D default;</font></div><div><font face=3D"cour=
ier new,monospace">=C2=A0=C2=A0 =C2=A0A(A&&) =3D default;</font></d=
iv><font face=3D"courier new,monospace">=C2=A0 };</font></div></div><div><b=
r><br>On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding=
-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-l=
eft-style:solid"><div>I like many things about this proposal & thank yo=
u for trying to tackle this. =C2=A0Apologies if already covered, but can yo=
u clarify why there is a distinction between the multiple & single relo=
cators? =C2=A0Am I correct in guessing that it=E2=80=99s to try & avoid=
the loop overhead when you only have a single object? =C2=A0Some other rea=
son?<div><br></div><div>The =E2=80=9Ccomposition=E2=80=9D section seems to =
read kind of contradictory to the terminology being used to frame the solut=
ion. =C2=A0If construction order is indeed more appropriate (which I think =
you are correct on), doesn=E2=80=99t it speak that this is more naturally t=
hought of as a destructive move constructor? =C2=A0Beyond just semantics, I=
think users writing their own may easily get confused about which order th=
ey need to destroy/construct & bugs in this area will be very subtle, h=
ard-to-find & particularly nasty.</div><div><br></div><div>nitpicks:</d=
iv><div><br></div><div>The static keyword preceding the function=C2=A0A::~A=
seems out-of-place no? =C2=A0I could be mistaken, but the static keyword i=
s illegal in this context & can only be there on free-standing function=
s or on functions as part of the class declaration; it cannot be used for e=
xternal class function definition. =C2=A0Is the static keyword in this plac=
e new to this proposal or C++17?</div><div><br></div><div><div>While discus=
sion relocation, there is what amounts to a footnote mentioning realloc. =
=C2=A0Is it correct that this is the language proposal that would complemen=
t any eventual library features that would enable the use of realloc within=
containers? =C2=A0I think that could do with some clarification to properl=
y frame the discussion; it sounds like this is trying to solve the memcpy p=
roblem but it seems like it solves both that & realloc, no?</div><div><=
br></div></div><div>I=E2=80=99m not very familiar with the standardese term=
inology, so apologies for the silly question, but In the "Implicit rel=
ocator=E2=80=9D section, does "user-declared=E2=80=9D also cover decla=
rations that are "=3D default=E2=80=9D?</div><div><br></div><div>Thank=
s,</div><div>Vitali</div><div><br></div><div><br><div><div><blockquote type=
=3D"cite"><div>On Aug 8, 2015, at 1:37 AM, <a rel=3D"nofollow">isocp...@den=
isbider.com</a> wrote:</div><br><div><div dir=3D"ltr"><div>I have published=
an updated draft:</div><div><br></div><div><a href=3D"http://www.denisbide=
r.com/Relocator.pdf" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdv=
VOsQ';return true;" onclick=3D"this.href=3D'http://www.google.com/u=
rl?q\75http%3A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751=
\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;">http://www.d=
enisbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><div>I have co=
nsistently renamed move destructor -> relocator and move destruction -&g=
t; relocation.=C2=A0Reason is=C2=A0explained in a new section, Rationales, =
on last page.</div><div><br></div><div><br></div><div>Comments:</div><div><=
br></div><div>> Might want to explain "destructive move"</div>=
<div>> in the opening paragraph. </div><div><br></div><div>Very good, do=
ne.</div><div><br></div><div><br></div><div>> - Might want to mention st=
d::unique_ptr?</div><div>> This is a really simple example=C2=A0 of a cl=
ass that is</div><div>> trivially relocatable but has an "interesti=
ng" move <br>> constructor and "interesting" destructor. =
<br></div><div><br></div><div>I've spent a fair amount of time thinking=
about this, but I cannot think of a container scenario involving unique_pt=
r that's worse than string. unique_ptr already has nothrow move constru=
ction; and has nothrow destruction as long as the object has nothrow destru=
ction; and in any case, it=C2=A0will not throw after a move. I'm having=
some trouble conjuring a situation where the lack of relocation for unique=
_ptr does not result in strictly a performance penalty for having to execut=
e a non-trivial destructor.</div><div><br>Did you have a specific scenario =
involving unique_ptr in mind?</div><div><br></div><div><br></div><div>> =
In the defaulted example, s.b. ~int(int&).</div><div><br></div><div>Goo=
d point, done that.<br></div><div><br></div><div><br></div><div>> explai=
n elsewhere when a cting-dtor is trivial</div><div><br></div><div>Edited te=
xt where trait types are defined in an attempt to better explain this.</div=
><div><br></div><div><br></div><div>> The multiple object helper should =
work</div><div>> on overlapping memory.</div><div><br></div><div>It shou=
ld indeed. :) Fixed!</div><div><br></div><div><br></div><div>> Should(n&=
#39;t) the cting-dtor be implicit-default if the</div><div>> class has a=
) a=C2=A0*default* move ctor *or copy ctor*,</div><div>> *and* b) a defa=
ult dtor, whether or=C2=A0not such are declared?</div><div><br></div><div>H=
mm. I wouldn't necessarily mind, but current rules for move constructor=
wouldn't implicitly declare one if a copy constructor or destructor, o=
r any=C2=A0other special member, is user-declared.=C2=A0The way I read 12.8=
, para 9, the following:</div><div><br></div><div><font face=3D"courier new=
,monospace">struct A {</font></div><div><font face=3D"courier new,monospace=
">=C2=A0 A(A const&) =3D default;</font></div><div><font face=3D"courie=
r new,monospace">};</font></div><div><br></div><div>would result in a move =
constructor NOT being implicitly declared.</div><div><br></div><div>As far =
as I can test right now, this is the case. If A inherits from B, which impl=
ements=C2=A0both move=C2=A0and copy construction,=C2=A0I can observe that t=
rying to move A actually results in copy construction of B. I need add:</di=
v><div><br></div><div><div><font face=3D"courier new,monospace">struct A : =
B=C2=A0{</font></div><div><div><font face=3D"courier new,monospace">=C2=A0 =
A(A const&) =3D default;</font></div><font face=3D"courier new,monospac=
e">=C2=A0 A(A&&) =3D default;</font></div><div><font face=3D"courie=
r new,monospace">};</font></div><div><br></div><div>... in order for B(B&am=
p;&) to be called.</div><div><br></div><div>For consistency as well as =
safety, it would make sense to me to use the same rules for the relocator.<=
/div><div><br></div><div><br></div><div>> I feel fairly strongly that th=
ere should be a cutoff point</div><div>> for which we can use the same s=
yntax to relocate</div><div>> objects that can't be simply relocated=
..</div><div><br></div><div>I agree, but I think it should be at a level abo=
ve this. I have added a discussion in the Rationales section.</div><div><br=
></div><div><br></div><div>> I'm not entirely confident that the com=
position case is</div><div>> solved. As worded, the class members are re=
located</div><div>> after the base class has been destroyed</div><div><b=
r></div><div>The relocator performs the tasks of both a constructor and a d=
estructor, so one of the two orders have to be chosen. I have added a secti=
on for this in the Rationales section.</div><div><br></div><div>I hope also=
that calling the special member a "relocator"; expressing its du=
ality and impartiality, rather than a bias toward construction or destructi=
on;=C2=A0might also help alleviate this concern.</div><div><br></div><div><=
br></div></div><div><br>On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matt=
hew Woehlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border=
-left-width:1px;border-left-style:solid">On 2015-08-07 16:47, <a rel=3D"nof=
ollow">isocp...@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a href=3D"http://www.denisbider.com/MoveDestructor.pdf" rel=3D"no=
follow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google=
..com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\=
46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" o=
nclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.d=
enisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4=
KskLTP7oqtb3GQp9_QLlboQ';return true;">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div><div><br></div>
-- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=
=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';ret=
urn true;" onclick=3D"this.href=3D'http://groups.google.com/a/isocpp.or=
g/group/std-proposals/';return true;">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></div></blockquote></div></blockqu=
ote></div></blockquote></div>
<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 />
------=_Part_3990_1045747249.1439169258974--
------=_Part_3989_1001969736.1439169258973--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 9 Aug 2015 18:58:39 -0700 (PDT)
Raw View
------=_Part_488_1183214092.1439171919413
Content-Type: multipart/alternative;
boundary="----=_Part_489_1955315911.1439171919413"
------=_Part_489_1955315911.1439171919413
Content-Type: text/plain; charset=UTF-8
On Sunday, August 9, 2015 at 9:14:19 PM UTC-4, jgot...@gmail.com wrote:
>
> Very nice, but I have one question. How do you handle member variables
> that might or might not be self-references?
>
As I understand it, that's quite simple.
If you have a class that potentially contains a self-reference, then there
are certain things you must do in order for it to be functional. Such a
class *must* have a non-trivial copy constructor/assignment operator; if
you user-define it, the copy's pointer must now refer to the copy (you
could also delete it). Such a class *must* have a non-trivial move
constructor/assignment operator; if you user-define it, the moved object's
pointer must now refer to the target of the move.
In short: even before this proposal was enacted, if such a class was to be
functional, it could never have been trivially copyable or trivially
moveable. And by inference, it cannot under this proposal be trivially
relocatable. So such a class *cannot* be memcpy'd or realloc'd. It can
still undergo the process of relocation, but it cannot be trivial
relocation. So you get the benefit of a combined move+destructor. But
that's all.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_489_1955315911.1439171919413
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, August 9, 2015 at 9:14:19 PM UTC-4, jgo=
t...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><code></code>Very nice, but I have one question.=C2=A0 How do you =
handle member variables that might or might not be self-references?</div></=
blockquote><div><br>As I understand it, that's quite simple.<br><br>If =
you have a class that potentially contains a self-reference, then there are=
certain things you must do in order for it to be functional. Such a class =
<i>must</i> have a non-trivial copy constructor/assignment operator; if you=
user-define it, the copy's pointer must now refer to the copy (you cou=
ld also delete it). Such a class <i>must</i> have a non-trivial move constr=
uctor/assignment operator; if you user-define it, the moved object's po=
inter must now refer to the target of the move.<br><br>In short: even befor=
e this proposal was enacted, if such a class was to be functional, it could=
never have been trivially copyable or trivially moveable. And by inference=
, it cannot under this proposal be trivially relocatable. So such a class <=
i>cannot</i> be memcpy'd or realloc'd. It can still undergo the pro=
cess of relocation, but it cannot be trivial relocation. So you get the ben=
efit of a combined move+destructor. But that's all.</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_489_1955315911.1439171919413--
------=_Part_488_1183214092.1439171919413--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 10 Aug 2015 10:05:08 -0400
Raw View
On 2015-08-07 17:51, isocppgroup@denisbider.com wrote:
> Great responses! Thank you!
>=20
> I urgently have to sleep, but I've had the following idea:
>=20
> Do you think we should approach this from the opposite direction - a=20
> destructing constructor?
No. IIRC that was actually the original idea, and I'd also thought on it
a good bit, but...
Being able to pass an object destructively, to a ctor or otherwise,
feels like it would be a really useful feature. However, the problem I
keep running into when going down that train of thought is how on earth
the compiler is supposed to track object lifetimes in order to know to
not destroy the object again. (There's also the problem that a
destructed parameter needs to be destroyed somehow, and likely not in
the usual manner.)
Consider, for example:
void* pfoo =3D allocate_storage<Foo>();
if (expr) // assume 'expr' is something that changes at runtime
new (pfoo) Foo(std::destruct(old_foo));
else
new (pfoo) Foo{};
I suppose this already comes up with explicit calls to dtors, so the
compiler in theory does already know how to deal with it(?), but it
still makes me twitchy. The advantage of a cting-dtor/move-dtor is that
it a) should more directly leverage such existing support, and b)
clearly looks like a dtor, i.e. someone reading the code is less likely
to overlook that an object was destroyed.
Anyway, that's my take... I wouldn't say I'm firmly opposed to it, just
that I thought about it and it seemed that a cting-dtor was preferable.
(There's also no=C2=B9 syntax change, vs. introducing a 'T~'/'T~&'/etc..)
(=C2=B9 ...depending on if dtors are precisely specified syntactically to
take no parameters.)
--=20
Matthew
--=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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 10 Aug 2015 10:29:22 -0400
Raw View
(Note: just replying to comments for now; haven't yet read the updated
draft.)
On 2015-08-08 04:37, isocppgroup@denisbider.com wrote:
>> - Might want to mention std::unique_ptr?
>> This is a really simple example of a class that is
>> trivially relocatable but has an "interesting" move
>> constructor and "interesting" destructor.
>
> I've spent a fair amount of time thinking about this, but I cannot think of
> a container scenario involving unique_ptr that's worse than string.
Certainly, and that's sort of my point; std::string is a pathological
case; it is NEVER trivially relocatable. unique_ptr is an example of the
opposite; a class with "important" move ctor and dtor, but that *is*
trivially relocatable.
Basically, there are four classes of object, for this purpose:
- C-like types (trivial ctors, dtor, trivially relocatable)
- "Interesting" but trivially relocatable (std::unique_ptr)
- Relocatable with repair (std::string)
- Not (practically) relocatable
> unique_ptr already has nothrow move construction; and has nothrow
> destruction as long as the object has nothrow destruction; and in any case,
> it will not throw after a move. I'm having some trouble conjuring a
> situation where the lack of relocation for unique_ptr does not result in
> strictly a performance penalty for having to execute a non-trivial
> destructor.
I... think that's my point? It's not that std::unique_ptr is worse than
std::string... it's *better*, because it's trivially relocatable.
Therefore it makes a good poster child for how relocatability is
extremely useful in trivial cases (which can be reduced entirely to
memmove).
Basically, what I meant is that I would cover (i.e. call out
specifically) the first three cases above, at least with brief mentions.
The first case, we hopefully get implicit relocatability and a huge win
because we can use a straight up memmove with no looping (besides the
memmove itself). The first case we have to explicitly declare trivial
relocatability, but we get the same huge win (more so, even, because the
ctor and/or dtor was non-trivial). The third case needs to be handled
more carefully, and that's the case you've covered thoroughly already.
So, really, that's all I was getting at... just that it seems it would
strengthen the case to give a little more mention to the easy examples
also and how we get an easy but major win from those.
Hope that makes sense...
>> Should(n't) the cting-dtor be implicit-default if the
>> class has a) a *default* move ctor *or copy ctor*,
>> *and* b) a default dtor, whether or not such are declared?
>
> Hmm. I wouldn't necessarily mind, but current rules for move constructor
> wouldn't implicitly declare one if a copy constructor or destructor, or
> any other special member, is user-declared. The way I read 12.8, para 9,
> the following:
>
> struct A {
> A(A const&) = default;
> };
>
> would result in a move constructor NOT being implicitly declared.
Truuuuuue... see however my comment about libraries being able to use
this for any type that is relocatable - whether or not that has to fall
back on (separate) move-construct and destroy - without having to check
a type trait. It's mostly for that reason that I think you should always
have a cting-dtor unless it is suppressed either explicitly, or by there
being no sensible implicit definition possible.
--
Matthew
--
---
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: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 09:00:02 -0700 (PDT)
Raw View
------=_Part_4617_1244612664.1439222402172
Content-Type: multipart/alternative;
boundary="----=_Part_4618_1798610023.1439222402173"
------=_Part_4618_1798610023.1439222402173
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Matthew:
> I wouldn't say I'm firmly opposed to it, just that I
> thought about it and it seemed that a cting-dtor
> was preferable. (There's also no=C2=B9 syntax change,
> vs. introducing a 'T~'/'T~&'/etc..)=20
After studying the syntax of ~T(T&), which operates on old object, and=20
takes new object as parameter; and >>T(T&) - which is identical in=20
function, but takes old object as parameter; it seems to me that=20
implementation of >>T(T&) is much more intuitive.
With the invocation I propose, I think that would look intuitive also:
T* oldArray;
void* newStorage =3D allocate_storage<T>(n);
T* newArray =3D T::>>T(newStorage, oldArray, n);
It even has a built-in arrow, showing that things are going from T to T...=
=20
:)
> Certainly, and that's sort of my point; std::string
> is a pathological case; it is NEVER trivially relocatable.
Ah, gotcha!
It seems like the misunderstanding was in our different assumptions.
From my point of view (VS), what I usually see is a string that's 4 pointer=
=20
types in size, and is trivially relocatable. A string with SSO is the weird=
=20
case.
From your point of view (libc++), you always see a string that's 1 pointer=
=20
type in size, and has SSO. A string without SSO is the weird case.
I have edited a sentence in the draft to recognize this:
http://denisbider.com/Relocator.pdf
"For example, fix-ups are needed by std::string in libc++, which uses=20
self-references for short string optimization; yet they are not needed by=
=20
std::unique_ptr, or std::string in Visual Studio."
On Monday, August 10, 2015 at 8:05:17 AM UTC-6, Matthew Woehlke wrote:
> On 2015-08-07 17:51, isocp...@denisbider.com <javascript:> wrote:=20
> > Great responses! Thank you!=20
> >=20
> > I urgently have to sleep, but I've had the following idea:=20
> >=20
> > Do you think we should approach this from the opposite direction - a=20
> > destructing constructor?=20
>
> No. IIRC that was actually the original idea, and I'd also thought on it=
=20
> a good bit, but...=20
>
> Being able to pass an object destructively, to a ctor or otherwise,=20
> feels like it would be a really useful feature. However, the problem I=20
> keep running into when going down that train of thought is how on earth=
=20
> the compiler is supposed to track object lifetimes in order to know to=20
> not destroy the object again. (There's also the problem that a=20
> destructed parameter needs to be destroyed somehow, and likely not in=20
> the usual manner.)=20
>
> Consider, for example:=20
>
> void* pfoo =3D allocate_storage<Foo>();=20
> if (expr) // assume 'expr' is something that changes at runtime=20
> new (pfoo) Foo(std::destruct(old_foo));=20
> else=20
> new (pfoo) Foo{};=20
>
> I suppose this already comes up with explicit calls to dtors, so the=20
> compiler in theory does already know how to deal with it(?), but it=20
> still makes me twitchy. The advantage of a cting-dtor/move-dtor is that=
=20
> it a) should more directly leverage such existing support, and b)=20
> clearly looks like a dtor, i.e. someone reading the code is less likely=
=20
> to overlook that an object was destroyed.=20
>
> Anyway, that's my take... I wouldn't say I'm firmly opposed to it, just=
=20
> that I thought about it and it seemed that a cting-dtor was preferable.=
=20
> (There's also no=C2=B9 syntax change, vs. introducing a 'T~'/'T~&'/etc..)=
=20
>
> (=C2=B9 ...depending on if dtors are precisely specified syntactically to=
=20
> take no parameters.)=20
>
> --=20
> Matthew=20
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_4618_1798610023.1439222402173
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Matthew:</div><div><br></div><div>> I wouldn't=
say I'm firmly opposed to it, just that I</div><div>> thought about=
it and it seemed that a cting-dtor</div><div>> was preferable.=C2=A0 (T=
here's also no=C2=B9 syntax change,</div><div>> vs. introducing a &#=
39;T~'/'T~&'/etc..) <br></div><div><br></div><div>After stu=
dying the syntax of ~T(T&), which operates on old object, and takes new=
object as parameter; and >>T(T&) - which is identical in functio=
n, but takes old object as parameter; it seems to me that implementation of=
>>T(T&) is much more intuitive.</div><div><br></div><div>With th=
e invocation I propose, I think that would=C2=A0look intuitive also:</div><=
div><br></div><div><font face=3D"courier new,monospace">T* oldArray;</font>=
</div><div><font face=3D"courier new,monospace">void* newStorage=C2=A0=3D a=
llocate_storage<T>(n);</font></div><div><font face=3D"courier new,mon=
ospace">T* newArray =3D T::>>T(newStorage, oldArray, n);</font></div>=
<div><br></div><div>It even has a built-in=C2=A0arrow,=C2=A0showing that th=
ings are going from T to T... :)</div><div><br></div><div><br></div><div>&g=
t; Certainly, and that's sort of my point; std::string</div><div>> i=
s a pathological case; it is NEVER trivially relocatable.</div><div><br></d=
iv><div>Ah, gotcha!</div><div><br></div><div>It seems like the misunderstan=
ding was=C2=A0in our different assumptions.</div><div><br></div><div>From m=
y point of view (VS),=C2=A0what=C2=A0I usually see is=C2=A0a string=C2=A0th=
at's 4 pointer types=C2=A0in size, and is trivially relocatable. A stri=
ng with SSO is the weird case.</div><div><br></div><div>From your point of =
view (libc++), you=C2=A0always see=C2=A0a string=C2=A0that's=C2=A01 poi=
nter type=C2=A0in size, and has SSO. A string without SSO is the weird case=
..</div><div><br></div><div>I have edited a=C2=A0sentence in the draft to re=
cognize this:</div><div><br></div><div><a href=3D"http://denisbider.com/Rel=
ocator.pdf">http://denisbider.com/Relocator.pdf</a></div><div><br></div><di=
v>"For example, fix-ups are needed by std::string in libc++, which use=
s self-references for short string optimization; yet they are not needed by=
std::unique_ptr, or std::string in Visual Studio."</div><div><br></di=
v><div><br>On Monday, August 10, 2015 at 8:05:17 AM UTC-6, Matthew Woehlke =
wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px =
0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-lef=
t-width: 1px; border-left-style: solid;">On 2015-08-07 17:51, <a onmousedow=
n=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;" href=3D"javascript:" target=3D"_blan=
k" rel=3D"nofollow" gdf-obfuscated-mailto=3D"eG-6MGBuAQAJ">isocp...@denisbi=
der.com</a> wrote:
<br>> Great responses! Thank you!
<br>>=20
<br>> I urgently have to sleep, but I've had the following idea:
<br>>=20
<br>> Do you think we should approach this from the opposite direction -=
a=20
<br>> destructing constructor?
<br>
<br>No. IIRC that was actually the original idea, and I'd also thought =
on it
<br>a good bit, but...
<br>
<br>Being able to pass an object destructively, to a ctor or otherwise,
<br>feels like it would be a really useful feature. However, the problem I
<br>keep running into when going down that train of thought is how on earth
<br>the compiler is supposed to track object lifetimes in order to know to
<br>not destroy the object again. (There's also the problem that a
<br>destructed parameter needs to be destroyed somehow, and likely not in
<br>the usual manner.)
<br>
<br>Consider, for example:
<br>
<br>=C2=A0 void* pfoo =3D allocate_storage<Foo>();
<br>=C2=A0 if (expr) // assume 'expr' is something that changes at =
runtime
<br>=C2=A0 =C2=A0 new (pfoo) Foo(std::destruct(old_foo));
<br>=C2=A0 else
<br>=C2=A0 =C2=A0 new (pfoo) Foo{};
<br>
<br>I suppose this already comes up with explicit calls to dtors, so the
<br>compiler in theory does already know how to deal with it(?), but it
<br>still makes me twitchy. The advantage of a cting-dtor/move-dtor is that
<br>it a) should more directly leverage such existing support, and b)
<br>clearly looks like a dtor, i.e. someone reading the code is less likely
<br>to overlook that an object was destroyed.
<br>
<br>Anyway, that's my take... I wouldn't say I'm firmly opposed=
to it, just
<br>that I thought about it and it seemed that a cting-dtor was preferable.
<br>(There's also no=C2=B9 syntax change, vs. introducing a 'T~'=
;/'T~&'/etc..)
<br>
<br>(=C2=B9 ...depending on if dtors are precisely specified syntactically =
to
<br>take no parameters.)
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_4618_1798610023.1439222402173--
------=_Part_4617_1244612664.1439222402172--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 10 Aug 2015 12:21:47 -0400
Raw View
On 2015-08-10 12:00, isocppgroup@denisbider.com wrote:
>> Certainly, and that's sort of my point; std::string
>> is a pathological case; it is NEVER trivially relocatable.
>
> Ah, gotcha!
>
> It seems like the misunderstanding was in our different assumptions.
>
> From my point of view (VS), what I usually see is a string that's 4 pointer
> types in size, and is trivially relocatable. A string with SSO is the weird
> case.
>
> From your point of view (libc++), you always see a string that's 1 pointer
> type in size, and has SSO. A string without SSO is the weird case.
Ah! Yes, that would be it. I was assuming you were using (e.g.
libstdc++) std::string as an example where memcpy (esp. large block
memcpy of a vector of adjacent objects) can *help*, but the object still
needs to be corrected after, and not as a trivially relocatable object.
--
Matthew
--
---
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: Thiago Macieira <thiago@macieira.org>
Date: Mon, 10 Aug 2015 09:22:23 -0700
Raw View
On Monday 10 August 2015 09:00:02 isocppgroup@denisbider.com wrote:
> "For example, fix-ups are needed by std::string in libc++, which uses
> self-references for short string optimization; yet they are not needed by
> std::unique_ptr, or std::string in Visual Studio."
That's libstdc++, not libc++.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 10:45:46 -0700 (PDT)
Raw View
------=_Part_4722_702655073.1439228746626
Content-Type: multipart/alternative;
boundary="----=_Part_4723_1346840608.1439228746638"
------=_Part_4723_1346840608.1439228746638
Content-Type: text/plain; charset=UTF-8
Thanks! Fixed. I appreciate the correction.
On Monday, August 10, 2015 at 10:22:28 AM UTC-6, Thiago Macieira wrote:
>
> On Monday 10 August 2015 09:00:02 isocp...@denisbider.com <javascript:>
> wrote:
> > "For example, fix-ups are needed by std::string in libc++, which uses
> > self-references for short string optimization; yet they are not needed
> by
> > std::unique_ptr, or std::string in Visual Studio."
>
> That's libstdc++, not libc++.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4723_1346840608.1439228746638
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Thanks! Fixed. I appreciate the correction.<br><br>On Mond=
ay, August 10, 2015 at 10:22:28 AM UTC-6, Thiago Macieira wrote:<blockquote=
class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1e=
x; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-le=
ft-style: solid;">On Monday 10 August 2015 09:00:02 <a onmousedown=3D"this.=
href=3D'javascript:';return true;" onclick=3D"this.href=3D'java=
script:';return true;" href=3D"javascript:" target=3D"_blank" rel=3D"no=
follow" gdf-obfuscated-mailto=3D"tIEqotx1AQAJ">isocp...@denisbider.com</a> =
wrote:
<br>> "For example, fix-ups are needed by std::string in libc++, wh=
ich uses=20
<br>> self-references for short string optimization; yet they are not ne=
eded by=20
<br>> std::unique_ptr, or std::string in Visual Studio."
<br>
<br>That's libstdc++, not libc++.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a onmousedown=3D"this.href=3D'http:/=
/www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\7=
5D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;=
" href=3D"http://macieira.info" target=3D"_blank" rel=3D"nofollow">macieira=
..info</a> - thiago (AT) <a onmousedown=3D"this.href=3D'http://www.googl=
e.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJd=
o5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'http=
://www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;" href=3D"http://kde.o=
rg" target=3D"_blank" rel=3D"nofollow">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
5358
<br>
<br></blockquote></div>
<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 />
------=_Part_4723_1346840608.1439228746638--
------=_Part_4722_702655073.1439228746626--
.
Author: Vitali Lovich <vlovich@gmail.com>
Date: Mon, 10 Aug 2015 12:52:31 -0700
Raw View
--Apple-Mail-A9A7FBDF-163F-43D4-B4BC-7A25CC8557FE
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
> On Aug 9, 2015, at 3:57 AM, isocppgroup@denisbider.com wrote:
>=20
> > If construction order is indeed more appropriate (which I
> > think you are correct on), doesn=E2=80=99t it speak that this is
> > more naturally thought of as a destructive move constructor?
>=20
> Yes, I think you're very right!
>=20
> I have updated the proposal with an annex that presents an alternate cons=
tructor-like syntax, and discusses the merits and demerits of the two appro=
aches:
>=20
> http://denisbider.com/Relocator.pdf
>=20
> It seems to me that the constructor-like approach may in fact be superior=
; no more complex, yet more intuitive; and potentially more extensible, if =
needed.
>=20
> If folks like this, I'm leaning to promote constructor-like syntax from t=
he annex, and place it in the center of the proposal.
>=20
>=20
> > distinction between the multiple & single relocators?
>=20
> Yes - it's just a formal distinction to emphasize cost-less optimization =
of the single-object case. I have added to the text to make this clearer.
I misread the part where it says these can only be generated by the compile=
r so I thought people would have to write them some times. From the call-s=
ite, distinguishing the one/many case makes things more legible.
> > The static keyword preceding the function A::~A
> > seems out-of-place no?
>=20
> It is illegal in the definition, yes. It's okay in the declaration.
> I have changed the definition to put "static" into C-style comments. I'm =
still keeping it, to make it clear that the wrappers are invoked as static =
members.
Yup. I was just thrown by the static keyword on the definition.
>=20
> > it sounds like this is trying to solve the memcpy problem
> > but it seems like it solves both that & realloc, no?
>=20
> To properly solve the realloc problem, it would be necessary to have the =
equivalent of realloc_in_place.
>=20
> If realloc_in_place or equivalent fails:
>=20
> - The equivalent of malloc needs to be used to allocate new memory, while=
keeping old memory.
>=20
> - The static relocator needs to be called to move objects from old locati=
on to new. This could be as trivial as memcpy, or may require fix-ups.
>=20
> - The old memory is freed.
>=20
> In the absence of realloc_in_place; and for trivially relocatable objects=
only; it would work for a container to call realloc, also.
>=20
> To permit use with realloc with non-trivially relocatable objects, the re=
locator would have to:
>=20
> - use constructor-like syntax (the old location is gone when it is called=
);
>=20
> - accept a ptrdiff_t instead of reference to the old location.
>=20
> The ptrdiff_t would be the offset between the old location and the new on=
e, and would allow the relocator to perform any patch-ups.=20
>=20
> The drawback of this approach is that, if you have a small object; e.g. l=
ibc++ std::string, which is just one pointer in size; and this object requi=
res a patch-up during relocation; it's twice as costly to execute realloc +=
patch-up, than to execute a relocator that performs the copy as part of it=
s process.
Probably off-topic, but can you expand on this point? Why 2x? For instanc=
e, realloc frequently will have a ptrdiff of 0 which can be optimized out, =
no? Especially for larger regions of memory where all the OS needs to do i=
s tack on an extra VM page which is when you'd get the most benefit from re=
alloc. Even if there is an offset, surely realloc + patch up can't be more=
costly than malloc+memcpy + relocate since patch necessarily is a simpler =
operation and you avoid a memcpy (or worse if you have non-trivial relocati=
on).
That being said, I'm not sure you could even do the patch-up for something =
that contains a self-reference without invoking undefined behavior...
> Basically, the lack of a realloc_in_place or equivalent is the deficiency=
.. A feature such as relocation should not be designed around a library defi=
ciency that should relatively trivial to solve.
Well, as you point out, realloc requires the object to patch itself which c=
an't be done as a library-level feature, can it? I guess it could have a n=
on-special function that the library calls to "fixup" an object but that fe=
els dangerous. Anyway, if realloc is a different problem, does it make sen=
se to put in clarifying wording about what specific problem this is trying =
to solve and perhaps mention the story about realloc more clearly? I'm obv=
iously late to the discussion, am missing context and haven't reread it in =
a few days, so if you feel that's already covered in the proposal, feel fre=
e to ignore.
> > does "user-declared=E2=80=9D also cover declarations that are "=3D defa=
ult=E2=80=9D?
>=20
> Yes, it does. For example, if you have this:
>=20
> struct B {
> B(B const&) { ... }
> B(B&&) { ... }
> };
>=20
> struct A : B {
> A(A const&) =3D default;
> };
>=20
> The user declaration of A(A const&) - even as default - blocks an implici=
t declaration of a move constructor for A. To get an implicitly defined mov=
e constructor, one must use either this:
>=20
> struct A : B {
> };
>=20
> or this:
>=20
> struct A : B {
> A(A const&) =3D default;
> A(A&&) =3D default;
> };
>=20
>=20
>> On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:
>> I like many things about this proposal & thank you for trying to tackle =
this. Apologies if already covered, but can you clarify why there is a dis=
tinction between the multiple & single relocators? Am I correct in guessin=
g that it=E2=80=99s to try & avoid the loop overhead when you only have a s=
ingle object? Some other reason?
>>=20
>> The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contradi=
ctory to the terminology being used to frame the solution. If construction=
order is indeed more appropriate (which I think you are correct on), doesn=
=E2=80=99t it speak that this is more naturally thought of as a destructive=
move constructor? Beyond just semantics, I think users writing their own =
may easily get confused about which order they need to destroy/construct & =
bugs in this area will be very subtle, hard-to-find & particularly nasty.
>>=20
>> nitpicks:
>>=20
>> The static keyword preceding the function A::~A seems out-of-place no? =
I could be mistaken, but the static keyword is illegal in this context & ca=
n only be there on free-standing functions or on functions as part of the c=
lass declaration; it cannot be used for external class function definition.=
Is the static keyword in this place new to this proposal or C++17?
>>=20
>> While discussion relocation, there is what amounts to a footnote mention=
ing realloc. Is it correct that this is the language proposal that would c=
omplement any eventual library features that would enable the use of reallo=
c within containers? I think that could do with some clarification to prop=
erly frame the discussion; it sounds like this is trying to solve the memcp=
y problem but it seems like it solves both that & realloc, no?
>>=20
>> I=E2=80=99m not very familiar with the standardese terminology, so apolo=
gies for the silly question, but In the "Implicit relocator=E2=80=9D sectio=
n, does "user-declared=E2=80=9D also cover declarations that are "=3D defau=
lt=E2=80=9D?
>>=20
>> Thanks,
>> Vitali
>>=20
>>=20
>>> On Aug 8, 2015, at 1:37 AM, isocp...@denisbider.com wrote:
>>>=20
>>> I have published an updated draft:
>>>=20
>>> http://www.denisbider.com/Relocator.pdf
>>>=20
>>> I have consistently renamed move destructor -> relocator and move destr=
uction -> relocation. Reason is explained in a new section, Rationales, on =
last page.
>>>=20
>>>=20
>>> Comments:
>>>=20
>>> > Might want to explain "destructive move"
>>> > in the opening paragraph.
>>>=20
>>> Very good, done.
>>>=20
>>>=20
>>> > - Might want to mention std::unique_ptr?
>>> > This is a really simple example of a class that is
>>> > trivially relocatable but has an "interesting" move=20
>>> > constructor and "interesting" destructor.=20
>>>=20
>>> I've spent a fair amount of time thinking about this, but I cannot thin=
k of a container scenario involving unique_ptr that's worse than string. un=
ique_ptr already has nothrow move construction; and has nothrow destruction=
as long as the object has nothrow destruction; and in any case, it will no=
t throw after a move. I'm having some trouble conjuring a situation where t=
he lack of relocation for unique_ptr does not result in strictly a performa=
nce penalty for having to execute a non-trivial destructor.
>>>=20
>>> Did you have a specific scenario involving unique_ptr in mind?
>>>=20
>>>=20
>>> > In the defaulted example, s.b. ~int(int&).
>>>=20
>>> Good point, done that.
>>>=20
>>>=20
>>> > explain elsewhere when a cting-dtor is trivial
>>>=20
>>> Edited text where trait types are defined in an attempt to better expla=
in this.
>>>=20
>>>=20
>>> > The multiple object helper should work
>>> > on overlapping memory.
>>>=20
>>> It should indeed. :) Fixed!
>>>=20
>>>=20
>>> > Should(n't) the cting-dtor be implicit-default if the
>>> > class has a) a *default* move ctor *or copy ctor*,
>>> > *and* b) a default dtor, whether or not such are declared?
>>>=20
>>> Hmm. I wouldn't necessarily mind, but current rules for move constructo=
r wouldn't implicitly declare one if a copy constructor or destructor, or a=
ny other special member, is user-declared. The way I read 12.8, para 9, the=
following:
>>>=20
>>> struct A {
>>> A(A const&) =3D default;
>>> };
>>>=20
>>> would result in a move constructor NOT being implicitly declared.
>>>=20
>>> As far as I can test right now, this is the case. If A inherits from B,=
which implements both move and copy construction, I can observe that tryin=
g to move A actually results in copy construction of B. I need add:
>>>=20
>>> struct A : B {
>>> A(A const&) =3D default;
>>> A(A&&) =3D default;
>>> };
>>>=20
>>> ... in order for B(B&&) to be called.
>>>=20
>>> For consistency as well as safety, it would make sense to me to use the=
same rules for the relocator.
>>>=20
>>>=20
>>> > I feel fairly strongly that there should be a cutoff point
>>> > for which we can use the same syntax to relocate
>>> > objects that can't be simply relocated.
>>>=20
>>> I agree, but I think it should be at a level above this. I have added a=
discussion in the Rationales section.
>>>=20
>>>=20
>>> > I'm not entirely confident that the composition case is
>>> > solved. As worded, the class members are relocated
>>> > after the base class has been destroyed
>>>=20
>>> The relocator performs the tasks of both a constructor and a destructor=
, so one of the two orders have to be chosen. I have added a section for th=
is in the Rationales section.
>>>=20
>>> I hope also that calling the special member a "relocator"; expressing i=
ts duality and impartiality, rather than a bias toward construction or dest=
ruction; might also help alleviate this concern.
>>>=20
>>>=20
>>>=20
>>>> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>>>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:=20
>>>> > I believe the destructive move Jesus is upon us!=20
>>>> >=20
>>>> > I have uploaded the following draft:=20
>>>> >=20
>>>> > http://www.denisbider.com/MoveDestructor.pdf=20
>>>>=20
>>>> Editorial comments:=20
>>>>=20
>>>> - Might want to explain "destructive move" in the opening paragraph.=
=20
>>>>=20
>>>> - Might want to mention std::unique_ptr? This is a really simple examp=
le=20
>>>> of a class that is trivially relocatable but has an "interesting" move=
=20
>>>> constructor and "interesting" destructor.=20
>>>>=20
>>>>=20
>>>> Nits:=20
>>>>=20
>>>> - In the defaulted example, s.b. ~int(int&). That is, define the defau=
lt=20
>>>> behavior as cting-dtor for ALL members, and explain elsewhere when a=
=20
>>>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=
=20
>>>> relocatable members" case seems sufficiently covered) and that trivial=
=20
>>>> means to just copy the bits. (Also, it's expected that the compiler wi=
ll=20
>>>> combine trivial cting-dtors of adjacent members into a single memcpy.)=
=20
>>>> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
>>>> anything.)=20
>>>>=20
>>>>=20
>>>> Not-so-nits:=20
>>>>=20
>>>> - The multiple object helper should work on overlapping memory. I=20
>>>> imagine you intended this, but I don't see any wording to that effect;=
=20
>>>> it seems to me that such wording may be important.=20
>>>>=20
>>>> - Should(n't) the cting-dtor be implicit-default if the class has a) a=
=20
>>>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether o=
r=20
>>>> not such are declared?=20
>>>>=20
>>>> - I feel fairly strongly that there should be a cutoff point for which=
=20
>>>> we can use the same syntax to relocate objects that can't be simply=20
>>>> relocated. I proposed that there is *always* a cting-dtor (except for=
=20
>>>> objects that explicitly delete it, or can't be copied/moved and/or=20
>>>> destroyed at all, i.e. the fallback implementation would be ill-formed=
),=20
>>>> but at any rate, I think the helpers should work regardless.=20
>>>>=20
>>>> - I'm not entirely confident that the composition case is solved. As=
=20
>>>> worded, the class members are relocated after the base class has been=
=20
>>>> destroyed (moveover, the derived class itself is technically "destroye=
d"=20
>>>> after the base class has been destroyed), which seems like it could=20
>>>> present problems... :-( Unfortunately I don't have any suggestions her=
e.=20
>>>> I do hope that this won't kill the proposal though.=20
>>>>=20
>>>>=20
>>>> Comments:=20
>>>>=20
>>>> - It took me a minute or two to understand the invocation helpers, but=
=20
>>>> now that I do, I like! IIUC what these mean is that instead of librari=
es=20
>>>> having to check a type trait and write a memmove themselves, the=20
>>>> compiler will do so. Cool!=20
>>>>=20
>>>>=20
>>>> Bikesheds (JFTR):=20
>>>>=20
>>>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>>>>=20
>>>> - "cting-dtor" vs. "move-dtor" ;-).=20
>>>>=20
>>>> - Type trait names.=20
>>>>=20
>>>>=20
>>>> Thanks for sticking with this!=20
>>>>=20
>>>> --=20
>>>> Matthew
>>>=20
>>>=20
>>> --=20
>>>=20
>>> ---=20
>>> You received this message because you are subscribed to the Google Grou=
ps "ISO C++ Standard - Future Proposals" group.
>>> To unsubscribe from this group and stop receiving emails from it, send =
an email to std-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> Visit this group at http://groups.google.com/a/isocpp.org/group/std-pro=
posals/.
>=20
> --=20
>=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=
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-propo=
sals/.
--=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-A9A7FBDF-163F-43D4-B4BC-7A25CC8557FE
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div><span></span></div><div><meta http=
-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8"><div></div><=
div><br></div><div><br>On Aug 9, 2015, at 3:57 AM, <a href=3D"mailto:isocpp=
group@denisbider.com">isocppgroup@denisbider.com</a> wrote:<br><br></div><b=
lockquote type=3D"cite"><div><div dir=3D"ltr"><div>> If construction ord=
er is indeed more appropriate (which I<br>> think you are correct on), d=
oesn=E2=80=99t it speak that this is<br>> more naturally thought of as a=
destructive move constructor?</div><div><br></div><div>Yes, I think y=
ou're very right!</div><div><br></div><div>I have updated the proposal=
with an annex that presents an alternate constructor-like syntax, and disc=
usses the merits and demerits of the two approaches:</div><div><br></div><d=
iv><a href=3D"http://denisbider.com/Relocator.pdf">http://denisbider.com/Re=
locator.pdf</a><br></div><div><br></div><div>It seems to me that the constr=
uctor-like approach may in fact be superior; no more complex, yet more=
intuitive; and potentially more extensible, if needed.</div><div><br></div=
><div>If folks like this, I'm leaning to promote constructor-like synt=
ax from the annex, and place it in the center of the proposal.</d=
iv><div><br></div><div><br></div><div>> distinction between the multiple=
& single relocators?</div><div><br></div><div>Yes - it's just a formal=
distinction to emphasize cost-less optimization of the single-object =
case. I have added to the text to make this clearer.</div></div><=
/div></blockquote><div>I misread the part where it says these can only be g=
enerated by the compiler so I thought people would have to write them some =
times. From the call-site, distinguishing the one/many case makes thi=
ngs more legible.</div><br><blockquote type=3D"cite"><div><div dir=3D"ltr">=
<div>> The static keyword preceding the function A::~A</div><div>&g=
t; seems out-of-place no?</div><div><br></div><div>It is illegal in the def=
inition, yes. It's okay in the declaration.</div></div></div></blockquote><=
blockquote type=3D"cite"><div dir=3D"ltr"><div>I have changed the definitio=
n to put "static" into C-style comments. I'm still keeping it, to make=
it clear that the wrappers are invoked as static members.</div></div>=
</blockquote>Yup. I was just thrown by the static keyword on the defi=
nition.<br><blockquote type=3D"cite"><div><div dir=3D"ltr"><div><br></div><=
div>> it sounds like this is trying to solve the memcpy problem</div><di=
v>> but it seems like it solves both that & realloc, no?</div><div><=
br></div><div>To properly solve the <font face=3D"courier new,monospace">re=
alloc</font> problem, it would be necessary to have the equivalent of&=
nbsp;<font face=3D"courier new,monospace">realloc_in_place</font>.</div><di=
v><br></div><div>If <font face=3D"courier new,monospace">realloc_in_place</=
font> or equivalent fails:</div><div><br></div><div>- The equivalent of mal=
loc needs to be used to allocate new memory, while keeping old memory.</div=
><div><br></div><div>- The static relocator needs to be called to move obje=
cts from old location to new. This could be as trivial as memcpy, or may re=
quire fix-ups.</div><div><br></div><div>- The old memory is freed.</div><di=
v><br></div><div>In the absence of <font face=3D"courier new,monospace">rea=
lloc_in_place</font>; and for trivially relocatable objects only; it would =
work for a container to call <font face=3D"courier new,monospace">realloc</=
font>, also.</div><div><br></div><div>To permit use with <font face=3D"cour=
ier new,monospace">realloc</font> with non-trivially relocatable =
objects, the relocator would have to:</div><div><br></div><div>- use constr=
uctor-like syntax (the old location is gone when it is called);</div><div><=
br></div><div>- accept a <font face=3D"courier new,monospace">ptrdiff_t</fo=
nt> instead of reference to the old location.</div><div><br></div><div>The =
<font face=3D"courier new,monospace">ptrdiff_t</font> would be the offset b=
etween the old location and the new one, and would allow the relocator to&n=
bsp;perform any patch-ups. </div><div><br></div><div>The drawback of t=
his approach is that, if you have a small object; e.g. libc++ std::string, =
which is just one pointer in size; and this object requires a pat=
ch-up during relocation; it's twice as costly to execute realloc + patch-up=
, than to execute a relocator that performs the copy as part of its process=
..</div></div></div></blockquote><div>Probably off-topic, but can you expand=
on this point? Why 2x? For instance, realloc frequently will h=
ave a ptrdiff of 0 which can be optimized out, no? Especially for lar=
ger regions of memory where all the OS needs to do is tack on an extra VM p=
age which is when you'd get the most benefit from realloc. Even if th=
ere is an offset, surely realloc + patch up can't be more costly than mallo=
c+memcpy + relocate since patch necessarily is a simpler operation and you =
avoid a memcpy (or worse if you have non-trivial relocation).</div><div><br=
></div><div>That being said, I'm not sure you could even do the patch-up fo=
r something that contains a self-reference without invoking undefined behav=
ior...</div><div><br></div><blockquote type=3D"cite"><div><div dir=3D"ltr">=
<div>Basically, the lack of a <font face=3D"courier new,monospace">realloc_=
in_place</font> or equivalent is the deficiency. A feature such as rel=
ocation should not be designed around a library deficiency that should =
;relatively trivial to solve.</div></div></div></blockquote><div>Well, as y=
ou point out, realloc requires the object to patch itself which can't be do=
ne as a library-level feature, can it? I guess it could have a non-sp=
ecial function that the library calls to "fixup" an object but that feels d=
angerous. Anyway, if realloc is a different problem, does it make sen=
se to put in clarifying wording about what specific problem this is trying =
to solve and perhaps mention the story about realloc more clearly? I'=
m obviously late to the discussion, am missing context and haven't reread i=
t in a few days, so if you feel that's already covered in the proposal, fee=
l free to ignore.</div><br><blockquote type=3D"cite"><div><div dir=3D"ltr">=
<div>> does "user-declared=E2=80=9D also cover declarations that are "=
=3D default=E2=80=9D?</div><div><br></div><div>Yes, it does. For example, i=
f you have this:</div><div><br></div><div><font face=3D"courier new,monospa=
ce"> struct B {</font></div><div><font face=3D"courier new,monospace"=
> B(B const&) { ... }</font></div><div><font face=3D"couri=
er new,monospace"> B(B&&) { ... }</font></div><div><fo=
nt face=3D"courier new,monospace"> };</font></div><div><font face=3D"=
courier new,monospace"><br></font></div><div><font face=3D"courier new,mono=
space"> struct A : B {</font></div><div><font face=3D"courier new,mon=
ospace"> A(A const&) =3D default;</font></div><div><font f=
ace=3D"courier new,monospace"> };</font></div><div><br></div><div>The=
user declaration of A(A const&) - even as default - blocks a=
n implicit declaration of a move constructor for A. To get an implicit=
ly defined move constructor, one must use either this:</div><div><br></div>=
<div><font face=3D"courier new,monospace"> struct A : B {</font></div=
><div><font face=3D"courier new,monospace"> };</font></div><div><br><=
/div><div>or this:</div><div><br></div><div><div><font face=3D"courier new,=
monospace"> struct A : B {</font></div><div><div><font face=3D"courie=
r new,monospace"> A(A const&) =3D default;</font></div><di=
v><font face=3D"courier new,monospace"> A(A&&) =
=3D default;</font></div><font face=3D"courier new,monospace"> };</fo=
nt></div></div><div><br><br>On Saturday, August 8, 2015 at 4:27:16 PM UTC-6=
, vlovich wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0p=
x 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); =
border-left-width: 1px; border-left-style: solid;"><div style=3D"-ms-word-w=
rap: break-word;">I like many things about this proposal & thank you fo=
r trying to tackle this. Apologies if already covered, but can you cl=
arify why there is a distinction between the multiple & single relocato=
rs? Am I correct in guessing that it=E2=80=99s to try & avoid the=
loop overhead when you only have a single object? Some other reason?=
<div><br></div><div>The =E2=80=9Ccomposition=E2=80=9D section seems to read=
kind of contradictory to the terminology being used to frame the solution.=
If construction order is indeed more appropriate (which I think you =
are correct on), doesn=E2=80=99t it speak that this is more naturally thoug=
ht of as a destructive move constructor? Beyond just semantics, I thi=
nk users writing their own may easily get confused about which order they n=
eed to destroy/construct & bugs in this area will be very subtle, hard-=
to-find & particularly nasty.</div><div><br></div><div>nitpicks:</div><=
div><br></div><div>The static keyword preceding the function A::~A see=
ms out-of-place no? I could be mistaken, but the static keyword is il=
legal in this context & can only be there on free-standing functions or=
on functions as part of the class declaration; it cannot be used for exter=
nal class function definition. Is the static keyword in this place ne=
w to this proposal or C++17?</div><div><br></div><div><div>While discussion=
relocation, there is what amounts to a footnote mentioning realloc. =
Is it correct that this is the language proposal that would complement any =
eventual library features that would enable the use of realloc within conta=
iners? I think that could do with some clarification to properly fram=
e the discussion; it sounds like this is trying to solve the memcpy problem=
but it seems like it solves both that & realloc, no?</div><div><br></d=
iv></div><div>I=E2=80=99m not very familiar with the standardese terminolog=
y, so apologies for the silly question, but In the "Implicit relocator=E2=
=80=9D section, does "user-declared=E2=80=9D also cover declarations that a=
re "=3D default=E2=80=9D?</div><div><br></div><div>Thanks,</div><div>Vitali=
</div><div><br></div><div><br><div><div><blockquote type=3D"cite"><div>On A=
ug 8, 2015, at 1:37 AM, <a onmousedown=3D"this.href=3D'javascript:';return =
true;" onclick=3D"this.href=3D'javascript:';return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"1ZLY4ZvsAAA=
J">isocp...@denisbider.com</a> wrote:</div><br><div><div dir=3D"ltr"><div>I=
have published an updated draft:</div><div><br></div><div><a onmousedown=
=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.=
com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg=
7hdvVOsQ';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;" href=3D"http://www.d=
enisbider.com/Relocator.pdf" target=3D"_blank" rel=3D"nofollow">http://www.=
denisbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><div>I have c=
onsistently renamed move destructor -> relocator and move destruction -&=
gt; relocation. Reason is explained in a new section, Rationales,=
on last page.</div><div><br></div><div><br></div><div>Comments:</div><div>=
<br></div><div>> Might want to explain "destructive move"</div><div>>=
in the opening paragraph. </div><div><br></div><div>Very good, done.</div>=
<div><br></div><div><br></div><div>> - Might want to mention std::unique=
_ptr?</div><div>> This is a really simple example of a class that =
is</div><div>> trivially relocatable but has an "interesting" move <br>&=
gt; constructor and "interesting" destructor. <br></div><div><br></div><div=
>I've spent a fair amount of time thinking about this, but I cannot think o=
f a container scenario involving unique_ptr that's worse than string. uniqu=
e_ptr already has nothrow move construction; and has nothrow destruction as=
long as the object has nothrow destruction; and in any case, it will =
not throw after a move. I'm having some trouble conjuring a situation where=
the lack of relocation for unique_ptr does not result in strictly a perfor=
mance penalty for having to execute a non-trivial destructor.</div><div><br=
>Did you have a specific scenario involving unique_ptr in mind?</div><div><=
br></div><div><br></div><div>> In the defaulted example, s.b. ~int(int&a=
mp;).</div><div><br></div><div>Good point, done that.<br></div><div><br></d=
iv><div><br></div><div>> explain elsewhere when a cting-dtor is trivial<=
/div><div><br></div><div>Edited text where trait types are defined in an at=
tempt to better explain this.</div><div><br></div><div><br></div><div>> =
The multiple object helper should work</div><div>> on overlapping memory=
..</div><div><br></div><div>It should indeed. :) Fixed!</div><div><br></div>=
<div><br></div><div>> Should(n't) the cting-dtor be implicit-default if =
the</div><div>> class has a) a *default* move ctor *or copy ctor*,<=
/div><div>> *and* b) a default dtor, whether or not such are declar=
ed?</div><div><br></div><div>Hmm. I wouldn't necessarily mind, but current =
rules for move constructor wouldn't implicitly declare one if a copy constr=
uctor or destructor, or any other special member, is user-declared.&nb=
sp;The way I read 12.8, para 9, the following:</div><div><br></div><div><fo=
nt face=3D"courier new,monospace">struct A {</font></div><div><font face=3D=
"courier new,monospace"> A(A const&) =3D default;</font></div><di=
v><font face=3D"courier new,monospace">};</font></div><div><br></div><div>w=
ould result in a move constructor NOT being implicitly declared.</div><div>=
<br></div><div>As far as I can test right now, this is the case. If A inher=
its from B, which implements both move and copy construction,&nbs=
p;I can observe that trying to move A actually results in copy construction=
of B. I need add:</div><div><br></div><div><div><font face=3D"courier new,=
monospace">struct A : B {</font></div><div><div><font face=3D"courier =
new,monospace"> A(A const&) =3D default;</font></div><font face=
=3D"courier new,monospace"> A(A&&) =3D default;</font></div><=
div><font face=3D"courier new,monospace">};</font></div><div><br></div><div=
>... in order for B(B&&) to be called.</div><div><br></div><div>For=
consistency as well as safety, it would make sense to me to use the same r=
ules for the relocator.</div><div><br></div><div><br></div><div>> I feel=
fairly strongly that there should be a cutoff point</div><div>> for whi=
ch we can use the same syntax to relocate</div><div>> objects that can't=
be simply relocated.</div><div><br></div><div>I agree, but I think it shou=
ld be at a level above this. I have added a discussion in the Rationales se=
ction.</div><div><br></div><div><br></div><div>> I'm not entirely confid=
ent that the composition case is</div><div>> solved. As worded, the clas=
s members are relocated</div><div>> after the base class has been destro=
yed</div><div><br></div><div>The relocator performs the tasks of both a con=
structor and a destructor, so one of the two orders have to be chosen. I ha=
ve added a section for this in the Rationales section.</div><div><br></div>=
<div>I hope also that calling the special member a "relocator"; expressing =
its duality and impartiality, rather than a bias toward construction or des=
truction; might also help alleviate this concern.</div><div><br></div>=
<div><br></div></div><div><br>On Friday, August 7, 2015 at 3:32:51 PM UTC-6=
, Matthew Woehlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204=
, 204); border-left-width: 1px; border-left-style: solid;">On 2015-08-07 16=
:47, <a rel=3D"nofollow">isocp...@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\=
75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FMoveDestru=
ctor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';r=
eturn true;" href=3D"http://www.denisbider.com/MoveDestructor.pdf" target=
=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>MoveDestructor.=
pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening paragraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting" move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivially
<br>relocatable members" case seems sufficiently covered) and that trivial
<br>means to just copy the bits. (Also, it's expected that the compiler wil=
l
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually change
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effect;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. As
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "destroyed=
"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions here=
..
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div><div><br></div>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" target=3D"=
_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"1ZLY4ZvsAAAJ">std-proposa=
l...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return true;" href=
=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=
=3D"1ZLY4ZvsAAAJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google.com=
/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.href=3D'h=
ttp://groups.google.com/a/isocpp.org/group/std-proposals/';return true;" hr=
ef=3D"http://groups.google.com/a/isocpp.org/group/std-proposals/" target=3D=
"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>isocpp.org/group/=
std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></div></blockquote></div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
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>
</div></blockquote></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-A9A7FBDF-163F-43D4-B4BC-7A25CC8557FE--
.
Author: Edward Catmur <ed@catmur.co.uk>
Date: Mon, 10 Aug 2015 13:20:27 -0700 (PDT)
Raw View
------=_Part_85_280231941.1439238028147
Content-Type: multipart/alternative;
boundary="----=_Part_86_1403924992.1439238028147"
------=_Part_86_1403924992.1439238028147
Content-Type: text/plain; charset=UTF-8
A few queries:
What exactly are the semantics of the mem-initializer-list, particularly
with regard to omitted, duplicated or misplaced bases/members:
struct A {
std::string q, r, s;
>>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
};
Is it ever legitimate for a mem-initializer to be omitted or to take any
form other than >>id(x.id) where the two identifiers are equivalent? If so,
whose responsibility is it to call the destructor on the corresponding
member of the source object? If not, would it be better to omit the
mem-initializer-list entirely, as with destructors?
Within the body of the relocator special member function, what are the
lifetime statuses of the source and destination objects, particularly with
regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
members of the source object, or is this undefined behavior as they are
destructed? If the type is polymorphic, is it permissible to dynamic_cast
or invoke virtual functions on the source? Indeed, is it permissible to
invoke any member functions on the source?
In particular, I'd like to make this utility class legal (noting that
aligned_storage_t is a POD but my utility class is not):
template<class T>
struct relocate_wrapper {
template<class... Args> relocate_wrapper(Args&&... args) {
new (&buf) T(std::forward<Args>(args)...);
}
~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
>>relocate_wrapper(relocate_wrapper& rhs) {
new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
reinterpret_cast<T&>(rhs.buf).~T();
}
std::aligned_storage_t<sizeof(T), alignof(T)> buf;
};
Hm... it might be nice to ensure that the relocator doesn't do any
unnecessary work copying the buffer that's just going to be placement new
moved into. Is that an argument against an implicit mem-initializer-list?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_86_1403924992.1439238028147
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>A few queries:</div><div><br></div><div>What exactly =
are the semantics of the mem-initializer-list, particularly with regard to =
omitted, duplicated or misplaced bases/members:<br></div><div><br></div><di=
v class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word=
-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">string</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> q</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> r</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> s</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">>></span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">A</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">A</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">r</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">r</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">>></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">/* oops */</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span></div></code></div><div><br></div><div>Is it ever legitima=
te for a mem-initializer to be omitted or to take any form other than <font=
face=3D"courier new, monospace">>>id(x.id)</font> where the two iden=
tifiers are equivalent? If so, whose responsibility is it to call the destr=
uctor on the corresponding member of the source object? If not, would it be=
better to omit the mem-initializer-list entirely, as with destructors?</di=
v><div><br></div><div>Within the body of the relocator special member funct=
ion, what are the lifetime statuses of the source and destination objects, =
particularly with regard to [class.cdtor]? Is it permissible to form lvalue=
s to the bases and members of the source object, or is this undefined behav=
ior as they are destructed? If the type is polymorphic, is it permissible t=
o dynamic_cast or invoke virtual functions on the source? Indeed, is it per=
missible to invoke any member functions on the source?</div><div><br></div>=
<div>In particular, I'd like to make this utility class legal (noting t=
hat aligned_storage_t is a POD but my utility class is not):</div><div><br>=
</div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 1=
87, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> relocate_wrapper </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>template</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> relocate_wrapper</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&&...</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> args</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(&</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">buf</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">forward</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">args=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">~</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">relocate_wrapper</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">reinterpret_cast</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&>(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">buf</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">).~</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">>></span><span style=3D"color:=
#000;" class=3D"styled-by-prettify">relocate_wrapper</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">relocate_wrapper</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">new</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(&=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">buf</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&&>(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">rhs</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">buf</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">reinterpret_cast</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
rhs</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">buf</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">).~</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">aligned_storage_t</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">alignof</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)></span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> buf</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">};</span></div></code></div><div><br></div></div><div>Hm... it =
might be nice to ensure that the relocator doesn't do any unnecessary w=
ork copying the buffer that's just going to be placement new moved into=
.. Is that an argument against an implicit mem-initializer-list?</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_86_1403924992.1439238028147--
------=_Part_85_280231941.1439238028147--
.
Author: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 13:42:00 -0700 (PDT)
Raw View
------=_Part_4929_1530091680.1439239321069
Content-Type: multipart/alternative;
boundary="----=_Part_4930_1722970052.1439239321070"
------=_Part_4930_1722970052.1439239321070
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
With regard to realloc - it boils down to that the following combination:
(1)
- copying relocator with signature >>T(T&)
- logic: if (!realloc_in_place) { malloc, copying_relocator, free }
is strictly at least as efficient, or more efficient than:
(2)
- patching relocator with signature >>T(ptrdiff_t)
- logic: if (realloc(p) !=3D p) { patching_relocator }
under the reasonable assumption that realloc_in_place is a strict subset of=
=20
realloc, like this:
realloc =3D if (!realloc_in_place) { malloc, memcpy, free }
The reason is that the first strategy boils down to:
if (!realloc_in_place) { malloc, copying_relocator, free }
Whereas the second strategy boils down to:
if (!realloc_in_place) { malloc, memcpy, free, patching_relocator }
You seem to be assuming that we have realloc, but we don't have=20
realloc_in_place.
However, it seems reasonable to me that if we can add support for=20
relocation, we can also add the equivalent of realloc_in_place.
And if we do add relocation, but do not add an equivalent of=20
realloc_in_place - which would be kinda sad, but okay - we can nevertheless=
=20
use platform-specific functionality that provides the equivalent of=20
realloc_in_place.
For example, on Windows, I have:
template <class T>
bool ReAllocInPlace (T* p, size_t n) noexcept
{ return HeapReAlloc(s_processHeap, HEAP_REALLOC_IN_PLACE_ONLY, p, n*
sizeof(T)) !=3D nullptr; }
On Monday, August 10, 2015 at 1:52:32 PM UTC-6, vlovich wrote:
>
>
> On Aug 9, 2015, at 3:57 AM, isocp...@denisbider.com <javascript:> wrote:
>
> > If construction order is indeed more appropriate (which I
> > think you are correct on), doesn=E2=80=99t it speak that this is
> > more naturally thought of as a destructive move constructor?
>
> Yes, I think you're very right!
>
> I have updated the proposal with an annex that presents an alternate=20
> constructor-like syntax, and discusses the merits and demerits of the two=
=20
> approaches:
>
> http://denisbider.com/Relocator.pdf
>
> It seems to me that the constructor-like approach may in fact be superior=
;=20
> no more complex, yet more intuitive; and potentially more extensible, if=
=20
> needed.
>
> If folks like this, I'm leaning to promote constructor-like syntax from=
=20
> the annex, and place it in the center of the proposal.
>
>
> > distinction between the multiple & single relocators?
>
> Yes - it's just a formal distinction to emphasize cost-less optimization=
=20
> of the single-object case. I have added to the text to make this clearer.
>
> I misread the part where it says these can only be generated by the=20
> compiler so I thought people would have to write them some times. From t=
he=20
> call-site, distinguishing the one/many case makes things more legible.
>
> > The static keyword preceding the function A::~A
> > seems out-of-place no?
>
> It is illegal in the definition, yes. It's okay in the declaration.
>
> I have changed the definition to put "static" into C-style comments. I'm=
=20
> still keeping it, to make it clear that the wrappers are invoked as stati=
c=20
> members.
>
> Yup. I was just thrown by the static keyword on the definition.
>
>
> > it sounds like this is trying to solve the memcpy problem
> > but it seems like it solves both that & realloc, no?
>
> To properly solve the realloc problem, it would be necessary to have the=
=20
> equivalent of realloc_in_place.
>
> If realloc_in_place or equivalent fails:
>
> - The equivalent of malloc needs to be used to allocate new memory, while=
=20
> keeping old memory.
>
> - The static relocator needs to be called to move objects from old=20
> location to new. This could be as trivial as memcpy, or may require fix-u=
ps.
>
> - The old memory is freed.
>
> In the absence of realloc_in_place; and for trivially relocatable objects=
=20
> only; it would work for a container to call realloc, also.
>
> To permit use with realloc with non-trivially relocatable objects, the=20
> relocator would have to:
>
> - use constructor-like syntax (the old location is gone when it is called=
);
>
> - accept a ptrdiff_t instead of reference to the old location.
>
> The ptrdiff_t would be the offset between the old location and the new=20
> one, and would allow the relocator to perform any patch-ups.=20
>
> The drawback of this approach is that, if you have a small object; e.g.=
=20
> libc++ std::string, which is just one pointer in size; and this object=20
> requires a patch-up during relocation; it's twice as costly to execute=20
> realloc + patch-up, than to execute a relocator that performs the copy as=
=20
> part of its process.
>
> Probably off-topic, but can you expand on this point? Why 2x? For=20
> instance, realloc frequently will have a ptrdiff of 0 which can be=20
> optimized out, no? Especially for larger regions of memory where all the=
=20
> OS needs to do is tack on an extra VM page which is when you'd get the mo=
st=20
> benefit from realloc. Even if there is an offset, surely realloc + patch=
=20
> up can't be more costly than malloc+memcpy + relocate since patch=20
> necessarily is a simpler operation and you avoid a memcpy (or worse if yo=
u=20
> have non-trivial relocation).
>
> That being said, I'm not sure you could even do the patch-up for somethin=
g=20
> that contains a self-reference without invoking undefined behavior...
>
> Basically, the lack of a realloc_in_place or equivalent is the=20
> deficiency. A feature such as relocation should not be designed around a=
=20
> library deficiency that should relatively trivial to solve.
>
> Well, as you point out, realloc requires the object to patch itself which=
=20
> can't be done as a library-level feature, can it? I guess it could have =
a=20
> non-special function that the library calls to "fixup" an object but that=
=20
> feels dangerous. Anyway, if realloc is a different problem, does it make=
=20
> sense to put in clarifying wording about what specific problem this is=20
> trying to solve and perhaps mention the story about realloc more clearly?=
=20
> I'm obviously late to the discussion, am missing context and haven't=20
> reread it in a few days, so if you feel that's already covered in the=20
> proposal, feel free to ignore.
>
> > does "user-declared=E2=80=9D also cover declarations that are "=3D defa=
ult=E2=80=9D?
>
> Yes, it does. For example, if you have this:
>
> struct B {
> B(B const&) { ... }
> B(B&&) { ... }
> };
>
> struct A : B {
> A(A const&) =3D default;
> };
>
> The user declaration of A(A const&) - even as default - blocks an implici=
t=20
> declaration of a move constructor for A. To get an implicitly defined mov=
e=20
> constructor, one must use either this:
>
> struct A : B {
> };
>
> or this:
>
> struct A : B {
> A(A const&) =3D default;
> A(A&&) =3D default;
> };
>
>
> On Saturday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:
>
>> I like many things about this proposal & thank you for trying to tackle=
=20
>> this. Apologies if already covered, but can you clarify why there is a=
=20
>> distinction between the multiple & single relocators? Am I correct in=
=20
>> guessing that it=E2=80=99s to try & avoid the loop overhead when you onl=
y have a=20
>> single object? Some other reason?
>>
>> The =E2=80=9Ccomposition=E2=80=9D section seems to read kind of contradi=
ctory to the=20
>> terminology being used to frame the solution. If construction order is=
=20
>> indeed more appropriate (which I think you are correct on), doesn=E2=80=
=99t it=20
>> speak that this is more naturally thought of as a destructive move=20
>> constructor? Beyond just semantics, I think users writing their own may=
=20
>> easily get confused about which order they need to destroy/construct & b=
ugs=20
>> in this area will be very subtle, hard-to-find & particularly nasty.
>>
>> nitpicks:
>>
>> The static keyword preceding the function A::~A seems out-of-place no? =
I=20
>> could be mistaken, but the static keyword is illegal in this context & c=
an=20
>> only be there on free-standing functions or on functions as part of the=
=20
>> class declaration; it cannot be used for external class function=20
>> definition. Is the static keyword in this place new to this proposal or=
=20
>> C++17?
>>
>> While discussion relocation, there is what amounts to a footnote=20
>> mentioning realloc. Is it correct that this is the language proposal th=
at=20
>> would complement any eventual library features that would enable the use=
of=20
>> realloc within containers? I think that could do with some clarificatio=
n=20
>> to properly frame the discussion; it sounds like this is trying to solve=
=20
>> the memcpy problem but it seems like it solves both that & realloc, no?
>>
>> I=E2=80=99m not very familiar with the standardese terminology, so apolo=
gies for=20
>> the silly question, but In the "Implicit relocator=E2=80=9D section, doe=
s=20
>> "user-declared=E2=80=9D also cover declarations that are "=3D default=E2=
=80=9D?
>>
>> Thanks,
>> Vitali
>>
>>
>> On Aug 8, 2015, at 1:37 AM, isocp...@denisbider.com wrote:
>>
>> I have published an updated draft:
>>
>> http://www.denisbider.com/Relocator.pdf
>>
>> I have consistently renamed move destructor -> relocator and move=20
>> destruction -> relocation. Reason is explained in a new section,=20
>> Rationales, on last page.
>>
>>
>> Comments:
>>
>> > Might want to explain "destructive move"
>> > in the opening paragraph.=20
>>
>> Very good, done.
>>
>>
>> > - Might want to mention std::unique_ptr?
>> > This is a really simple example of a class that is
>> > trivially relocatable but has an "interesting" move=20
>> > constructor and "interesting" destructor.=20
>>
>> I've spent a fair amount of time thinking about this, but I cannot think=
=20
>> of a container scenario involving unique_ptr that's worse than string.=
=20
>> unique_ptr already has nothrow move construction; and has nothrow=20
>> destruction as long as the object has nothrow destruction; and in any ca=
se,=20
>> it will not throw after a move. I'm having some trouble conjuring a=20
>> situation where the lack of relocation for unique_ptr does not result in=
=20
>> strictly a performance penalty for having to execute a non-trivial=20
>> destructor.
>>
>> Did you have a specific scenario involving unique_ptr in mind?
>>
>>
>> > In the defaulted example, s.b. ~int(int&).
>>
>> Good point, done that.
>>
>>
>> > explain elsewhere when a cting-dtor is trivial
>>
>> Edited text where trait types are defined in an attempt to better explai=
n=20
>> this.
>>
>>
>> > The multiple object helper should work
>> > on overlapping memory.
>>
>> It should indeed. :) Fixed!
>>
>>
>> > Should(n't) the cting-dtor be implicit-default if the
>> > class has a) a *default* move ctor *or copy ctor*,
>> > *and* b) a default dtor, whether or not such are declared?
>>
>> Hmm. I wouldn't necessarily mind, but current rules for move constructor=
=20
>> wouldn't implicitly declare one if a copy constructor or destructor, or=
=20
>> any other special member, is user-declared. The way I read 12.8, para 9,=
=20
>> the following:
>>
>> struct A {
>> A(A const&) =3D default;
>> };
>>
>> would result in a move constructor NOT being implicitly declared.
>>
>> As far as I can test right now, this is the case. If A inherits from B,=
=20
>> which implements both move and copy construction, I can observe that try=
ing=20
>> to move A actually results in copy construction of B. I need add:
>>
>> struct A : B {
>> A(A const&) =3D default;
>> A(A&&) =3D default;
>> };
>>
>> ... in order for B(B&&) to be called.
>>
>> For consistency as well as safety, it would make sense to me to use the=
=20
>> same rules for the relocator.
>>
>>
>> > I feel fairly strongly that there should be a cutoff point
>> > for which we can use the same syntax to relocate
>> > objects that can't be simply relocated.
>>
>> I agree, but I think it should be at a level above this. I have added a=
=20
>> discussion in the Rationales section.
>>
>>
>> > I'm not entirely confident that the composition case is
>> > solved. As worded, the class members are relocated
>> > after the base class has been destroyed
>>
>> The relocator performs the tasks of both a constructor and a destructor,=
=20
>> so one of the two orders have to be chosen. I have added a section for t=
his=20
>> in the Rationales section.
>>
>> I hope also that calling the special member a "relocator"; expressing it=
s=20
>> duality and impartiality, rather than a bias toward construction or=20
>> destruction; might also help alleviate this concern.
>>
>>
>>
>> On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matthew Woehlke wrote:
>>
>>> On 2015-08-07 16:47, isocp...@denisbider.com wrote:=20
>>> > I believe the destructive move Jesus is upon us!=20
>>> >=20
>>> > I have uploaded the following draft:=20
>>> >=20
>>> > http://www.denisbider.com/MoveDestructor.pdf=20
>>>
>>> Editorial comments:=20
>>>
>>> - Might want to explain "destructive move" in the opening paragraph.=20
>>>
>>> - Might want to mention std::unique_ptr? This is a really simple exampl=
e=20
>>> of a class that is trivially relocatable but has an "interesting" move=
=20
>>> constructor and "interesting" destructor.=20
>>>
>>>
>>> Nits:=20
>>>
>>> - In the defaulted example, s.b. ~int(int&). That is, define the defaul=
t=20
>>> behavior as cting-dtor for ALL members, and explain elsewhere when a=20
>>> cting-dtor is trivial (i.e. for POD types; the "consists of trivially=
=20
>>> relocatable members" case seems sufficiently covered) and that trivial=
=20
>>> means to just copy the bits. (Also, it's expected that the compiler wil=
l=20
>>> combine trivial cting-dtors of adjacent members into a single memcpy.)=
=20
>>> At least, I'd do that... seems cleaner. (Shouldn't actually change=20
>>> anything.)=20
>>>
>>>
>>> Not-so-nits:=20
>>>
>>> - The multiple object helper should work on overlapping memory. I=20
>>> imagine you intended this, but I don't see any wording to that effect;=
=20
>>> it seems to me that such wording may be important.=20
>>>
>>> - Should(n't) the cting-dtor be implicit-default if the class has a) a=
=20
>>> *default* move ctor *or copy ctor*, *and* b) a default dtor, whether or=
=20
>>> not such are declared?=20
>>>
>>> - I feel fairly strongly that there should be a cutoff point for which=
=20
>>> we can use the same syntax to relocate objects that can't be simply=20
>>> relocated. I proposed that there is *always* a cting-dtor (except for=
=20
>>> objects that explicitly delete it, or can't be copied/moved and/or=20
>>> destroyed at all, i.e. the fallback implementation would be ill-formed)=
,=20
>>> but at any rate, I think the helpers should work regardless.=20
>>>
>>> - I'm not entirely confident that the composition case is solved. As=20
>>> worded, the class members are relocated after the base class has been=
=20
>>> destroyed (moveover, the derived class itself is technically "destroyed=
"=20
>>> after the base class has been destroyed), which seems like it could=20
>>> present problems... :-( Unfortunately I don't have any suggestions here=
..=20
>>> I do hope that this won't kill the proposal though.=20
>>>
>>>
>>> Comments:=20
>>>
>>> - It took me a minute or two to understand the invocation helpers, but=
=20
>>> now that I do, I like! IIUC what these mean is that instead of librarie=
s=20
>>> having to check a type trait and write a memmove themselves, the=20
>>> compiler will do so. Cool!=20
>>>
>>>
>>> Bikesheds (JFTR):=20
>>>
>>> - ~A(A&) vs. ~A(A*) vs. ~A(void*).=20
>>>
>>> - "cting-dtor" vs. "move-dtor" ;-).=20
>>>
>>> - Type trait names.=20
>>>
>>>
>>> Thanks for sticking with this!=20
>>>
>>> --=20
>>> Matthew=20
>>>
>>>
>> --=20
>>
>> ---=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>> Visit this group at=20
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>>
>> --=20
>
> ---=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at=20
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_4930_1722970052.1439239321070
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>With regard to realloc - it boils down to that the fo=
llowing combination:</div><div><br></div><div>(1)</div><div><div>- copying =
relocator with signature >>T(T&)</div>-=C2=A0logic: if (!realloc_=
in_place)=C2=A0{ malloc, copying_relocator, free=C2=A0}</div><div><br></div=
><div>is strictly at least as efficient, or more efficient than:</div><div>=
<br></div><div>(2)</div><div>- patching relocator with signature >>T(=
ptrdiff_t)</div><div><div>- logic: if (realloc(p) !=3D p) {=C2=A0patching_r=
elocator }</div><div><br></div></div><div>under the reasonable assumption t=
hat realloc_in_place is a strict subset of realloc, like this:</div><div><b=
r></div><div>realloc =3D if (!realloc_in_place) { malloc, memcpy, free }</d=
iv><div><br></div><div>The reason is that the first strategy boils down to:=
</div><div><br></div><div>if (!realloc_in_place)=C2=A0{ malloc, copying_rel=
ocator, free=C2=A0}</div><div><br></div><div>Whereas the second strategy bo=
ils down to:</div><div><br></div><div>if (!realloc_in_place) { malloc, memc=
py, free, patching_relocator=C2=A0}</div><div><br></div><div>You seem to be=
assuming that we have realloc, but we don't have realloc_in_place.</di=
v><div><br></div><div>However, it seems reasonable to me that if we can add=
support for relocation, we can also add the equivalent of realloc_in_place=
..</div><div><br></div><div>And if we do=C2=A0add relocation, but do not add=
=C2=A0an equivalent of realloc_in_place=C2=A0-=C2=A0which would be kinda sa=
d, but okay=C2=A0-=C2=A0we can nevertheless use platform-specific functiona=
lity that provides the equivalent of realloc_in_place.</div><div><br></div>=
<div>For example, on Windows, I have:</div><div><br></div><div><p><font fac=
e=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></fon=
t><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000=
ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" =
size=3D"2">template</font></font></font><font face=3D"Consolas" size=3D"2">=
<font face=3D"Consolas" size=3D"2"> <</font></font><font color=3D"#0000f=
f" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" s=
ize=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">class</font>=
</font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" si=
ze=3D"2"> </font></font><font color=3D"#2b91af" face=3D"Consolas" size=3D"2=
"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91=
af" face=3D"Consolas" size=3D"2">T</font></font></font><font face=3D"Consol=
as" size=3D"2"><font face=3D"Consolas" size=3D"2">></font></font></p><p>=
<font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff=
" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" si=
ze=3D"2">bool</font></font></font><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2"> ReAllocInPlace (</font></font><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Conso=
las" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</fon=
t></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" =
size=3D"2">* </font></font><font color=3D"#808080" face=3D"Consolas" size=
=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"=
#808080" face=3D"Consolas" size=3D"2">p</font></font></font><font face=3D"C=
onsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></font><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2">size_t</font></font></font><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#808080" face=3D=
"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">=
<font color=3D"#808080" face=3D"Consolas" size=3D"2">n</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">) </f=
ont></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=
=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2">noexcept</font></font></font></p><p><font face=3D"Conso=
las" size=3D"2"><font face=3D"Consolas" size=3D"2">=C2=A0=C2=A0 { </font></=
font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0=
000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consola=
s" size=3D"2">return</font></font></font><font face=3D"Consolas" size=3D"2"=
><font face=3D"Consolas" size=3D"2"> HeapReAlloc(s_processHeap, </font></fo=
nt><font color=3D"#6f008a" face=3D"Consolas" size=3D"2"><font color=3D"#6f0=
08a" face=3D"Consolas" size=3D"2"><font color=3D"#6f008a" face=3D"Consolas"=
size=3D"2">HEAP_REALLOC_IN_PLACE_ONLY</font></font></font><font face=3D"Co=
nsolas" size=3D"2"><font face=3D"Consolas" size=3D"2">, </font></font><font=
color=3D"#808080" face=3D"Consolas" size=3D"2"><font color=3D"#808080" fac=
e=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D=
"2">p</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D"=
Consolas" size=3D"2">, </font></font><font color=3D"#808080" face=3D"Consol=
as" size=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#808080" face=3D"Consolas" size=3D"2">n</font></font></font><font f=
ace=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">*</font></fo=
nt><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#000=
0ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas"=
size=3D"2">sizeof</font></font></font><font face=3D"Consolas" size=3D"2"><=
font face=3D"Consolas" size=3D"2">(</font></font><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font>=
</font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2=
">)) !=3D </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2=
"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000=
ff" face=3D"Consolas" size=3D"2">nullptr</font></font></font><font face=3D"=
Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">; }</font></font></=
p></div><div><br></div><div><br>On Monday, August 10, 2015 at 1:52:32 PM UT=
C-6, vlovich wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204=
); border-left-width: 1px; border-left-style: solid;"><div dir=3D"auto"><di=
v><span></span></div><div><div></div><div><br></div><div><br>On Aug 9, 2015=
, at 3:57 AM, <a onmousedown=3D"this.href=3D'javascript:';return tr=
ue;" onclick=3D"this.href=3D'javascript:';return true;" href=3D"jav=
ascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"4_cQX=
1OBAQAJ">isocp...@denisbider.com</a> wrote:<br><br></div><blockquote type=
=3D"cite"><div><div dir=3D"ltr"><div>> If construction order is indeed m=
ore appropriate (which I<br>> think you are correct on), doesn=E2=80=99t=
it speak that this is<br>> more naturally thought of as a destructive m=
ove constructor?</div><div><br></div><div>Yes,=C2=A0I think you're=C2=
=A0very right!</div><div><br></div><div>I have updated the proposal with an=
annex that presents an alternate constructor-like syntax, and discusses th=
e merits and demerits of the two approaches:</div><div><br></div><div><a on=
mousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fde=
nisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGRaVpviwtOS=
XhpXtDNRASkBLXVYw';return true;" onclick=3D"this.href=3D'http://www=
..google.com/url?q\75http%3A%2F%2Fdenisbider.com%2FRelocator.pdf\46sa\75D\46=
sntz\0751\46usg\75AFQjCNGRaVpviwtOSXhpXtDNRASkBLXVYw';return true;" hre=
f=3D"http://denisbider.com/Relocator.pdf" target=3D"_blank" rel=3D"nofollow=
">http://denisbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><div=
>It seems to me that the constructor-like approach may in fact be superior;=
no more complex,=C2=A0yet more intuitive; and potentially more extensible,=
if needed.</div><div><br></div><div>If folks like this, I'm leaning to=
=C2=A0promote constructor-like syntax=C2=A0from the annex, and=C2=A0place i=
t in the center of the proposal.</div><div><br></div><div><br></div><div>&g=
t; distinction between the multiple & single relocators?</div><div><br>=
</div><div>Yes - it's just a formal distinction to=C2=A0emphasize cost-=
less optimization of the single-object case. I have added=C2=A0to the text=
=C2=A0to make this clearer.</div></div></div></blockquote><div>I misread th=
e part where it says these can only be generated by the compiler so I thoug=
ht people would have to write them some times. =C2=A0From the call-site, di=
stinguishing the one/many case makes things more legible.</div><br><blockqu=
ote type=3D"cite"><div><div dir=3D"ltr"><div>> The static keyword preced=
ing the function=C2=A0A::~A</div><div>> seems out-of-place no?</div><div=
><br></div><div>It is illegal in the definition, yes. It's okay in the =
declaration.</div></div></div></blockquote><blockquote type=3D"cite"><div d=
ir=3D"ltr"><div>I have changed the definition to put "static" int=
o C-style comments. I'm still keeping it, to=C2=A0make it clear that th=
e wrappers are=C2=A0invoked as static members.</div></div></blockquote>Yup.=
=C2=A0I was just thrown by the static keyword on the definition.<br><block=
quote type=3D"cite"><div><div dir=3D"ltr"><div><br></div><div>> it sound=
s like this is trying to solve the memcpy problem</div><div>> but it see=
ms like it solves both that & realloc, no?</div><div><br></div><div>To =
properly solve the <font face=3D"courier new,monospace">realloc</font> prob=
lem, it would be necessary to have=C2=A0the equivalent of=C2=A0<font face=
=3D"courier new,monospace">realloc_in_place</font>.</div><div><br></div><di=
v>If <font face=3D"courier new,monospace">realloc_in_place</font> or equiva=
lent fails:</div><div><br></div><div>- The equivalent of malloc needs to be=
used to allocate new memory, while keeping old memory.</div><div><br></div=
><div>- The static relocator needs to be called to move objects from old lo=
cation to new. This could be as trivial as memcpy, or may require fix-ups.<=
/div><div><br></div><div>- The old memory is freed.</div><div><br></div><di=
v>In the absence of <font face=3D"courier new,monospace">realloc_in_place</=
font>; and for trivially relocatable objects only; it would work for a cont=
ainer to call <font face=3D"courier new,monospace">realloc</font>, also.</d=
iv><div><br></div><div>To permit use with <font face=3D"courier new,monospa=
ce">realloc</font> with=C2=A0non-trivially relocatable=C2=A0objects, the re=
locator would have to:</div><div><br></div><div>- use constructor-like synt=
ax (the old location is gone when it is called);</div><div><br></div><div>-=
accept a <font face=3D"courier new,monospace">ptrdiff_t</font> instead of =
reference to the old location.</div><div><br></div><div>The <font face=3D"c=
ourier new,monospace">ptrdiff_t</font> would be the offset between the old =
location and the new one, and would allow the relocator to=C2=A0perform any=
patch-ups.=C2=A0</div><div><br></div><div>The drawback of this approach is=
that, if you have a small object; e.g. libc++ std::string, which is just=
=C2=A0one pointer=C2=A0in size; and this object requires a patch-up during =
relocation; it's twice as costly to execute realloc + patch-up, than to=
execute a relocator that performs the copy as part of its process.</div></=
div></div></blockquote><div>Probably off-topic, but can you expand on this =
point? =C2=A0Why 2x? =C2=A0For instance, realloc frequently will have a ptr=
diff of 0 which can be optimized out, no? =C2=A0Especially for larger regio=
ns of memory where all the OS needs to do is tack on an extra VM page which=
is when you'd get the most benefit from realloc. =C2=A0Even if there i=
s an offset, surely realloc + patch up can't be more costly than malloc=
+memcpy + relocate since patch necessarily is a simpler operation and you a=
void a memcpy (or worse if you have non-trivial relocation).</div><div><br>=
</div><div>That being said, I'm not sure you could even do the patch-up=
for something that contains a self-reference without invoking undefined be=
havior...</div><div><br></div><blockquote type=3D"cite"><div><div dir=3D"lt=
r"><div>Basically, the lack of a <font face=3D"courier new,monospace">reall=
oc_in_place</font> or equivalent is the deficiency.=C2=A0A feature such as =
relocation should not be designed around a library deficiency that should=
=C2=A0relatively trivial to solve.</div></div></div></blockquote><div>Well,=
as you point out, realloc requires the object to patch itself which can=
9;t be done as a library-level feature, can it? =C2=A0I guess it could have=
a non-special function that the library calls to "fixup" an obje=
ct but that feels dangerous. =C2=A0Anyway, if realloc is a different proble=
m, does it make sense to put in clarifying wording about what specific prob=
lem this is trying to solve and perhaps mention the story about realloc mor=
e clearly? =C2=A0I'm obviously late to the discussion, am missing conte=
xt and haven't reread it in a few days, so if you feel that's alrea=
dy covered in the proposal, feel free to ignore.</div><br><blockquote type=
=3D"cite"><div><div dir=3D"ltr"><div>> does "user-declared=E2=80=9D=
also cover declarations that are "=3D default=E2=80=9D?</div><div><br=
></div><div>Yes, it does. For example, if you have this:</div><div><br></di=
v><div><font face=3D"courier new,monospace">=C2=A0 struct B {</font></div><=
div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 B(B const&) { ..=
.. }</font></div><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 B(B=
&&) { ... }</font></div><div><font face=3D"courier new,monospace">=
=C2=A0 };</font></div><div><font face=3D"courier new,monospace"><br></font>=
</div><div><font face=3D"courier new,monospace">=C2=A0 struct A : B {</font=
></div><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 A(A const&am=
p;) =3D default;</font></div><div><font face=3D"courier new,monospace">=C2=
=A0 };</font></div><div><br></div><div>The user declaration of A(A const&am=
p;) -=C2=A0even as default -=C2=A0blocks an implicit declaration of a=C2=A0=
move constructor for A. To get an implicitly defined move constructor, one =
must use either this:</div><div><br></div><div><font face=3D"courier new,mo=
nospace">=C2=A0 struct A : B {</font></div><div><font face=3D"courier new,m=
onospace">=C2=A0 };</font></div><div><br></div><div>or this:</div><div><br>=
</div><div><div><font face=3D"courier new,monospace">=C2=A0 struct A : B {<=
/font></div><div><div><font face=3D"courier new,monospace">=C2=A0 =C2=A0 A(=
A const&) =3D default;</font></div><div><font face=3D"courier new,monos=
pace">=C2=A0=C2=A0 =C2=A0A(A&&) =3D default;</font></div><font face=
=3D"courier new,monospace">=C2=A0 };</font></div></div><div><br><br>On Satu=
rday, August 8, 2015 at 4:27:16 PM UTC-6, vlovich wrote:</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex;=
border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left=
-style: solid;"><div>I like many things about this proposal & thank you=
for trying to tackle this. =C2=A0Apologies if already covered, but can you=
clarify why there is a distinction between the multiple & single reloc=
ators? =C2=A0Am I correct in guessing that it=E2=80=99s to try & avoid =
the loop overhead when you only have a single object? =C2=A0Some other reas=
on?<div><br></div><div>The =E2=80=9Ccomposition=E2=80=9D section seems to r=
ead kind of contradictory to the terminology being used to frame the soluti=
on. =C2=A0If construction order is indeed more appropriate (which I think y=
ou are correct on), doesn=E2=80=99t it speak that this is more naturally th=
ought of as a destructive move constructor? =C2=A0Beyond just semantics, I =
think users writing their own may easily get confused about which order the=
y need to destroy/construct & bugs in this area will be very subtle, ha=
rd-to-find & particularly nasty.</div><div><br></div><div>nitpicks:</di=
v><div><br></div><div>The static keyword preceding the function=C2=A0A::~A =
seems out-of-place no? =C2=A0I could be mistaken, but the static keyword is=
illegal in this context & can only be there on free-standing functions=
or on functions as part of the class declaration; it cannot be used for ex=
ternal class function definition. =C2=A0Is the static keyword in this place=
new to this proposal or C++17?</div><div><br></div><div><div>While discuss=
ion relocation, there is what amounts to a footnote mentioning realloc. =C2=
=A0Is it correct that this is the language proposal that would complement a=
ny eventual library features that would enable the use of realloc within co=
ntainers? =C2=A0I think that could do with some clarification to properly f=
rame the discussion; it sounds like this is trying to solve the memcpy prob=
lem but it seems like it solves both that & realloc, no?</div><div><br>=
</div></div><div>I=E2=80=99m not very familiar with the standardese termino=
logy, so apologies for the silly question, but In the "Implicit reloca=
tor=E2=80=9D section, does "user-declared=E2=80=9D also cover declarat=
ions that are "=3D default=E2=80=9D?</div><div><br></div><div>Thanks,<=
/div><div>Vitali</div><div><br></div><div><br><div><div><blockquote type=3D=
"cite"><div>On Aug 8, 2015, at 1:37 AM, <a rel=3D"nofollow">isocp...@denisb=
ider.com</a> wrote:</div><br><div><div dir=3D"ltr"><div>I have published an=
updated draft:</div><div><br></div><div><a onmousedown=3D"this.href=3D'=
;http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FRelocator.=
pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQ=
jCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;" href=3D"http://www.denis=
bider.com/Relocator.pdf" target=3D"_blank" rel=3D"nofollow">http://www.deni=
sbider.com/<wbr>Relocator.pdf</a><br></div><div><br></div><div>I have consi=
stently renamed move destructor -> relocator and move destruction -> =
relocation.=C2=A0Reason is=C2=A0explained in a new section, Rationales, on =
last page.</div><div><br></div><div><br></div><div>Comments:</div><div><br>=
</div><div>> Might want to explain "destructive move"</div><di=
v>> in the opening paragraph. </div><div><br></div><div>Very good, done.=
</div><div><br></div><div><br></div><div>> - Might want to mention std::=
unique_ptr?</div><div>> This is a really simple example=C2=A0 of a class=
that is</div><div>> trivially relocatable but has an "interesting&=
quot; move <br>> constructor and "interesting" destructor. <br=
></div><div><br></div><div>I've spent a fair amount of time thinking ab=
out this, but I cannot think of a container scenario involving unique_ptr t=
hat's worse than string. unique_ptr already has nothrow move constructi=
on; and has nothrow destruction as long as the object has nothrow destructi=
on; and in any case, it=C2=A0will not throw after a move. I'm having so=
me trouble conjuring a situation where the lack of relocation for unique_pt=
r does not result in strictly a performance penalty for having to execute a=
non-trivial destructor.</div><div><br>Did you have a specific scenario inv=
olving unique_ptr in mind?</div><div><br></div><div><br></div><div>> In =
the defaulted example, s.b. ~int(int&).</div><div><br></div><div>Good p=
oint, done that.<br></div><div><br></div><div><br></div><div>> explain e=
lsewhere when a cting-dtor is trivial</div><div><br></div><div>Edited text =
where trait types are defined in an attempt to better explain this.</div><d=
iv><br></div><div><br></div><div>> The multiple object helper should wor=
k</div><div>> on overlapping memory.</div><div><br></div><div>It should =
indeed. :) Fixed!</div><div><br></div><div><br></div><div>> Should(n'=
;t) the cting-dtor be implicit-default if the</div><div>> class has a) a=
=C2=A0*default* move ctor *or copy ctor*,</div><div>> *and* b) a default=
dtor, whether or=C2=A0not such are declared?</div><div><br></div><div>Hmm.=
I wouldn't necessarily mind, but current rules for move constructor wo=
uldn't implicitly declare one if a copy constructor or destructor, or a=
ny=C2=A0other special member, is user-declared.=C2=A0The way I read 12.8, p=
ara 9, the following:</div><div><br></div><div><font face=3D"courier new,mo=
nospace">struct A {</font></div><div><font face=3D"courier new,monospace">=
=C2=A0 A(A const&) =3D default;</font></div><div><font face=3D"courier =
new,monospace">};</font></div><div><br></div><div>would result in a move co=
nstructor NOT being implicitly declared.</div><div><br></div><div>As far as=
I can test right now, this is the case. If A inherits from B, which implem=
ents=C2=A0both move=C2=A0and copy construction,=C2=A0I can observe that try=
ing to move A actually results in copy construction of B. I need add:</div>=
<div><br></div><div><div><font face=3D"courier new,monospace">struct A : B=
=C2=A0{</font></div><div><div><font face=3D"courier new,monospace">=C2=A0 A=
(A const&) =3D default;</font></div><font face=3D"courier new,monospace=
">=C2=A0 A(A&&) =3D default;</font></div><div><font face=3D"courier=
new,monospace">};</font></div><div><br></div><div>... in order for B(B&=
;&) to be called.</div><div><br></div><div>For consistency as well as s=
afety, it would make sense to me to use the same rules for the relocator.</=
div><div><br></div><div><br></div><div>> I feel fairly strongly that the=
re should be a cutoff point</div><div>> for which we can use the same sy=
ntax to relocate</div><div>> objects that can't be simply relocated.=
</div><div><br></div><div>I agree, but I think it should be at a level abov=
e this. I have added a discussion in the Rationales section.</div><div><br>=
</div><div><br></div><div>> I'm not entirely confident that the comp=
osition case is</div><div>> solved. As worded, the class members are rel=
ocated</div><div>> after the base class has been destroyed</div><div><br=
></div><div>The relocator performs the tasks of both a constructor and a de=
structor, so one of the two orders have to be chosen. I have added a sectio=
n for this in the Rationales section.</div><div><br></div><div>I hope also =
that calling the special member a "relocator"; expressing its dua=
lity and impartiality, rather than a bias toward construction or destructio=
n;=C2=A0might also help alleviate this concern.</div><div><br></div><div><b=
r></div></div><div><br>On Friday, August 7, 2015 at 3:32:51 PM UTC-6, Matth=
ew Woehlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204);=
border-left-width: 1px; border-left-style: solid;">On 2015-08-07 16:47, <a=
rel=3D"nofollow">isocp...@denisbider.com</a> wrote:
<br>> I believe the destructive move Jesus is upon us!
<br>>=20
<br>> =C2=A0I have uploaded the following draft:
<br>>=20
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46=
usg\75AFQjCNEmOr4KskLTP7oqtb3GQp9_QLlboQ';return true;" onclick=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%=
2FMoveDestructor.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNEmOr4KskLTP7oqtb3GQ=
p9_QLlboQ';return true;" href=3D"http://www.denisbider.com/MoveDestruct=
or.pdf" target=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>M=
oveDestructor.pdf</a>
<br>
<br>Editorial comments:
<br>
<br>- Might want to explain "destructive move" in the opening par=
agraph.
<br>
<br>- Might want to mention std::unique_ptr? This is a really simple exampl=
e
<br>of a class that is trivially relocatable but has an "interesting&q=
uot; move
<br>constructor and "interesting" destructor.
<br>
<br>
<br>Nits:
<br>
<br>- In the defaulted example, s.b. ~int(int&). That is, define the de=
fault
<br>behavior as cting-dtor for ALL members, and explain elsewhere when a
<br>cting-dtor is trivial (i.e. for POD types; the "consists of trivia=
lly
<br>relocatable members" case seems sufficiently covered) and that tri=
vial
<br>means to just copy the bits. (Also, it's expected that the compiler=
will
<br>combine trivial cting-dtors of adjacent members into a single memcpy.)
<br>At least, I'd do that... seems cleaner. (Shouldn't actually cha=
nge
<br>anything.)
<br>
<br>
<br>Not-so-nits:
<br>
<br>- The multiple object helper should work on overlapping memory. I
<br>imagine you intended this, but I don't see any wording to that effe=
ct;
<br>it seems to me that such wording may be important.
<br>
<br>- Should(n't) the cting-dtor be implicit-default if the class has a=
) a
<br>*default* move ctor *or copy ctor*, *and* b) a default dtor, whether or
<br>not such are declared?
<br>
<br>- I feel fairly strongly that there should be a cutoff point for which
<br>we can use the same syntax to relocate objects that can't be simply
<br>relocated. I proposed that there is *always* a cting-dtor (except for
<br>objects that explicitly delete it, or can't be copied/moved and/or
<br>destroyed at all, i.e. the fallback implementation would be ill-formed)=
,
<br>but at any rate, I think the helpers should work regardless.
<br>
<br>- I'm not entirely confident that the composition case is solved. A=
s
<br>worded, the class members are relocated after the base class has been
<br>destroyed (moveover, the derived class itself is technically "dest=
royed"
<br>after the base class has been destroyed), which seems like it could
<br>present problems... :-( Unfortunately I don't have any suggestions =
here.
<br>I do hope that this won't kill the proposal though.
<br>
<br>
<br>Comments:
<br>
<br>- It took me a minute or two to understand the invocation helpers, but
<br>now that I do, I like! IIUC what these mean is that instead of librarie=
s
<br>having to check a type trait and write a memmove themselves, the
<br>compiler will do so. Cool!
<br>
<br>
<br>Bikesheds (JFTR):
<br>
<br>- ~A(A&) vs. ~A(A*) vs. ~A(void*).
<br>
<br>- "cting-dtor" vs. "move-dtor" ;-).
<br>
<br>- Type trait names.
<br>
<br>
<br>Thanks for sticking with this!
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div><div><br></div>
-- <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 rel=3D"nofollow">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow">std-pr...@isocpp.o=
rg</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google=
..com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.h=
ref=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div><br></div></div></div></blockquote></div>
<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 onmousedown=3D"this.href=3D'javascript:';return true;" o=
nclick=3D"this.href=3D'javascript:';return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"4_cQX1OBAQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"4_cQX1OBAQAJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google=
..com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.h=
ref=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/std-<wbr>proposals/</a>.<br>
</div></blockquote></div></div></blockquote></div>
<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 />
------=_Part_4930_1722970052.1439239321070--
------=_Part_4929_1530091680.1439239321069--
.
Author: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 14:59:07 -0700 (PDT)
Raw View
------=_Part_866_2035194516.1439243947633
Content-Type: multipart/alternative;
boundary="----=_Part_867_988721069.1439243947634"
------=_Part_867_988721069.1439243947634
Content-Type: text/plain; charset=UTF-8
Hmm, good points.
There are definitely situations where you don't want to mem-initialize a
trivial member, such as in the example:
>>A(A& x) : >>B(x), >>c(x.c), >>i(x.i)
{ a = *this*; }
However, one might definitely argue that situations where you want to
mem-initialize a base or a member, but with a non-corresponding member, are
practically nonexistent. So, we may in fact prefer the following:
>>A(A& x) : >>B, >>c, >>i
{ a = *this*; }
The relocate_wrapper you suggest I think looks neat, and should be legal. I
don't see a reason why it wouldn't be legal, if the mem-initializer-list is
not implicit.
It seems to me, intuitively, that there's no reason to make it illegal to
access any data member of the moved-from subobject until the outermost
relocator exits.
I see no obvious reason why virtual methods shouldn't continue to work, as
well. But this is not to say, of course, that one should call them.
In general, anything that's const ought to be safe to call. Which is an
argument in favor of making the signature >>T(T const&) - except that would
prevent zeroing out of members.
On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wrote:
> A few queries:
>
> What exactly are the semantics of the mem-initializer-list, particularly
> with regard to omitted, duplicated or misplaced bases/members:
>
> struct A {
> std::string q, r, s;
> >>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
> };
>
> Is it ever legitimate for a mem-initializer to be omitted or to take any
> form other than >>id(x.id) where the two identifiers are equivalent? If
> so, whose responsibility is it to call the destructor on the corresponding
> member of the source object? If not, would it be better to omit the
> mem-initializer-list entirely, as with destructors?
>
> Within the body of the relocator special member function, what are the
> lifetime statuses of the source and destination objects, particularly with
> regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
> members of the source object, or is this undefined behavior as they are
> destructed? If the type is polymorphic, is it permissible to dynamic_cast
> or invoke virtual functions on the source? Indeed, is it permissible to
> invoke any member functions on the source?
>
> In particular, I'd like to make this utility class legal (noting that
> aligned_storage_t is a POD but my utility class is not):
>
> template<class T>
> struct relocate_wrapper {
> template<class... Args> relocate_wrapper(Args&&... args) {
> new (&buf) T(std::forward<Args>(args)...);
> }
> ~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
> >>relocate_wrapper(relocate_wrapper& rhs) {
> new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
> reinterpret_cast<T&>(rhs.buf).~T();
> }
> std::aligned_storage_t<sizeof(T), alignof(T)> buf;
> };
>
> Hm... it might be nice to ensure that the relocator doesn't do any
> unnecessary work copying the buffer that's just going to be placement new
> moved into. Is that an argument against an implicit mem-initializer-list?
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_867_988721069.1439243947634
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hmm, good points.</div><div><br></div><div>There are =
definitely situations where you don't want to mem-initialize a trivial =
member, such as in the example:</div><div><br></div><div><font color=3D"#00=
0000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";"><span style=
=3D"mso-spacerun: yes;">=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"col=
or: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-=
font-family: "Times New Roman";">>></span><span style=3D"co=
lor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";">A</span><span style=3D"color: rgb(4=
8, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 3=
2); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">A</span><span style=3D"color: rgb(48, 128, 128); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">&</span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Ro=
man";"> x</span><span style=3D"color: rgb(48, 128, 128); font-family: =
Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&q=
uot;;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </=
span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-si=
ze: 10pt; mso-fareast-font-family: "Times New Roman";">:</span><s=
pan style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; =
mso-fareast-font-family: "Times New Roman";"> </span><span style=
=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";">>></span><span styl=
e=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fare=
ast-font-family: "Times New Roman";">B</span><span style=3D"color=
: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fo=
nt-family: "Times New Roman";">(</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family:=
"Times New Roman";">x</span><span style=3D"color: rgb(48, 128, 1=
28); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
;Times New Roman";">)</span><span style=3D"color: rgb(64, 96, 128); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">,</span><span style=3D"color: rgb(0, 0, 32); font-family:=
Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&=
quot;;"> </span><span style=3D"color: rgb(48, 128, 128); font-family: Conso=
las; font-size: 10pt; mso-fareast-font-family: "Times New Roman";=
">>></span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas=
; font-size: 10pt; mso-fareast-font-family: "Times New Roman";">c=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";">(</span=
><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10p=
t; mso-fareast-font-family: "Times New Roman";">x</span><span sty=
le=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">.</span><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-f=
ont-family: "Times New Roman";">c</span><span style=3D"color: rgb=
(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fa=
mily: "Times New Roman";">)</span><span style=3D"color: rgb(64, 9=
6, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &=
quot;Times New Roman";">, </span><span style=3D"color: rgb(48, 128, 12=
8); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">>></span><span style=3D"color: rgb(0, 0, 32);=
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Tim=
es New Roman";">i</span><span style=3D"color: rgb(48, 128, 128); font-=
family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New=
Roman";">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&quo=
t;;">x</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas=
; font-size: 10pt; mso-fareast-font-family: "Times New Roman";">.=
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">i</span><sp=
an style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10p=
t; mso-fareast-font-family: "Times New Roman";">)</span></p><font=
color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";"><span style=
=3D"mso-spacerun: yes;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span =
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">a </span><s=
pan style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10=
pt; mso-fareast-font-family: "Times New Roman";">=3D</span><span =
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-=
fareast-font-family: "Times New Roman";"> </span><b><span style=
=3D"color: rgb(32, 0, 128); font-family: Consolas; font-size: 10pt; mso-far=
east-font-family: "Times New Roman";">this</span></b><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fa=
reast-font-family: "Times New Roman";">; }</span></p><font color=
=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>However, one might definitely argue that s=
ituations where you want to mem-initialize a base or a member, but with a n=
on-corresponding member,=C2=A0are practically nonexistent. So, we may in fa=
ct=C2=A0prefer the following:</div><div><br></div><div><font color=3D"#0000=
00" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";"><span style=
=3D"mso-spacerun: yes;">=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"col=
or: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-=
font-family: "Times New Roman";">>></span><span style=3D"co=
lor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";">A</span><span style=3D"color: rgb(4=
8, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 3=
2); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">A</span><span style=3D"color: rgb(48, 128, 128); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">&</span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Ro=
man";"> x</span><span style=3D"color: rgb(48, 128, 128); font-family: =
Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&q=
uot;;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </=
span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-si=
ze: 10pt; mso-fareast-font-family: "Times New Roman";">:</span><s=
pan style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; =
mso-fareast-font-family: "Times New Roman";"> </span><span style=
=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";">>></span><span styl=
e=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fare=
ast-font-family: "Times New Roman";">B</span><span style=3D"color=
: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";">,</span><span style=3D"color: rgb(0=
, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: =
"Times New Roman";"> </span><span style=3D"color: rgb(48, 128, 12=
8); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">>></span><span style=3D"color: rgb(0, 0, 32);=
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Tim=
es New Roman";">c</span><span style=3D"color: rgb(64, 96, 128); font-f=
amily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New =
Roman";">, </span><span style=3D"color: rgb(48, 128, 128); font-family=
: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman=
";">>></span><span style=3D"color: rgb(0, 0, 32); font-family: C=
onsolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&qu=
ot;;">i</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"=
3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";"><span style=
=3D"mso-spacerun: yes;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span =
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">a </span><s=
pan style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10=
pt; mso-fareast-font-family: "Times New Roman";">=3D</span><span =
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-=
fareast-font-family: "Times New Roman";"> </span><b><span style=
=3D"color: rgb(32, 0, 128); font-family: Consolas; font-size: 10pt; mso-far=
east-font-family: "Times New Roman";">this</span></b><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fa=
reast-font-family: "Times New Roman";">; }</span></p><font color=
=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>The relocate_wrapper you suggest I think l=
ooks neat, and should be legal. I don't see a reason why it wouldn'=
t be legal, if the mem-initializer-list is not implicit.</div><div><br></di=
v><div>It seems to me,=C2=A0intuitively,=C2=A0that there's no reason to=
make it illegal to access any data member of the moved-from subobject unti=
l the outermost relocator exits.</div><div><br></div><div>I see no obvious =
reason why virtual methods shouldn't continue to work, as well. But thi=
s is not to say, of course, that one should call them.</div><div><br></div>=
<div>In general, anything that's const ought to be safe to call. Which =
is an argument in favor of making the signature >>T(T const&) -=
=C2=A0except that would prevent zeroing out of members.</div><div><br></div=
><div><br>On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>A few queries:<=
/div><div><br></div><div>What exactly are the semantics of the mem-initiali=
zer-list, particularly with regard to omitted, duplicated or misplaced base=
s/members:<br></div><div><br></div><div style=3D"border: 1px solid rgb(187,=
187, 187); border-image: none; -ms-word-wrap: break-word; background-color=
: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0, 136);">st=
ruct</span><span style=3D"color: rgb(0, 0, 0);"> A </span><span style=3D"co=
lor: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=
=C2=A0 =C2=A0 std</span><span style=3D"color: rgb(102, 102, 0);">::</span><=
span style=3D"color: rgb(0, 0, 136);">string</span><span style=3D"color: rg=
b(0, 0, 0);"> q</span><span style=3D"color: rgb(102, 102, 0);">,</span><spa=
n style=3D"color: rgb(0, 0, 0);"> r</span><span style=3D"color: rgb(102, 10=
2, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"> s</span><span style=
=3D"color: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">>><=
/span><span style=3D"color: rgb(0, 0, 0);">A</span><span style=3D"color: rg=
b(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">A</span><span=
style=3D"color: rgb(102, 102, 0);">&</span><span style=3D"color: rgb(0=
, 0, 0);"> x</span><span style=3D"color: rgb(102, 102, 0);">)</span><span s=
tyle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0=
);">:</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"col=
or: rgb(102, 102, 0);">>></span><span style=3D"color: rgb(0, 0, 0);">=
r</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"col=
or: rgb(0, 0, 0);">x</span><span style=3D"color: rgb(102, 102, 0);">.</span=
><span style=3D"color: rgb(0, 0, 0);">r</span><span style=3D"color: rgb(102=
, 102, 0);">),</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">>></span><span style=3D"color: rgb(0,=
0, 0);">s</span><span style=3D"color: rgb(102, 102, 0);">(</span><span sty=
le=3D"color: rgb(0, 0, 0);">x</span><span style=3D"color: rgb(102, 102, 0);=
">.</span><span style=3D"color: rgb(0, 0, 0);">r</span><span style=3D"color=
: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><=
span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0=
, 0, 0);"> </span><span style=3D"color: rgb(136, 0, 0);">/* oops */</span><=
span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, =
102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br></span><span sty=
le=3D"color: rgb(102, 102, 0);">};</span><span style=3D"color: rgb(0, 0, 0)=
;"><br></span></div></code></div><div><br></div><div>Is it ever legitimate =
for a mem-initializer to be omitted or to take any form other than <font fa=
ce=3D"courier new, monospace">>>id(<a onmousedown=3D"this.href=3D'=
;http://www.google.com/url?q\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0751\46usg=
\75AFQjCNG_YifSOWB69ZOU5okYoDl3uhnQkQ';return true;" onclick=3D"this.hr=
ef=3D'http://www.google.com/url?q\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0=
751\46usg\75AFQjCNG_YifSOWB69ZOU5okYoDl3uhnQkQ';return true;" href=3D"h=
ttp://x.id" target=3D"_blank" rel=3D"nofollow">x.id</a>)</font> where the t=
wo identifiers are equivalent? If so, whose responsibility is it to call th=
e destructor on the corresponding member of the source object? If not, woul=
d it be better to omit the mem-initializer-list entirely, as with destructo=
rs?</div><div><br></div><div>Within the body of the relocator special membe=
r function, what are the lifetime statuses of the source and destination ob=
jects, particularly with regard to [class.cdtor]? Is it permissible to form=
lvalues to the bases and members of the source object, or is this undefine=
d behavior as they are destructed? If the type is polymorphic, is it permis=
sible to dynamic_cast or invoke virtual functions on the source? Indeed, is=
it permissible to invoke any member functions on the source?</div><div><br=
></div><div>In particular, I'd like to make this utility class legal (n=
oting that aligned_storage_t is a POD but my utility class is not):</div><d=
iv><br></div><div><div style=3D"border: 1px solid rgb(187, 187, 187); borde=
r-image: none; -ms-word-wrap: break-word; background-color: rgb(250, 250, 2=
50);"><code><div><span style=3D"color: rgb(0, 0, 136);">template</span><spa=
n style=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0=
, 0, 136);">class</span><span style=3D"color: rgb(0, 0, 0);"> T</span><span=
style=3D"color: rgb(102, 102, 0);">></span><span style=3D"color: rgb(0,=
0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136);">struct</span><sp=
an style=3D"color: rgb(0, 0, 0);"> relocate_wrapper </span><span style=3D"c=
olor: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=
=C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">template</span><span s=
tyle=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0=
, 136);">class</span><span style=3D"color: rgb(102, 102, 0);">...</span><sp=
an style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 0,=
102);">Args</span><span style=3D"color: rgb(102, 102, 0);">></span><spa=
n style=3D"color: rgb(0, 0, 0);"> relocate_wrapper</span><span style=3D"col=
or: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102);">Arg=
s</span><span style=3D"color: rgb(102, 102, 0);">&&...</span><span =
style=3D"color: rgb(0, 0, 0);"> args</span><span style=3D"color: rgb(102, 1=
02, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">new</span><=
span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, =
102, 0);">(&</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span=
style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0,=
0);"> T</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=
=3D"color: rgb(0, 0, 0);">std</span><span style=3D"color: rgb(102, 102, 0);=
">::</span><span style=3D"color: rgb(0, 0, 0);">forward</span><span style=
=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(102, 0, =
102);">Args</span><span style=3D"color: rgb(102, 102, 0);">>(</span><spa=
n style=3D"color: rgb(0, 0, 0);">args</span><span style=3D"color: rgb(102, =
102, 0);">)...)<wbr>;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0=
</span><span style=3D"color: rgb(102, 102, 0);">}</span><span style=3D"col=
or: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0)=
;">~</span><span style=3D"color: rgb(0, 0, 0);">relocate_wrapper</span><spa=
n style=3D"color: rgb(102, 102, 0);">()</span><span style=3D"color: rgb(0, =
0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">{</span><span styl=
e=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">r=
einterpret_cast</span><span style=3D"color: rgb(102, 102, 0);"><</span><=
span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, =
102, 0);">&>(</span><span style=3D"color: rgb(0, 0, 0);">buf</span><=
span style=3D"color: rgb(102, 102, 0);">).~</span><span style=3D"color: rgb=
(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">()<wbr>;</span=
><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102=
, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span>=
<span style=3D"color: rgb(102, 102, 0);">>></span><span style=3D"colo=
r: rgb(0, 0, 0);">relocate_wrapper</span><span style=3D"color: rgb(102, 102=
, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">relocate_<wbr>wrapper</=
span><span style=3D"color: rgb(102, 102, 0);">&</span><span style=3D"co=
lor: rgb(0, 0, 0);"> rhs</span><span style=3D"color: rgb(102, 102, 0);">)</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: rgb(0, 0, 136);">new</span><span style=3D"=
color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">(&am=
p;</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span style=3D"colo=
r: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> T</span=
><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb=
(0, 0, 136);">reinterpret_cast</span><span style=3D"color: rgb(102, 102, 0)=
;"><</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"c=
olor: rgb(102, 102, 0);">&&>(</span><span style=3D"color: rgb(0,=
0, 0);">rhs</span><span style=3D"color: rgb(102, 102, 0);">.</span><span s=
tyle=3D"color: rgb(0, 0, 0);">bu<wbr>f</span><span style=3D"color: rgb(102,=
102, 0);">));</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0=
</span><span style=3D"color: rgb(0, 0, 136);">reinterpret_cast</span><span=
style=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0,=
0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">&>(</span>=
<span style=3D"color: rgb(0, 0, 0);">rhs</span><span style=3D"color: rgb(10=
2, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span s=
tyle=3D"color: rgb(102, 102, 0);">).<wbr>~</span><span style=3D"color: rgb(=
0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">();</span><span=
style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb=
(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 std=
</span><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"col=
or: rgb(0, 0, 0);">aligned_storage_t</span><span style=3D"color: rgb(102, 1=
02, 0);"><</span><span style=3D"color: rgb(0, 0, 136);">sizeof</span><sp=
an style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, =
0, 0);"><wbr>T</span><span style=3D"color: rgb(102, 102, 0);">),</span><spa=
n style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 13=
6);">alignof</span><span style=3D"color: rgb(102, 102, 0);">(</span><span s=
tyle=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0=
);">)></span><span style=3D"color: rgb(0, 0, 0);"> buf</span><span style=
=3D"color: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);">=
<br></span><span style=3D"color: rgb(102, 102, 0);">};</span></div></code><=
/div><div><br></div></div><div>Hm... it might be nice to ensure that the re=
locator doesn't do any unnecessary work copying the buffer that's j=
ust going to be placement new moved into. Is that an argument against an im=
plicit mem-initializer-list?</div></div></blockquote></div>
<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 />
------=_Part_867_988721069.1439243947634--
------=_Part_866_2035194516.1439243947633--
.
Author: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 15:17:01 -0700 (PDT)
Raw View
------=_Part_5153_517007116.1439245021585
Content-Type: multipart/alternative;
boundary="----=_Part_5154_539478872.1439245021586"
------=_Part_5154_539478872.1439245021586
Content-Type: text/plain; charset=UTF-8
However, if there's real desire for the wrapper you show to be legal, a
better way to do it would probably be to allow this:
>>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { a = this; }
But this means we:
- say goodbye to the noexcept guarantee;
- define the point when ~B is called in the original location -
probably when >>A returns;
- introduce another type trait, is_nothrow_relocatable
I would have preferred to avoid this, but - I guess, if people *really*
want to merge move and copy construction into relocation... *(shudder :)*
On Monday, August 10, 2015 at 3:59:07 PM UTC-6, isocp...@denisbider.com
wrote:
> Hmm, good points.
>
> There are definitely situations where you don't want to mem-initialize a
> trivial member, such as in the example:
>
> >>A(A& x) : >>B(x), >>c(x.c), >>i(x.i)
>
> { a = *this*; }
>
> However, one might definitely argue that situations where you want to
> mem-initialize a base or a member, but with a non-corresponding member, are
> practically nonexistent. So, we may in fact prefer the following:
>
> >>A(A& x) : >>B, >>c, >>i
>
> { a = *this*; }
>
> The relocate_wrapper you suggest I think looks neat, and should be legal.
> I don't see a reason why it wouldn't be legal, if the mem-initializer-list
> is not implicit.
>
> It seems to me, intuitively, that there's no reason to make it illegal to
> access any data member of the moved-from subobject until the outermost
> relocator exits.
>
> I see no obvious reason why virtual methods shouldn't continue to work, as
> well. But this is not to say, of course, that one should call them.
>
> In general, anything that's const ought to be safe to call. Which is an
> argument in favor of making the signature >>T(T const&) - except that would
> prevent zeroing out of members.
>
>
> On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wrote:
>
>> A few queries:
>>
>> What exactly are the semantics of the mem-initializer-list, particularly
>> with regard to omitted, duplicated or misplaced bases/members:
>>
>> struct A {
>> std::string q, r, s;
>> >>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
>> };
>>
>> Is it ever legitimate for a mem-initializer to be omitted or to take any
>> form other than >>id(x.id) where the two identifiers are equivalent? If
>> so, whose responsibility is it to call the destructor on the corresponding
>> member of the source object? If not, would it be better to omit the
>> mem-initializer-list entirely, as with destructors?
>>
>> Within the body of the relocator special member function, what are the
>> lifetime statuses of the source and destination objects, particularly with
>> regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
>> members of the source object, or is this undefined behavior as they are
>> destructed? If the type is polymorphic, is it permissible to dynamic_cast
>> or invoke virtual functions on the source? Indeed, is it permissible to
>> invoke any member functions on the source?
>>
>> In particular, I'd like to make this utility class legal (noting that
>> aligned_storage_t is a POD but my utility class is not):
>>
>> template<class T>
>> struct relocate_wrapper {
>> template<class... Args> relocate_wrapper(Args&&... args) {
>> new (&buf) T(std::forward<Args>(args)...);
>> }
>> ~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
>> >>relocate_wrapper(relocate_wrapper& rhs) {
>> new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
>> reinterpret_cast<T&>(rhs.buf).~T();
>> }
>> std::aligned_storage_t<sizeof(T), alignof(T)> buf;
>> };
>>
>> Hm... it might be nice to ensure that the relocator doesn't do any
>> unnecessary work copying the buffer that's just going to be placement new
>> moved into. Is that an argument against an implicit mem-initializer-list?
>>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5154_539478872.1439245021586
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>However,=C2=A0if there's real desire for the wrap=
per you show to be legal, a better way to do it would probably be to allow =
this:</div><div><br></div><div><font color=3D"#000000" face=3D"Times New Ro=
man" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"font-family: Consolas; font-size: 10pt;"><font color=
=3D"#000000">=C2=A0</font></span></p><font color=3D"#000000" face=3D"Times =
New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"><span s=
tyle=3D"mso-spacerun: yes;">=C2=A0 </span>>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font=
-family: "Times New Roman";">A</span><span style=3D"color: rgb(48=
, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-famil=
y: "Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "T=
imes New Roman";">A</span><span style=3D"color: rgb(48, 128, 128); fon=
t-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times N=
ew Roman";">&</span><span style=3D"color: rgb(0, 0, 32); font-fami=
ly: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Rom=
an";"> x</span><span style=3D"color: rgb(48, 128, 128); font-family: C=
onsolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&qu=
ot;;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; f=
ont-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </s=
pan><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">:</span><sp=
an style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";"> B</span><span style=
=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";">(</span><span style=3D"co=
lor: rgb(0, 102, 238); font-family: Consolas; font-size: 10pt; mso-fareast-=
font-family: "Times New Roman";">std</span><span style=3D"color: =
rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-=
family: "Times New Roman";">::</span><span style=3D"color: rgb(0,=
0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &=
quot;Times New Roman";">move</span><span style=3D"color: rgb(48, 128, =
128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &quo=
t;Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times Ne=
w Roman";">x</span><span style=3D"color: rgb(48, 128, 128); font-famil=
y: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roma=
n";">))</span><span style=3D"color: rgb(64, 96, 128); font-family: Con=
solas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;;">,</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </spa=
n><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size=
: 10pt; mso-fareast-font-family: "Times New Roman";">>></sp=
an><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 1=
0pt; mso-fareast-font-family: "Times New Roman";">c</span><span s=
tyle=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">(</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";">x</span><span style=3D"color:=
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";">.</span><span style=3D"color: rgb(0=
, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: =
"Times New Roman";">c</span><span style=3D"color: rgb(48, 128, 12=
8); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">)</span><span style=3D"color: rgb(64, 96, 128); fon=
t-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times N=
ew Roman";">, </span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Ro=
man";">>></span><span style=3D"color: rgb(0, 0, 32); font-family=
: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman=
";">i</span><span style=3D"color: rgb(48, 128, 128); font-family: Cons=
olas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";">x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt; mso-fareast-font-family: "Times New Roman";">.</span><span=
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">i</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";">)</span><span style=3D"color:=
rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-fa=
mily: "Times New Roman";"> </span><span style=3D"color: rgb(64, 9=
6, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &=
quot;Times New Roman";">{ </span><span style=3D"color: rgb(0, 0, 32); =
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Time=
s New Roman";">a </span><span style=3D"color: rgb(48, 128, 128); font-=
family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New=
Roman";">=3D</span><span style=3D"color: rgb(0, 0, 32); font-family: =
Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&q=
uot;;"> </span><span style=3D"color: rgb(48, 128, 128); font-family: Consol=
as; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"=
>this</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; =
font-size: 10pt; mso-fareast-font-family: "Times New Roman";">; }=
</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0</spa=
n></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>But this means we:</div><div><br></div><di=
v>- say goodbye to the noexcept guarantee;</div><div><br></div><div>- defin=
e the point when=C2=A0~B is called=C2=A0in the original location - probably=
=C2=A0when >>A returns;</div><div><br></div><div>- introduce another =
type trait, <font face=3D"courier new,monospace">is_nothrow_relocatable</fo=
nt></div><div><br></div><div>I would have preferred to avoid this, but - I =
guess, if people <em>really</em> want to merge move and copy=C2=A0construct=
ion into relocation... <em>(shudder :)</em></div><div><br></div><div><br>On=
Monday, August 10, 2015 at 3:59:07 PM UTC-6, isocp...@denisbider.com wrote=
:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex=
; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-wid=
th: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>Hmm, good points.=
</div><div><br></div><div>There are definitely situations where you don'=
;t want to mem-initialize a trivial member, such as in the example:</div><d=
iv><br></div><div><font color=3D"#000000" face=3D"Times New Roman" size=3D"=
3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; f=
ont-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: =
Consolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128)=
; font-family: Consolas; font-size: 10pt;">)</span><span style=3D"color: rg=
b(64, 96, 128); font-family: Consolas; font-size: 10pt;">,</span><span styl=
e=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">(</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">x</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">.</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;">c</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; =
font-size: 10pt;">)</span><span style=3D"color: rgb(64, 96, 128); font-fami=
ly: Consolas; font-size: 10pt;">, </span><span style=3D"color: rgb(48, 128,=
128); font-family: Consolas; font-size: 10pt;">>></span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">i</span>=
<span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: =
10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;">.</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;">i</span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span></p><fon=
t color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>However, one might definitely argue that s=
ituations where you want to mem-initialize a base or a member, but with a n=
on-corresponding member,=C2=A0are practically nonexistent. So, we may in fa=
ct=C2=A0prefer the following:</div><div><br></div><div><font color=3D"#0000=
00" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fo=
nt-size: 10pt;">,</span><span style=3D"color: rgb(0, 0, 32); font-family: C=
onsolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128);=
font-family: Consolas; font-size: 10pt;">>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">c</span><span s=
tyle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">,=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt;">i</span></p><font color=3D"#000000" face=
=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>The relocate_wrapper you suggest I think l=
ooks neat, and should be legal. I don't see a reason why it wouldn'=
t be legal, if the mem-initializer-list is not implicit.</div><div><br></di=
v><div>It seems to me,=C2=A0intuitively,=C2=A0that there's no reason to=
make it illegal to access any data member of the moved-from subobject unti=
l the outermost relocator exits.</div><div><br></div><div>I see no obvious =
reason why virtual methods shouldn't continue to work, as well. But thi=
s is not to say, of course, that one should call them.</div><div><br></div>=
<div>In general, anything that's const ought to be safe to call. Which =
is an argument in favor of making the signature >>T(T const&) -=
=C2=A0except that would prevent zeroing out of members.</div><div><br></div=
><div><br>On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>A few queries:<=
/div><div><br></div><div>What exactly are the semantics of the mem-initiali=
zer-list, particularly with regard to omitted, duplicated or misplaced base=
s/members:<br></div><div><br></div><div style=3D"border: 1px solid rgb(187,=
187, 187); border-image: none; background-color: rgb(250, 250, 250);"><cod=
e><div><span style=3D"color: rgb(0, 0, 136);">struct</span><span style=3D"c=
olor: rgb(0, 0, 0);"> A </span><span style=3D"color: rgb(102, 102, 0);">{</=
span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 std</span><span=
style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0=
, 136);">string</span><span style=3D"color: rgb(0, 0, 0);"> q</span><span s=
tyle=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0=
);"> r</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=
=3D"color: rgb(0, 0, 0);"> s</span><span style=3D"color: rgb(102, 102, 0);"=
>;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color: rgb(102, 102, 0);">>></span><span style=3D"color: r=
gb(0, 0, 0);">A</span><span style=3D"color: rgb(102, 102, 0);">(</span><spa=
n style=3D"color: rgb(0, 0, 0);">A</span><span style=3D"color: rgb(102, 102=
, 0);">&</span><span style=3D"color: rgb(0, 0, 0);"> x</span><span styl=
e=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"=
> </span><span style=3D"color: rgb(102, 102, 0);">:</span><span style=3D"co=
lor: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">>&g=
t;</span><span style=3D"color: rgb(0, 0, 0);">r</span><span style=3D"color:=
rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">x</span><s=
pan style=3D"color: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0,=
0, 0);">r</span><span style=3D"color: rgb(102, 102, 0);">),</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0)=
;">>></span><span style=3D"color: rgb(0, 0, 0);">s</span><span style=
=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">=
x</span><span style=3D"color: rgb(102, 102, 0);">.</span><span style=3D"col=
or: rgb(0, 0, 0);">r</span><span style=3D"color: rgb(102, 102, 0);">)</span=
><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102=
, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"> </span><span styl=
e=3D"color: rgb(136, 0, 0);">/* oops */</span><span style=3D"color: rgb(0, =
0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">}</span><span styl=
e=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0=
);">};</span><span style=3D"color: rgb(0, 0, 0);"><br></span></div></code><=
/div><div><br></div><div>Is it ever legitimate for a mem-initializer to be =
omitted or to take any form other than <font face=3D"courier new, monospace=
">>>id(<a onmousedown=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB69ZOU5okYo=
Dl3uhnQkQ';return true;" onclick=3D"this.href=3D'http://www.google.=
com/url?q\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB6=
9ZOU5okYoDl3uhnQkQ';return true;" href=3D"http://x.id" target=3D"_blank=
" rel=3D"nofollow">x.id</a>)</font> where the two identifiers are equivalen=
t? If so, whose responsibility is it to call the destructor on the correspo=
nding member of the source object? If not, would it be better to omit the m=
em-initializer-list entirely, as with destructors?</div><div><br></div><div=
>Within the body of the relocator special member function, what are the lif=
etime statuses of the source and destination objects, particularly with reg=
ard to [class.cdtor]? Is it permissible to form lvalues to the bases and me=
mbers of the source object, or is this undefined behavior as they are destr=
ucted? If the type is polymorphic, is it permissible to dynamic_cast or inv=
oke virtual functions on the source? Indeed, is it permissible to invoke an=
y member functions on the source?</div><div><br></div><div>In particular, I=
'd like to make this utility class legal (noting that aligned_storage_t=
is a POD but my utility class is not):</div><div><br></div><div><div style=
=3D"border: 1px solid rgb(187, 187, 187); border-image: none; background-co=
lor: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0, 136);"=
>template</span><span style=3D"color: rgb(102, 102, 0);"><</span><span s=
tyle=3D"color: rgb(0, 0, 136);">class</span><span style=3D"color: rgb(0, 0,=
0);"> T</span><span style=3D"color: rgb(102, 102, 0);">></span><span st=
yle=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136=
);">struct</span><span style=3D"color: rgb(0, 0, 0);"> relocate_wrapper </s=
pan><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: =
rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">tem=
plate</span><span style=3D"color: rgb(102, 102, 0);"><</span><span style=
=3D"color: rgb(0, 0, 136);">class</span><span style=3D"color: rgb(102, 102,=
0);">...</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D=
"color: rgb(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0=
);">></span><span style=3D"color: rgb(0, 0, 0);"> relocate_wrapper</span=
><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb=
(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0);">&&a=
mp;...</span><span style=3D"color: rgb(0, 0, 0);"> args</span><span style=
=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);">=
</span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"col=
or: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0,=
136);">new</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">(&</span><span style=3D"color: rgb(0, 0, =
0);">buf</span><span style=3D"color: rgb(102, 102, 0);">)</span><span style=
=3D"color: rgb(0, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0);"=
>(</span><span style=3D"color: rgb(0, 0, 0);">std</span><span style=3D"colo=
r: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0, 0);">forward=
</span><span style=3D"color: rgb(102, 102, 0);"><</span><span style=3D"c=
olor: rgb(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0);=
">>(</span><span style=3D"color: rgb(0, 0, 0);">args</span><span style=
=3D"color: rgb(102, 102, 0);">)...)<wbr>;</span><span style=3D"color: rgb(0=
, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">}</spa=
n><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"col=
or: rgb(102, 102, 0);">~</span><span style=3D"color: rgb(0, 0, 0);">relocat=
e_wrapper</span><span style=3D"color: rgb(102, 102, 0);">()</span><span sty=
le=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);=
">{</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color=
: rgb(0, 0, 136);">reinterpret_cast</span><span style=3D"color: rgb(102, 10=
2, 0);"><</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=
=3D"color: rgb(102, 102, 0);">&>(</span><span style=3D"color: rgb(0,=
0, 0);">buf</span><span style=3D"color: rgb(102, 102, 0);">).~</span><span=
style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102,=
0);">()<wbr>;</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);=
"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">>></span=
><span style=3D"color: rgb(0, 0, 0);">relocate_wrapper</span><span style=3D=
"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">rel=
ocate_<wbr>wrapper</span><span style=3D"color: rgb(102, 102, 0);">&</sp=
an><span style=3D"color: rgb(0, 0, 0);"> rhs</span><span style=3D"color: rg=
b(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span=
style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0,=
0);"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">new</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">(&</span><span style=3D"color: rgb(0, 0, 0);">buf</span=
><span style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb=
(0, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
style=3D"color: rgb(0, 0, 136);">reinterpret_cast</span><span style=3D"col=
or: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 0);">T</s=
pan><span style=3D"color: rgb(102, 102, 0);">&&>(</span><span st=
yle=3D"color: rgb(0, 0, 0);">rhs</span><span style=3D"color: rgb(102, 102, =
0);">.</span><span style=3D"color: rgb(0, 0, 0);">bu<wbr>f</span><span styl=
e=3D"color: rgb(102, 102, 0);">));</span><span style=3D"color: rgb(0, 0, 0)=
;"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">reinterp=
ret_cast</span><span style=3D"color: rgb(102, 102, 0);"><</span><span st=
yle=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0)=
;">&>(</span><span style=3D"color: rgb(0, 0, 0);">rhs</span><span st=
yle=3D"color: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0)=
;">buf</span><span style=3D"color: rgb(102, 102, 0);">).<wbr>~</span><span =
style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, =
0);">();</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span=
style=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0,=
0);"><br>=C2=A0 std</span><span style=3D"color: rgb(102, 102, 0);">::</spa=
n><span style=3D"color: rgb(0, 0, 0);">aligned_storage_t</span><span style=
=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 13=
6);">sizeof</span><span style=3D"color: rgb(102, 102, 0);">(</span><span st=
yle=3D"color: rgb(0, 0, 0);"><wbr>T</span><span style=3D"color: rgb(102, 10=
2, 0);">),</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(0, 0, 136);">alignof</span><span style=3D"color: rgb(102, 10=
2, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D=
"color: rgb(102, 102, 0);">)></span><span style=3D"color: rgb(0, 0, 0);"=
> buf</span><span style=3D"color: rgb(102, 102, 0);">;</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">=
};</span></div></code></div><div><br></div></div><div>Hm... it might be nic=
e to ensure that the relocator doesn't do any unnecessary work copying =
the buffer that's just going to be placement new moved into. Is that an=
argument against an implicit mem-initializer-list?</div></div></blockquote=
></div></blockquote></div>
<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 />
------=_Part_5154_539478872.1439245021586--
------=_Part_5153_517007116.1439245021585--
.
Author: isocppgroup@denisbider.com
Date: Mon, 10 Aug 2015 15:45:58 -0700 (PDT)
Raw View
------=_Part_804_973806631.1439246758706
Content-Type: multipart/alternative;
boundary="----=_Part_805_972882936.1439246758708"
------=_Part_805_972882936.1439246758708
Content-Type: text/plain; charset=UTF-8
Actually, if we want to give the implementer this much control, there's no
reason we shouldn't put the burden of calling ~B on the implementer.
I thought this would be a problem if ~B is virtual, but it turns out the
following is legal:
*struct* A { *virtual* ~A() { cout << "~A()" << endl; } };
*struct* B : A { *virtual* ~B() { cout << "~B()" << endl; } };
*struct* C : B { *virtual* ~C() { cout << "~C()" << endl; } };
*void* DestroySubobject(B* b) { b->B::~B(); }
It turns out, this calls ~A and ~B, but not ~C.
It seems to me it follows: if we allow >>A to initialize the subobjects in
whatever fashion; including with copy or move construction; then it would
make sense to expect the author of >>A to call B::~B.
On Monday, August 10, 2015 at 4:17:01 PM UTC-6, isocp...@denisbider.com
wrote:
> However, if there's real desire for the wrapper you show to be legal, a
> better way to do it would probably be to allow this:
>
>
>
> >>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { a = this; }
>
>
>
> But this means we:
>
> - say goodbye to the noexcept guarantee;
>
> - define the point when ~B is called in the original location -
> probably when >>A returns;
>
> - introduce another type trait, is_nothrow_relocatable
>
> I would have preferred to avoid this, but - I guess, if people *really*
> want to merge move and copy construction into relocation... *(shudder :)*
>
>
> On Monday, August 10, 2015 at 3:59:07 PM UTC-6, isocp...@denisbider.com
> wrote:
>
>> Hmm, good points.
>>
>> There are definitely situations where you don't want to mem-initialize a
>> trivial member, such as in the example:
>>
>> >>A(A& x) : >>B(x), >>c(x.c), >>i(x.i)
>>
>> { a = *this*; }
>>
>> However, one might definitely argue that situations where you want to
>> mem-initialize a base or a member, but with a non-corresponding member, are
>> practically nonexistent. So, we may in fact prefer the following:
>>
>> >>A(A& x) : >>B, >>c, >>i
>>
>> { a = *this*; }
>>
>> The relocate_wrapper you suggest I think looks neat, and should be legal.
>> I don't see a reason why it wouldn't be legal, if the mem-initializer-list
>> is not implicit.
>>
>> It seems to me, intuitively, that there's no reason to make it illegal to
>> access any data member of the moved-from subobject until the outermost
>> relocator exits.
>>
>> I see no obvious reason why virtual methods shouldn't continue to work,
>> as well. But this is not to say, of course, that one should call them.
>>
>> In general, anything that's const ought to be safe to call. Which is an
>> argument in favor of making the signature >>T(T const&) - except that would
>> prevent zeroing out of members.
>>
>>
>> On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wrote:
>>
>>> A few queries:
>>>
>>> What exactly are the semantics of the mem-initializer-list, particularly
>>> with regard to omitted, duplicated or misplaced bases/members:
>>>
>>> struct A {
>>> std::string q, r, s;
>>> >>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
>>> };
>>>
>>> Is it ever legitimate for a mem-initializer to be omitted or to take any
>>> form other than >>id(x.id) where the two identifiers are equivalent? If
>>> so, whose responsibility is it to call the destructor on the corresponding
>>> member of the source object? If not, would it be better to omit the
>>> mem-initializer-list entirely, as with destructors?
>>>
>>> Within the body of the relocator special member function, what are the
>>> lifetime statuses of the source and destination objects, particularly with
>>> regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
>>> members of the source object, or is this undefined behavior as they are
>>> destructed? If the type is polymorphic, is it permissible to dynamic_cast
>>> or invoke virtual functions on the source? Indeed, is it permissible to
>>> invoke any member functions on the source?
>>>
>>> In particular, I'd like to make this utility class legal (noting that
>>> aligned_storage_t is a POD but my utility class is not):
>>>
>>> template<class T>
>>> struct relocate_wrapper {
>>> template<class... Args> relocate_wrapper(Args&&... args) {
>>> new (&buf) T(std::forward<Args>(args)...);
>>> }
>>> ~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
>>> >>relocate_wrapper(relocate_wrapper& rhs) {
>>> new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
>>> reinterpret_cast<T&>(rhs.buf).~T();
>>> }
>>> std::aligned_storage_t<sizeof(T), alignof(T)> buf;
>>> };
>>>
>>> Hm... it might be nice to ensure that the relocator doesn't do any
>>> unnecessary work copying the buffer that's just going to be placement new
>>> moved into. Is that an argument against an implicit mem-initializer-list?
>>>
>>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_805_972882936.1439246758708
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Actually, if we want to give the implementer this muc=
h control, there's no reason we shouldn't put the burden of calling=
~B on the implementer.</div><div><br></div><div>I thought this would be a =
problem if ~B is virtual, but it turns out the following is legal:</div><di=
v><br></div><div><font color=3D"#000000" face=3D"Times New Roman" size=3D"3=
">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0</spa=
n></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><b><span style=3D"color: rgb(32, 0, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">struct=
</span></b><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"> A<span=
style=3D"mso-spacerun: yes;">=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span =
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">{</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";"> </span><b><span style=3D"col=
or: rgb(32, 0, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fo=
nt-family: "Times New Roman";">virtual</span></b><span style=3D"c=
olor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-fo=
nt-family: "Times New Roman";"> </span><span style=3D"color: rgb(=
48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fam=
ily: "Times New Roman";">~</span><span style=3D"color: rgb(0, 0, =
32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
;Times New Roman";">A</span><span style=3D"color: rgb(48, 128, 128); f=
ont-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times=
New Roman";">()</span><span style=3D"color: rgb(0, 0, 32); font-famil=
y: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roma=
n";"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Cons=
olas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;">{</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </span=
><span style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10=
pt; mso-fareast-font-family: "Times New Roman";">cout</span><span=
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";"> </span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";"><<</span><span style=3D=
"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-=
font-family: "Times New Roman";"> </span><span style=3D"color: ma=
roon; font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &quo=
t;Times New Roman";">"</span><span style=3D"color: rgb(16, 96, 18=
2); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">~A()</span><span style=3D"color: maroon; font-famil=
y: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roma=
n";">"</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&quo=
t;;"> </span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas=
; font-size: 10pt; mso-fareast-font-family: "Times New Roman";">&=
lt;<</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; f=
ont-size: 10pt; mso-fareast-font-family: "Times New Roman";"> </s=
pan><span style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size:=
10pt; mso-fareast-font-family: "Times New Roman";">endl</span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t; mso-fareast-font-family: "Times New Roman";">;</span><span sty=
le=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-far=
east-font-family: "Times New Roman";"> </span><span style=3D"colo=
r: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fo=
nt-family: "Times New Roman";">}</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family:=
"Times New Roman";"> </span><span style=3D"color: rgb(64, 96, 12=
8); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
Times New Roman";">};</span></p><font color=3D"#000000" face=3D"Times =
New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><b><span style=3D"color: rgb(32, 0, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">struct=
</span></b><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"> B </sp=
an><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size=
: 10pt; mso-fareast-font-family: "Times New Roman";">:</span><spa=
n style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; ms=
o-fareast-font-family: "Times New Roman";"> A </span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fa=
reast-font-family: "Times New Roman";">{</span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font=
-family: "Times New Roman";"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";">virtual</span></b><span style=3D"color: r=
gb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";"> </span><span style=3D"color: rgb(48, 128=
, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &q=
uot;Times New Roman";">~</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">B</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Ro=
man";">()</span><span style=3D"color: rgb(0, 0, 32); font-family: Cons=
olas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; f=
ont-size: 10pt; mso-fareast-font-family: "Times New Roman";">{</s=
pan><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: =
10pt; mso-fareast-font-family: "Times New Roman";"> </span><span =
style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">cout</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";"> </span><span style=3D"color:=
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";"><<</span><span style=3D"color=
: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-f=
amily: "Times New Roman";"> </span><span style=3D"color: maroon; =
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Time=
s New Roman";">"</span><span style=3D"color: rgb(16, 96, 182); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">~B()</span><span style=3D"color: maroon; font-family: Con=
solas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;;">"</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas=
; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"> =
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"><<=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt; mso-fareast-font-family: "Times New Roman";"> </span><s=
pan style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt;=
mso-fareast-font-family: "Times New Roman";">endl</span><span st=
yle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">;</span><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-f=
ont-family: "Times New Roman";"> </span><span style=3D"color: rgb=
(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fam=
ily: "Times New Roman";">}</span><span style=3D"color: rgb(0, 0, =
32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
;Times New Roman";"> </span><span style=3D"color: rgb(64, 96, 128); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">};</span></p><font color=3D"#000000" face=3D"Times New Ro=
man" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><b><span style=3D"color: rgb(32, 0, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">struct=
</span></b><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"> C </sp=
an><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size=
: 10pt; mso-fareast-font-family: "Times New Roman";">:</span><spa=
n style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; ms=
o-fareast-font-family: "Times New Roman";"> B </span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fa=
reast-font-family: "Times New Roman";">{</span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font=
-family: "Times New Roman";"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";">virtual</span></b><span style=3D"color: r=
gb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-fami=
ly: "Times New Roman";"> </span><span style=3D"color: rgb(48, 128=
, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &q=
uot;Times New Roman";">~</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">C</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Ro=
man";">()</span><span style=3D"color: rgb(0, 0, 32); font-family: Cons=
olas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; f=
ont-size: 10pt; mso-fareast-font-family: "Times New Roman";">{</s=
pan><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: =
10pt; mso-fareast-font-family: "Times New Roman";"> </span><span =
style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">cout</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-farea=
st-font-family: "Times New Roman";"> </span><span style=3D"color:=
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-fon=
t-family: "Times New Roman";"><<</span><span style=3D"color=
: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-f=
amily: "Times New Roman";"> </span><span style=3D"color: maroon; =
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Time=
s New Roman";">"</span><span style=3D"color: rgb(16, 96, 182); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">~C()</span><span style=3D"color: maroon; font-family: Con=
solas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;;">"</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas=
; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"> =
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"><<=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt; mso-fareast-font-family: "Times New Roman";"> </span><s=
pan style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt;=
mso-fareast-font-family: "Times New Roman";">endl</span><span st=
yle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso=
-fareast-font-family: "Times New Roman";">;</span><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-f=
ont-family: "Times New Roman";"> </span><span style=3D"color: rgb=
(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-fam=
ily: "Times New Roman";">}</span><span style=3D"color: rgb(0, 0, =
32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "=
;Times New Roman";"> </span><span style=3D"color: rgb(64, 96, 128); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";">};</span></p><font color=3D"#000000" face=3D"Times New Ro=
man" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0</spa=
n></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><b><span style=3D"color: rgb(32, 0, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">void</=
span></b><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-s=
ize: 10pt; mso-fareast-font-family: "Times New Roman";"> DestroyS=
ubobject</span><span style=3D"color: rgb(48, 128, 128); font-family: Consol=
as; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"=
>(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-s=
ize: 10pt; mso-fareast-font-family: "Times New Roman";">B</span><=
span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 1=
0pt; mso-fareast-font-family: "Times New Roman";">*</span><span s=
tyle=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";"> b</span><span style=3D"c=
olor: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareas=
t-font-family: "Times New Roman";">)</span><span style=3D"color: =
rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-fam=
ily: "Times New Roman";"> </span><span style=3D"color: rgb(64, 96=
, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &q=
uot;Times New Roman";">{</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times =
New Roman";"> b</span><span style=3D"color: rgb(48, 128, 128); font-fa=
mily: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New R=
oman";">-></span><span style=3D"color: rgb(0, 0, 32); font-family: =
Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roman&q=
uot;;">B</span><span style=3D"color: rgb(64, 96, 128); font-family: Consola=
s; font-size: 10pt; mso-fareast-font-family: "Times New Roman";">=
::</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fo=
nt-size: 10pt; mso-fareast-font-family: "Times New Roman";">~</sp=
an><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 1=
0pt; mso-fareast-font-family: "Times New Roman";">B</span><span s=
tyle=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">()</span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fa=
reast-font-family: "Times New Roman";">;</span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font=
-family: "Times New Roman";"> </span><span style=3D"color: rgb(64=
, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family=
: "Times New Roman";">}</span></p><font color=3D"#000000" face=3D=
"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0</spa=
n></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>It turns out, this calls ~A and ~B, but no=
t ~C.</div><div><br></div><div>It seems to me it follows:=C2=A0if we allow =
>>A to initialize the subobjects in whatever fashion; including with =
copy or move construction; then it would make sense to expect the author of=
>>A to call B::~B.</div><div><br><br>On Monday, August 10, 2015 at 4=
:17:01 PM UTC-6, isocp...@denisbider.com wrote:</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-l=
eft-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: s=
olid;"><div dir=3D"ltr"><div>However,=C2=A0if there's real desire for t=
he wrapper you show to be legal, a better way to do it would probably be to=
allow this:</div><div><br></div><div><font color=3D"#000000" face=3D"Times=
New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"font-family: Consolas; font-size: 10pt;">=
<font color=3D"#000000">=C2=A0</font></span></p><font color=3D"#000000" fac=
e=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;"><span>=C2=A0 </span>>></span><span style=3D=
"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">A</span><sp=
an style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10p=
t;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fon=
t-size: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family=
: Consolas; font-size: 10pt;">&</span><span style=3D"color: rgb(0, 0, 3=
2); font-family: Consolas; font-size: 10pt;"> x</span><span style=3D"color:=
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span><span =
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </=
span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-si=
ze: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"> B</span><span style=3D"color: rgb(48, 128, 128); fon=
t-family: Consolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, =
102, 238); font-family: Consolas; font-size: 10pt;">std</span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">::</s=
pan><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: =
10pt;">move</span><span style=3D"color: rgb(48, 128, 128); font-family: Con=
solas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-=
family: Consolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 1=
28, 128); font-family: Consolas; font-size: 10pt;">))</span><span style=3D"=
color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">,</span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
"> </span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; f=
ont-size: 10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-f=
amily: Consolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 12=
8, 128); font-family: Consolas; font-size: 10pt;">(</span><span style=3D"co=
lor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">x</span><span =
style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;"=
>.</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-s=
ize: 10pt;">c</span><span style=3D"color: rgb(48, 128, 128); font-family: C=
onsolas; font-size: 10pt;">)</span><span style=3D"color: rgb(64, 96, 128); =
font-family: Consolas; font-size: 10pt;">, </span><span style=3D"color: rgb=
(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><sp=
an style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">=
i</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">.</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">i</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; f=
ont-size: 10pt;">{ </span><span style=3D"color: rgb(0, 0, 32); font-family:=
Consolas; font-size: 10pt;">a </span><span style=3D"color: rgb(48, 128, 12=
8); font-family: Consolas; font-size: 10pt;">=3D</span><span style=3D"color=
: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span sty=
le=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">th=
is</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fon=
t-size: 10pt;">; }</span></p><font color=3D"#000000" face=3D"Times New Roma=
n" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font></div><div><br></div><div>But this means we:</div><div><br></div><di=
v>- say goodbye to the noexcept guarantee;</div><div><br></div><div>- defin=
e the point when=C2=A0~B is called=C2=A0in the original location - probably=
=C2=A0when >>A returns;</div><div><br></div><div>- introduce another =
type trait, <font face=3D"courier new,monospace">is_nothrow_relocatable</fo=
nt></div><div><br></div><div>I would have preferred to avoid this, but - I =
guess, if people <em>really</em> want to merge move and copy=C2=A0construct=
ion into relocation... <em>(shudder :)</em></div><div><br></div><div><br>On=
Monday, August 10, 2015 at 3:59:07 PM UTC-6, <a>isocp...@denisbider.com</a=
> wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0p=
x 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-l=
eft-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>Hmm, good =
points.</div><div><br></div><div>There are definitely situations where you =
don't want to mem-initialize a trivial member, such as in the example:<=
/div><div><br></div><div><font color=3D"#000000" face=3D"Times New Roman" s=
ize=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; f=
ont-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: =
Consolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128)=
; font-family: Consolas; font-size: 10pt;">)</span><span style=3D"color: rg=
b(64, 96, 128); font-family: Consolas; font-size: 10pt;">,</span><span styl=
e=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">(</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">x</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">.</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;">c</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; =
font-size: 10pt;">)</span><span style=3D"color: rgb(64, 96, 128); font-fami=
ly: Consolas; font-size: 10pt;">, </span><span style=3D"color: rgb(48, 128,=
128); font-family: Consolas; font-size: 10pt;">>></span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">i</span>=
<span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: =
10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;">.</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;">i</span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span></p><fon=
t color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>However, one might definitely argue that s=
ituations where you want to mem-initialize a base or a member, but with a n=
on-corresponding member,=C2=A0are practically nonexistent. So, we may in fa=
ct=C2=A0prefer the following:</div><div><br></div><div><font color=3D"#0000=
00" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fo=
nt-size: 10pt;">,</span><span style=3D"color: rgb(0, 0, 32); font-family: C=
onsolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128);=
font-family: Consolas; font-size: 10pt;">>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">c</span><span s=
tyle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">,=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt;">i</span></p><font color=3D"#000000" face=
=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>The relocate_wrapper you suggest I think l=
ooks neat, and should be legal. I don't see a reason why it wouldn'=
t be legal, if the mem-initializer-list is not implicit.</div><div><br></di=
v><div>It seems to me,=C2=A0intuitively,=C2=A0that there's no reason to=
make it illegal to access any data member of the moved-from subobject unti=
l the outermost relocator exits.</div><div><br></div><div>I see no obvious =
reason why virtual methods shouldn't continue to work, as well. But thi=
s is not to say, of course, that one should call them.</div><div><br></div>=
<div>In general, anything that's const ought to be safe to call. Which =
is an argument in favor of making the signature >>T(T const&) -=
=C2=A0except that would prevent zeroing out of members.</div><div><br></div=
><div><br>On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8=
ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-w=
idth: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>A few queries:<=
/div><div><br></div><div>What exactly are the semantics of the mem-initiali=
zer-list, particularly with regard to omitted, duplicated or misplaced base=
s/members:<br></div><div><br></div><div style=3D"border: 1px solid rgb(187,=
187, 187); border-image: none; background-color: rgb(250, 250, 250);"><cod=
e><div><span style=3D"color: rgb(0, 0, 136);">struct</span><span style=3D"c=
olor: rgb(0, 0, 0);"> A </span><span style=3D"color: rgb(102, 102, 0);">{</=
span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 std</span><span=
style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0=
, 136);">string</span><span style=3D"color: rgb(0, 0, 0);"> q</span><span s=
tyle=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0=
);"> r</span><span style=3D"color: rgb(102, 102, 0);">,</span><span style=
=3D"color: rgb(0, 0, 0);"> s</span><span style=3D"color: rgb(102, 102, 0);"=
>;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color: rgb(102, 102, 0);">>></span><span style=3D"color: r=
gb(0, 0, 0);">A</span><span style=3D"color: rgb(102, 102, 0);">(</span><spa=
n style=3D"color: rgb(0, 0, 0);">A</span><span style=3D"color: rgb(102, 102=
, 0);">&</span><span style=3D"color: rgb(0, 0, 0);"> x</span><span styl=
e=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"=
> </span><span style=3D"color: rgb(102, 102, 0);">:</span><span style=3D"co=
lor: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">>&g=
t;</span><span style=3D"color: rgb(0, 0, 0);">r</span><span style=3D"color:=
rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">x</span><s=
pan style=3D"color: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0,=
0, 0);">r</span><span style=3D"color: rgb(102, 102, 0);">),</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0)=
;">>></span><span style=3D"color: rgb(0, 0, 0);">s</span><span style=
=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">=
x</span><span style=3D"color: rgb(102, 102, 0);">.</span><span style=3D"col=
or: rgb(0, 0, 0);">r</span><span style=3D"color: rgb(102, 102, 0);">)</span=
><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102=
, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"> </span><span styl=
e=3D"color: rgb(136, 0, 0);">/* oops */</span><span style=3D"color: rgb(0, =
0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">}</span><span styl=
e=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0=
);">};</span><span style=3D"color: rgb(0, 0, 0);"><br></span></div></code><=
/div><div><br></div><div>Is it ever legitimate for a mem-initializer to be =
omitted or to take any form other than <font face=3D"courier new, monospace=
">>>id(<a onmousedown=3D"this.href=3D'http://www.google.com/url?q=
\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB69ZOU5okYo=
Dl3uhnQkQ';return true;" onclick=3D"this.href=3D'http://www.google.=
com/url?q\75http%3A%2F%2Fx.id\46sa\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB6=
9ZOU5okYoDl3uhnQkQ';return true;" href=3D"http://x.id" target=3D"_blank=
" rel=3D"nofollow">x.id</a>)</font> where the two identifiers are equivalen=
t? If so, whose responsibility is it to call the destructor on the correspo=
nding member of the source object? If not, would it be better to omit the m=
em-initializer-list entirely, as with destructors?</div><div><br></div><div=
>Within the body of the relocator special member function, what are the lif=
etime statuses of the source and destination objects, particularly with reg=
ard to [class.cdtor]? Is it permissible to form lvalues to the bases and me=
mbers of the source object, or is this undefined behavior as they are destr=
ucted? If the type is polymorphic, is it permissible to dynamic_cast or inv=
oke virtual functions on the source? Indeed, is it permissible to invoke an=
y member functions on the source?</div><div><br></div><div>In particular, I=
'd like to make this utility class legal (noting that aligned_storage_t=
is a POD but my utility class is not):</div><div><br></div><div><div style=
=3D"border: 1px solid rgb(187, 187, 187); border-image: none; background-co=
lor: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0, 136);"=
>template</span><span style=3D"color: rgb(102, 102, 0);"><</span><span s=
tyle=3D"color: rgb(0, 0, 136);">class</span><span style=3D"color: rgb(0, 0,=
0);"> T</span><span style=3D"color: rgb(102, 102, 0);">></span><span st=
yle=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(0, 0, 136=
);">struct</span><span style=3D"color: rgb(0, 0, 0);"> relocate_wrapper </s=
pan><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: =
rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">tem=
plate</span><span style=3D"color: rgb(102, 102, 0);"><</span><span style=
=3D"color: rgb(0, 0, 136);">class</span><span style=3D"color: rgb(102, 102,=
0);">...</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D=
"color: rgb(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0=
);">></span><span style=3D"color: rgb(0, 0, 0);"> relocate_wrapper</span=
><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb=
(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0);">&&a=
mp;...</span><span style=3D"color: rgb(0, 0, 0);"> args</span><span style=
=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);">=
</span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"col=
or: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0,=
136);">new</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(102, 102, 0);">(&</span><span style=3D"color: rgb(0, 0, =
0);">buf</span><span style=3D"color: rgb(102, 102, 0);">)</span><span style=
=3D"color: rgb(0, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0);"=
>(</span><span style=3D"color: rgb(0, 0, 0);">std</span><span style=3D"colo=
r: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0, 0);">forward=
</span><span style=3D"color: rgb(102, 102, 0);"><</span><span style=3D"c=
olor: rgb(102, 0, 102);">Args</span><span style=3D"color: rgb(102, 102, 0);=
">>(</span><span style=3D"color: rgb(0, 0, 0);">args</span><span style=
=3D"color: rgb(102, 102, 0);">)...)<wbr>;</span><span style=3D"color: rgb(0=
, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">}</spa=
n><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"col=
or: rgb(102, 102, 0);">~</span><span style=3D"color: rgb(0, 0, 0);">relocat=
e_wrapper</span><span style=3D"color: rgb(102, 102, 0);">()</span><span sty=
le=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);=
">{</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color=
: rgb(0, 0, 136);">reinterpret_cast</span><span style=3D"color: rgb(102, 10=
2, 0);"><</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=
=3D"color: rgb(102, 102, 0);">&>(</span><span style=3D"color: rgb(0,=
0, 0);">buf</span><span style=3D"color: rgb(102, 102, 0);">).~</span><span=
style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102,=
0);">()<wbr>;</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);=
"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">>></span=
><span style=3D"color: rgb(0, 0, 0);">relocate_wrapper</span><span style=3D=
"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">rel=
ocate_<wbr>wrapper</span><span style=3D"color: rgb(102, 102, 0);">&</sp=
an><span style=3D"color: rgb(0, 0, 0);"> rhs</span><span style=3D"color: rg=
b(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span=
style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0,=
0);"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">new</=
span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb=
(102, 102, 0);">(&</span><span style=3D"color: rgb(0, 0, 0);">buf</span=
><span style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb=
(0, 0, 0);"> T</span><span style=3D"color: rgb(102, 102, 0);">(</span><span=
style=3D"color: rgb(0, 0, 136);">reinterpret_cast</span><span style=3D"col=
or: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 0);">T</s=
pan><span style=3D"color: rgb(102, 102, 0);">&&>(</span><span st=
yle=3D"color: rgb(0, 0, 0);">rhs</span><span style=3D"color: rgb(102, 102, =
0);">.</span><span style=3D"color: rgb(0, 0, 0);">bu<wbr>f</span><span styl=
e=3D"color: rgb(102, 102, 0);">));</span><span style=3D"color: rgb(0, 0, 0)=
;"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">reinterp=
ret_cast</span><span style=3D"color: rgb(102, 102, 0);"><</span><span st=
yle=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0)=
;">&>(</span><span style=3D"color: rgb(0, 0, 0);">rhs</span><span st=
yle=3D"color: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0)=
;">buf</span><span style=3D"color: rgb(102, 102, 0);">).<wbr>~</span><span =
style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, =
0);">();</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span=
style=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0,=
0);"><br>=C2=A0 std</span><span style=3D"color: rgb(102, 102, 0);">::</spa=
n><span style=3D"color: rgb(0, 0, 0);">aligned_storage_t</span><span style=
=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 13=
6);">sizeof</span><span style=3D"color: rgb(102, 102, 0);">(</span><span st=
yle=3D"color: rgb(0, 0, 0);"><wbr>T</span><span style=3D"color: rgb(102, 10=
2, 0);">),</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=
=3D"color: rgb(0, 0, 136);">alignof</span><span style=3D"color: rgb(102, 10=
2, 0);">(</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D=
"color: rgb(102, 102, 0);">)></span><span style=3D"color: rgb(0, 0, 0);"=
> buf</span><span style=3D"color: rgb(102, 102, 0);">;</span><span style=3D=
"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">=
};</span></div></code></div><div><br></div></div><div>Hm... it might be nic=
e to ensure that the relocator doesn't do any unnecessary work copying =
the buffer that's just going to be placement new moved into. Is that an=
argument against an implicit mem-initializer-list?</div></div></blockquote=
></div></blockquote></div></blockquote></div>
<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 />
------=_Part_805_972882936.1439246758708--
------=_Part_804_973806631.1439246758706--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 10 Aug 2015 16:17:39 -0700
Raw View
On Monday 10 August 2015 09:00:02 isocppgroup@denisbider.com wrote:
> T* newArray = T::>>T(newStorage, oldArray, n);
I don't think this should be a built-in function. Instead, the array move
should be an external, template function in the std namespace.
T *newArray = std::relocate(newStorage, oldArray, n);
Internally, it should just DTRT and either:
1) memcpy / memmove if T is trivially movable and trivially destructible
2) memcpy / memmove OR call the relocating constructor for the array
[The effect should be the same, so it's a QoI detail how it's implemented]
3) call the move constructor + destructor
I'd also be ok if #3 weren't implemented and caused a compilation error.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 11 Aug 2015 09:35:11 +0100
Raw View
--089e010d89dafa9359051d04faf5
Content-Type: text/plain; charset=UTF-8
Right; so it's the implementer's responsibility to ensure that all source
subobjects with non-trivial destructor are destructed, either by deferring
to the subobject relocator or by calling the destructor on the subobject.
So we end up writing:
>>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { x.B::~B(); a = this; }
There's a highly compelling reason to allow arbitrary mem-initializers:
reference members. These have to be initialized within the
mem-initializer-list, as they can't be reseated within the body of the
relocator:
struct A { int i; int& r = i; >>A(A& x) : >>i, r(i) {} };
With regard to noexcept, I think this has to be kept; otherwise you have to
be able to rollback the relocation which might not be feasible (e.g. if
pointers elsewhere have already been updated to point to relocated objects
or subobjects); or destruct the source object which would also be very
difficult and would rarely be the desired behavior.
On Mon, Aug 10, 2015 at 11:45 PM, <isocppgroup@denisbider.com> wrote:
> Actually, if we want to give the implementer this much control, there's no
> reason we shouldn't put the burden of calling ~B on the implementer.
>
> I thought this would be a problem if ~B is virtual, but it turns out the
> following is legal:
>
>
>
> *struct* A { *virtual* ~A() { cout << "~A()" << endl; } };
>
> *struct* B : A { *virtual* ~B() { cout << "~B()" << endl; } };
>
> *struct* C : B { *virtual* ~C() { cout << "~C()" << endl; } };
>
>
>
> *void* DestroySubobject(B* b) { b->B::~B(); }
>
>
>
> It turns out, this calls ~A and ~B, but not ~C.
>
> It seems to me it follows: if we allow >>A to initialize the subobjects in
> whatever fashion; including with copy or move construction; then it would
> make sense to expect the author of >>A to call B::~B.
>
>
> On Monday, August 10, 2015 at 4:17:01 PM UTC-6, isocp...@denisbider.com
> wrote:
>
>> However, if there's real desire for the wrapper you show to be legal, a
>> better way to do it would probably be to allow this:
>>
>>
>>
>> >>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { a = this; }
>>
>>
>>
>> But this means we:
>>
>> - say goodbye to the noexcept guarantee;
>>
>> - define the point when ~B is called in the original location -
>> probably when >>A returns;
>>
>> - introduce another type trait, is_nothrow_relocatable
>>
>> I would have preferred to avoid this, but - I guess, if people *really*
>> want to merge move and copy construction into relocation... *(shudder :)*
>>
>>
>> On Monday, August 10, 2015 at 3:59:07 PM UTC-6, isocp...@denisbider.com
>> wrote:
>>
>>> Hmm, good points.
>>>
>>> There are definitely situations where you don't want to mem-initialize a
>>> trivial member, such as in the example:
>>>
>>> >>A(A& x) : >>B(x), >>c(x.c), >>i(x.i)
>>>
>>> { a = *this*; }
>>>
>>> However, one might definitely argue that situations where you want to
>>> mem-initialize a base or a member, but with a non-corresponding member, are
>>> practically nonexistent. So, we may in fact prefer the following:
>>>
>>> >>A(A& x) : >>B, >>c, >>i
>>>
>>> { a = *this*; }
>>>
>>> The relocate_wrapper you suggest I think looks neat, and should be
>>> legal. I don't see a reason why it wouldn't be legal, if the
>>> mem-initializer-list is not implicit.
>>>
>>> It seems to me, intuitively, that there's no reason to make it illegal
>>> to access any data member of the moved-from subobject until the outermost
>>> relocator exits.
>>>
>>> I see no obvious reason why virtual methods shouldn't continue to work,
>>> as well. But this is not to say, of course, that one should call them.
>>>
>>> In general, anything that's const ought to be safe to call. Which is an
>>> argument in favor of making the signature >>T(T const&) - except that would
>>> prevent zeroing out of members.
>>>
>>>
>>> On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wrote:
>>>
>>>> A few queries:
>>>>
>>>> What exactly are the semantics of the mem-initializer-list,
>>>> particularly with regard to omitted, duplicated or misplaced bases/members:
>>>>
>>>> struct A {
>>>> std::string q, r, s;
>>>> >>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
>>>> };
>>>>
>>>> Is it ever legitimate for a mem-initializer to be omitted or to take
>>>> any form other than >>id(x.id) where the two identifiers are
>>>> equivalent? If so, whose responsibility is it to call the destructor on the
>>>> corresponding member of the source object? If not, would it be better to
>>>> omit the mem-initializer-list entirely, as with destructors?
>>>>
>>>> Within the body of the relocator special member function, what are the
>>>> lifetime statuses of the source and destination objects, particularly with
>>>> regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
>>>> members of the source object, or is this undefined behavior as they are
>>>> destructed? If the type is polymorphic, is it permissible to dynamic_cast
>>>> or invoke virtual functions on the source? Indeed, is it permissible to
>>>> invoke any member functions on the source?
>>>>
>>>> In particular, I'd like to make this utility class legal (noting that
>>>> aligned_storage_t is a POD but my utility class is not):
>>>>
>>>> template<class T>
>>>> struct relocate_wrapper {
>>>> template<class... Args> relocate_wrapper(Args&&... args) {
>>>> new (&buf) T(std::forward<Args>(args)...);
>>>> }
>>>> ~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
>>>> >>relocate_wrapper(relocate_wrapper& rhs) {
>>>> new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
>>>> reinterpret_cast<T&>(rhs.buf).~T();
>>>> }
>>>> std::aligned_storage_t<sizeof(T), alignof(T)> buf;
>>>> };
>>>>
>>>> Hm... it might be nice to ensure that the relocator doesn't do any
>>>> unnecessary work copying the buffer that's just going to be placement new
>>>> moved into. Is that an argument against an implicit mem-initializer-list?
>>>>
>>> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.
>
--
---
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/.
--089e010d89dafa9359051d04faf5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Right; so it's the implementer's responsibility to=
ensure that all source subobjects with non-trivial destructor are destruct=
ed, either by deferring to the subobject relocator or by calling the destru=
ctor on the subobject. So we end up writing:<div><br></div><div><p style=3D=
"margin:0in 0in 0pt;background-image:initial;background-repeat:initial"><sp=
an style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt;backg=
round-color:rgb(246,248,255)">=C2=A0=C2=A0>></span><span style=3D"col=
or:rgb(0,0,32);font-family:Consolas;font-size:10pt;background-color:rgb(246=
,248,255)">A</span><span style=3D"color:rgb(48,128,128);font-family:Consola=
s;font-size:10pt;background-color:rgb(246,248,255)">(</span><span style=3D"=
color:rgb(0,0,32);font-family:Consolas;font-size:10pt;background-color:rgb(=
246,248,255)">A</span><span style=3D"color:rgb(48,128,128);font-family:Cons=
olas;font-size:10pt;background-color:rgb(246,248,255)">&</span><span st=
yle=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt;background-col=
or:rgb(246,248,255)">=C2=A0x</span><span style=3D"color:rgb(48,128,128);fon=
t-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">)</span=
><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt;backg=
round-color:rgb(246,248,255)">=C2=A0</span><span style=3D"color:rgb(64,96,1=
28);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">=
:</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10p=
t;background-color:rgb(246,248,255)">=C2=A0B</span><span style=3D"color:rgb=
(48,128,128);font-family:Consolas;font-size:10pt;background-color:rgb(246,2=
48,255)">(</span><span style=3D"color:rgb(0,102,238);font-family:Consolas;f=
ont-size:10pt;background-color:rgb(246,248,255)">std</span><span style=3D"c=
olor:rgb(64,96,128);font-family:Consolas;font-size:10pt;background-color:rg=
b(246,248,255)">::</span><span style=3D"color:rgb(0,0,32);font-family:Conso=
las;font-size:10pt;background-color:rgb(246,248,255)">move</span><span styl=
e=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt;background-c=
olor:rgb(246,248,255)">(</span><span style=3D"color:rgb(0,0,32);font-family=
:Consolas;font-size:10pt;background-color:rgb(246,248,255)">x</span><span s=
tyle=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt;backgroun=
d-color:rgb(246,248,255)">))</span><span style=3D"color:rgb(64,96,128);font=
-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">,</span>=
<span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt;backgr=
ound-color:rgb(246,248,255)">=C2=A0</span><span style=3D"color:rgb(48,128,1=
28);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">=
>></span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-s=
ize:10pt;background-color:rgb(246,248,255)">c</span><span style=3D"color:rg=
b(48,128,128);font-family:Consolas;font-size:10pt;background-color:rgb(246,=
248,255)">(</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;fon=
t-size:10pt;background-color:rgb(246,248,255)">x</span><span style=3D"color=
:rgb(48,128,128);font-family:Consolas;font-size:10pt;background-color:rgb(2=
46,248,255)">.</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;=
font-size:10pt;background-color:rgb(246,248,255)">c</span><span style=3D"co=
lor:rgb(48,128,128);font-family:Consolas;font-size:10pt;background-color:rg=
b(246,248,255)">)</span><span style=3D"color:rgb(64,96,128);font-family:Con=
solas;font-size:10pt;background-color:rgb(246,248,255)">,=C2=A0</span><span=
style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt;backgro=
und-color:rgb(246,248,255)">>></span><span style=3D"color:rgb(0,0,32)=
;font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">i</=
span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10=
pt;background-color:rgb(246,248,255)">(</span><span style=3D"color:rgb(0,0,=
32);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">=
x</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size=
:10pt;background-color:rgb(246,248,255)">.</span><span style=3D"color:rgb(0=
,0,32);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255=
)">i</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-s=
ize:10pt;background-color:rgb(246,248,255)">)</span><span style=3D"color:rg=
b(0,0,32);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,=
255)">=C2=A0</span><span style=3D"color:rgb(64,96,128);font-family:Consolas=
;font-size:10pt;background-color:rgb(246,248,255)">{=C2=A0</span><span styl=
e=3D"font-family:Consolas;font-size:10pt;background-color:rgb(255,255,0)"><=
font color=3D"#000000">x.B::~B();</font></span><span style=3D"color:rgb(64,=
96,128);font-family:Consolas;font-size:10pt;background-color:rgb(246,248,25=
5)">=C2=A0</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font=
-size:10pt;background-color:rgb(246,248,255)">a=C2=A0</span><span style=3D"=
color:rgb(48,128,128);font-family:Consolas;font-size:10pt;background-color:=
rgb(246,248,255)">=3D</span><span style=3D"color:rgb(0,0,32);font-family:Co=
nsolas;font-size:10pt;background-color:rgb(246,248,255)">=C2=A0</span><span=
style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt;backgro=
und-color:rgb(246,248,255)">this</span><span style=3D"color:rgb(64,96,128);=
font-family:Consolas;font-size:10pt;background-color:rgb(246,248,255)">; }<=
/span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3"></fon=
t><div><br></div><div>There's a highly compelling reason to allow arbit=
rary mem-initializers: reference members. These have to be initialized with=
in the mem-initializer-list, as they can't be reseated within the body =
of the relocator:</div><div><br></div></div><blockquote style=3D"margin:0 0=
0 40px;border:none;padding:0px"><div><div><font face=3D"monospace, monospa=
ce">struct A { int i; <span style=3D"background-color:rgb(255,255,0)">int&a=
mp; r =3D i;</span> >>A(A& x) : >>i, <span style=3D"backgro=
und-color:rgb(255,255,0)">r(i)</span> {} };</font></div></div></blockquote>=
<div><div><br></div><div>With regard to noexcept, I think this has to be ke=
pt; otherwise you have to be able to rollback the relocation which might no=
t be feasible (e.g. if pointers elsewhere have already been updated to poin=
t to relocated objects or subobjects); or destruct the source object which =
would also be very difficult and would rarely be the desired behavior.</div=
><div><br></div><div>On Mon, Aug 10, 2015 at 11:45 PM, <span dir=3D"ltr">&=
lt;<a href=3D"mailto:isocppgroup@denisbider.com" target=3D"_blank">isocppgr=
oup@denisbider.com</a>></span> wrote:<br></div><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div>Actually, if we want to give the implementer this much control, ther=
e's no reason we shouldn't put the burden of calling ~B on the impl=
ementer.</div><div><br></div><div>I thought this would be a problem if ~B i=
s virtual, but it turns out the following is legal:</div><div><br></div><di=
v><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt">=C2=A0</span></p><font color=3D"#000000" face=3D"Times New Roman" siz=
e=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><b><span style=3D"color:rgb(32,0,128);font-family:Consolas;font-=
size:10pt">struct</span></b><span style=3D"color:rgb(0,0,32);font-family:Co=
nsolas;font-size:10pt"> A<span>=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span=
style=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">{</span=
><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </s=
pan><b><span style=3D"color:rgb(32,0,128);font-family:Consolas;font-size:10=
pt">virtual</span></b><span style=3D"color:rgb(0,0,32);font-family:Consolas=
;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128);font-family:C=
onsolas;font-size:10pt">~</span><span style=3D"color:rgb(0,0,32);font-famil=
y:Consolas;font-size:10pt">A</span><span style=3D"color:rgb(48,128,128);fon=
t-family:Consolas;font-size:10pt">()</span><span style=3D"color:rgb(0,0,32)=
;font-family:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(64,9=
6,128);font-family:Consolas;font-size:10pt">{</span><span style=3D"color:rg=
b(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D"color=
:rgb(0,48,96);font-family:Consolas;font-size:10pt">cout</span><span style=
=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span st=
yle=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt"><<<=
/span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"=
> </span><span style=3D"color:maroon;font-family:Consolas;font-size:10pt">&=
quot;</span><span style=3D"color:rgb(16,96,182);font-family:Consolas;font-s=
ize:10pt">~A()</span><span style=3D"color:maroon;font-family:Consolas;font-=
size:10pt">"</span><span style=3D"color:rgb(0,0,32);font-family:Consol=
as;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128);font-family=
:Consolas;font-size:10pt"><<</span><span style=3D"color:rgb(0,0,32);f=
ont-family:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(0,48,9=
6);font-family:Consolas;font-size:10pt">endl</span><span style=3D"color:rgb=
(64,96,128);font-family:Consolas;font-size:10pt">;</span><span style=3D"col=
or:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D"=
color:rgb(64,96,128);font-family:Consolas;font-size:10pt">}</span><span sty=
le=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span =
style=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">};</span=
></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><b><span style=3D"color:rgb(32,0,128);font-family:Consolas;font-=
size:10pt">struct</span></b><span style=3D"color:rgb(0,0,32);font-family:Co=
nsolas;font-size:10pt"> B </span><span style=3D"color:rgb(64,96,128);font-f=
amily:Consolas;font-size:10pt">:</span><span style=3D"color:rgb(0,0,32);fon=
t-family:Consolas;font-size:10pt"> A </span><span style=3D"color:rgb(64,96,=
128);font-family:Consolas;font-size:10pt">{</span><span style=3D"color:rgb(=
0,0,32);font-family:Consolas;font-size:10pt"> </span><b><span style=3D"colo=
r:rgb(32,0,128);font-family:Consolas;font-size:10pt">virtual</span></b><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">~<=
/span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"=
>B</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-siz=
e:10pt">()</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font=
-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-family:Consola=
s;font-size:10pt">{</span><span style=3D"color:rgb(0,0,32);font-family:Cons=
olas;font-size:10pt"> </span><span style=3D"color:rgb(0,48,96);font-family:=
Consolas;font-size:10pt">cout</span><span style=3D"color:rgb(0,0,32);font-f=
amily:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128)=
;font-family:Consolas;font-size:10pt"><<</span><span style=3D"color:r=
gb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D"colo=
r:maroon;font-family:Consolas;font-size:10pt">"</span><span style=3D"c=
olor:rgb(16,96,182);font-family:Consolas;font-size:10pt">~B()</span><span s=
tyle=3D"color:maroon;font-family:Consolas;font-size:10pt">"</span><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">&l=
t;<</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-siz=
e:10pt"> </span><span style=3D"color:rgb(0,48,96);font-family:Consolas;font=
-size:10pt">endl</span><span style=3D"color:rgb(64,96,128);font-family:Cons=
olas;font-size:10pt">;</span><span style=3D"color:rgb(0,0,32);font-family:C=
onsolas;font-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-fa=
mily:Consolas;font-size:10pt">}</span><span style=3D"color:rgb(0,0,32);font=
-family:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(64,96,128=
);font-family:Consolas;font-size:10pt">};</span></p><font color=3D"#000000"=
face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><b><span style=3D"color:rgb(32,0,128);font-family:Consolas;font-=
size:10pt">struct</span></b><span style=3D"color:rgb(0,0,32);font-family:Co=
nsolas;font-size:10pt"> C </span><span style=3D"color:rgb(64,96,128);font-f=
amily:Consolas;font-size:10pt">:</span><span style=3D"color:rgb(0,0,32);fon=
t-family:Consolas;font-size:10pt"> B </span><span style=3D"color:rgb(64,96,=
128);font-family:Consolas;font-size:10pt">{</span><span style=3D"color:rgb(=
0,0,32);font-family:Consolas;font-size:10pt"> </span><b><span style=3D"colo=
r:rgb(32,0,128);font-family:Consolas;font-size:10pt">virtual</span></b><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">~<=
/span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"=
>C</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-siz=
e:10pt">()</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font=
-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-family:Consola=
s;font-size:10pt">{</span><span style=3D"color:rgb(0,0,32);font-family:Cons=
olas;font-size:10pt"> </span><span style=3D"color:rgb(0,48,96);font-family:=
Consolas;font-size:10pt">cout</span><span style=3D"color:rgb(0,0,32);font-f=
amily:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128)=
;font-family:Consolas;font-size:10pt"><<</span><span style=3D"color:r=
gb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D"colo=
r:maroon;font-family:Consolas;font-size:10pt">"</span><span style=3D"c=
olor:rgb(16,96,182);font-family:Consolas;font-size:10pt">~C()</span><span s=
tyle=3D"color:maroon;font-family:Consolas;font-size:10pt">"</span><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">&l=
t;<</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-siz=
e:10pt"> </span><span style=3D"color:rgb(0,48,96);font-family:Consolas;font=
-size:10pt">endl</span><span style=3D"color:rgb(64,96,128);font-family:Cons=
olas;font-size:10pt">;</span><span style=3D"color:rgb(0,0,32);font-family:C=
onsolas;font-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-fa=
mily:Consolas;font-size:10pt">}</span><span style=3D"color:rgb(0,0,32);font=
-family:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(64,96,128=
);font-family:Consolas;font-size:10pt">};</span></p><font color=3D"#000000"=
face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt">=C2=A0</span></p><font color=3D"#000000" face=3D"Times New Roman" siz=
e=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><b><span style=3D"color:rgb(32,0,128);font-family:Consolas;font-=
size:10pt">void</span></b><span style=3D"color:rgb(0,0,32);font-family:Cons=
olas;font-size:10pt"> DestroySubobject</span><span style=3D"color:rgb(48,12=
8,128);font-family:Consolas;font-size:10pt">(</span><span style=3D"color:rg=
b(0,0,32);font-family:Consolas;font-size:10pt">B</span><span style=3D"color=
:rgb(48,128,128);font-family:Consolas;font-size:10pt">*</span><span style=
=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> b</span><span s=
tyle=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">)</span>=
<span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </sp=
an><span style=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt"=
>{</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10=
pt"> b</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font=
-size:10pt">-></span><span style=3D"color:rgb(0,0,32);font-family:Consol=
as;font-size:10pt">B</span><span style=3D"color:rgb(64,96,128);font-family:=
Consolas;font-size:10pt">::</span><span style=3D"color:rgb(48,128,128);font=
-family:Consolas;font-size:10pt">~</span><span style=3D"color:rgb(0,0,32);f=
ont-family:Consolas;font-size:10pt">B</span><span style=3D"color:rgb(48,128=
,128);font-family:Consolas;font-size:10pt">()</span><span style=3D"color:rg=
b(64,96,128);font-family:Consolas;font-size:10pt">;</span><span style=3D"co=
lor:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D=
"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">}</span></p><fon=
t color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt">=C2=A0</span></p><font color=3D"#000000" face=3D"Times New Roman" siz=
e=3D"3">
</font></div><div><br></div><div>It turns out, this calls ~A and ~B, but no=
t ~C.</div><div><br></div><div>It seems to me it follows:=C2=A0if we allow =
>>A to initialize the subobjects in whatever fashion; including with =
copy or move construction; then it would make sense to expect the author of=
>>A to call B::~B.</div><div><div class=3D"h5"><div><br><br>On Monda=
y, August 10, 2015 at 4:17:01 PM UTC-6, <a href=3D"mailto:isocp...@denisbid=
er.com" target=3D"_blank">isocp...@denisbider.com</a> wrote:</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex=
;border-left-color:rgb(204,204,204);border-left-width:1px;border-left-style=
:solid"><div dir=3D"ltr"><div>However,=C2=A0if there's real desire for =
the wrapper you show to be legal, a better way to do it would probably be t=
o allow this:</div><div><br></div><div><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"font-family:Consolas;font-size:10pt"><font color=
=3D"#000000">=C2=A0</font></span></p><font color=3D"#000000" face=3D"Times =
New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-s=
ize:10pt"><span>=C2=A0 </span>>></span><span style=3D"color:rgb(0,0,3=
2);font-family:Consolas;font-size:10pt">A</span><span style=3D"color:rgb(48=
,128,128);font-family:Consolas;font-size:10pt">(</span><span style=3D"color=
:rgb(0,0,32);font-family:Consolas;font-size:10pt">A</span><span style=3D"co=
lor:rgb(48,128,128);font-family:Consolas;font-size:10pt">&</span><span =
style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> x</span><s=
pan style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">)</=
span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">=
</span><span style=3D"color:rgb(64,96,128);font-family:Consolas;font-size:=
10pt">:</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-si=
ze:10pt"> B</span><span style=3D"color:rgb(48,128,128);font-family:Consolas=
;font-size:10pt">(</span><span style=3D"color:rgb(0,102,238);font-family:Co=
nsolas;font-size:10pt">std</span><span style=3D"color:rgb(64,96,128);font-f=
amily:Consolas;font-size:10pt">::</span><span style=3D"color:rgb(0,0,32);fo=
nt-family:Consolas;font-size:10pt">move</span><span style=3D"color:rgb(48,1=
28,128);font-family:Consolas;font-size:10pt">(</span><span style=3D"color:r=
gb(0,0,32);font-family:Consolas;font-size:10pt">x</span><span style=3D"colo=
r:rgb(48,128,128);font-family:Consolas;font-size:10pt">))</span><span style=
=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">,</span><span=
style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><s=
pan style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">>=
;></span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size=
:10pt">c</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;fo=
nt-size:10pt">(</span><span style=3D"color:rgb(0,0,32);font-family:Consolas=
;font-size:10pt">x</span><span style=3D"color:rgb(48,128,128);font-family:C=
onsolas;font-size:10pt">.</span><span style=3D"color:rgb(0,0,32);font-famil=
y:Consolas;font-size:10pt">c</span><span style=3D"color:rgb(48,128,128);fon=
t-family:Consolas;font-size:10pt">)</span><span style=3D"color:rgb(64,96,12=
8);font-family:Consolas;font-size:10pt">, </span><span style=3D"color:rgb(4=
8,128,128);font-family:Consolas;font-size:10pt">>></span><span style=
=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">i</span><span st=
yle=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">(</span><=
span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">x</spa=
n><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt"=
>.</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10=
pt">i</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-=
size:10pt">)</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;fo=
nt-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-family:Conso=
las;font-size:10pt">{ </span><span style=3D"color:rgb(0,0,32);font-family:C=
onsolas;font-size:10pt">a </span><span style=3D"color:rgb(48,128,128);font-=
family:Consolas;font-size:10pt">=3D</span><span style=3D"color:rgb(0,0,32);=
font-family:Consolas;font-size:10pt"> </span><span style=3D"color:rgb(48,12=
8,128);font-family:Consolas;font-size:10pt">this</span><span style=3D"color=
:rgb(64,96,128);font-family:Consolas;font-size:10pt">; }</span></p><font co=
lor=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt">=C2=A0</span></p><font color=3D"#000000" face=3D"Times New Roman" siz=
e=3D"3">
</font></div><div><br></div><div>But this means we:</div><div><br></div><di=
v>- say goodbye to the noexcept guarantee;</div><div><br></div><div>- defin=
e the point when=C2=A0~B is called=C2=A0in the original location - probably=
=C2=A0when >>A returns;</div><div><br></div><div>- introduce another =
type trait, <font face=3D"courier new,monospace">is_nothrow_relocatable</fo=
nt></div><div><br></div><div>I would have preferred to avoid this, but - I =
guess, if people <em>really</em> want to merge move and copy=C2=A0construct=
ion into relocation... <em>(shudder :)</em></div><div><br></div><div><br>On=
Monday, August 10, 2015 at 3:59:07 PM UTC-6, <a>isocp...@denisbider.com</a=
> wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-widt=
h:1px;border-left-style:solid"><div dir=3D"ltr"><div>Hmm, good points.</div=
><div><br></div><div>There are definitely situations where you don't wa=
nt to mem-initialize a trivial member, such as in the example:</div><div><b=
r></div><div><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"color:rgb(48,12=
8,128);font-family:Consolas;font-size:10pt">>></span><span style=3D"c=
olor:rgb(0,0,32);font-family:Consolas;font-size:10pt">A</span><span style=
=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">(</span><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">A</span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">&a=
mp;</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:1=
0pt"> x</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;fon=
t-size:10pt">)</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;=
font-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-family:Con=
solas;font-size:10pt">:</span><span style=3D"color:rgb(0,0,32);font-family:=
Consolas;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128);font-=
family:Consolas;font-size:10pt">>></span><span style=3D"color:rgb(0,0=
,32);font-family:Consolas;font-size:10pt">B</span><span style=3D"color:rgb(=
48,128,128);font-family:Consolas;font-size:10pt">(</span><span style=3D"col=
or:rgb(0,0,32);font-family:Consolas;font-size:10pt">x</span><span style=3D"=
color:rgb(48,128,128);font-family:Consolas;font-size:10pt">)</span><span st=
yle=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">,</span><s=
pan style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span=
><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">=
>></span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-s=
ize:10pt">c</span><span style=3D"color:rgb(48,128,128);font-family:Consolas=
;font-size:10pt">(</span><span style=3D"color:rgb(0,0,32);font-family:Conso=
las;font-size:10pt">x</span><span style=3D"color:rgb(48,128,128);font-famil=
y:Consolas;font-size:10pt">.</span><span style=3D"color:rgb(0,0,32);font-fa=
mily:Consolas;font-size:10pt">c</span><span style=3D"color:rgb(48,128,128);=
font-family:Consolas;font-size:10pt">)</span><span style=3D"color:rgb(64,96=
,128);font-family:Consolas;font-size:10pt">, </span><span style=3D"color:rg=
b(48,128,128);font-family:Consolas;font-size:10pt">>></span><span sty=
le=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">i</span><span =
style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">(</span=
><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">x</s=
pan><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10p=
t">.</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt">i</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;fon=
t-size:10pt">)</span></p><font color=3D"#000000" face=3D"Times New Roman" s=
ize=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"col=
or:rgb(64,96,128);font-family:Consolas;font-size:10pt">{
</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt=
">a </span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-s=
ize:10pt">=3D</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;f=
ont-size:10pt"> </span><b><span style=3D"color:rgb(32,0,128);font-family:Co=
nsolas;font-size:10pt">this</span></b><span style=3D"color:rgb(64,96,128);f=
ont-family:Consolas;font-size:10pt">; }</span></p><font color=3D"#000000" f=
ace=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>However, one might definitely argue that s=
ituations where you want to mem-initialize a base or a member, but with a n=
on-corresponding member,=C2=A0are practically nonexistent. So, we may in fa=
ct=C2=A0prefer the following:</div><div><br></div><div><font color=3D"#0000=
00" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"color:rgb(48,12=
8,128);font-family:Consolas;font-size:10pt">>></span><span style=3D"c=
olor:rgb(0,0,32);font-family:Consolas;font-size:10pt">A</span><span style=
=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">(</span><spa=
n style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">A</span><=
span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size:10pt">&a=
mp;</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:1=
0pt"> x</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;fon=
t-size:10pt">)</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;=
font-size:10pt"> </span><span style=3D"color:rgb(64,96,128);font-family:Con=
solas;font-size:10pt">:</span><span style=3D"color:rgb(0,0,32);font-family:=
Consolas;font-size:10pt"> </span><span style=3D"color:rgb(48,128,128);font-=
family:Consolas;font-size:10pt">>></span><span style=3D"color:rgb(0,0=
,32);font-family:Consolas;font-size:10pt">B</span><span style=3D"color:rgb(=
64,96,128);font-family:Consolas;font-size:10pt">,</span><span style=3D"colo=
r:rgb(0,0,32);font-family:Consolas;font-size:10pt"> </span><span style=3D"c=
olor:rgb(48,128,128);font-family:Consolas;font-size:10pt">>></span><s=
pan style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt">c</span=
><span style=3D"color:rgb(64,96,128);font-family:Consolas;font-size:10pt">,=
</span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-size=
:10pt">>></span><span style=3D"color:rgb(0,0,32);font-family:Consolas=
;font-size:10pt">i</span></p><font color=3D"#000000" face=3D"Times New Roma=
n" size=3D"3">
</font><p style=3D"background:rgb(246,248,255);margin:0in 0in 0pt;line-heig=
ht:normal"><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:=
10pt"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><span style=3D"col=
or:rgb(64,96,128);font-family:Consolas;font-size:10pt">{
</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;font-size:10pt=
">a </span><span style=3D"color:rgb(48,128,128);font-family:Consolas;font-s=
ize:10pt">=3D</span><span style=3D"color:rgb(0,0,32);font-family:Consolas;f=
ont-size:10pt"> </span><b><span style=3D"color:rgb(32,0,128);font-family:Co=
nsolas;font-size:10pt">this</span></b><span style=3D"color:rgb(64,96,128);f=
ont-family:Consolas;font-size:10pt">; }</span></p><font color=3D"#000000" f=
ace=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>The relocate_wrapper you suggest I think l=
ooks neat, and should be legal. I don't see a reason why it wouldn'=
t be legal, if the mem-initializer-list is not implicit.</div><div><br></di=
v><div>It seems to me,=C2=A0intuitively,=C2=A0that there's no reason to=
make it illegal to access any data member of the moved-from subobject unti=
l the outermost relocator exits.</div><div><br></div><div>I see no obvious =
reason why virtual methods shouldn't continue to work, as well. But thi=
s is not to say, of course, that one should call them.</div><div><br></div>=
<div>In general, anything that's const ought to be safe to call. Which =
is an argument in favor of making the signature >>T(T const&) -=
=C2=A0except that would prevent zeroing out of members.</div><div><br></div=
><div><br>On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wro=
te:</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px=
;border-left-style:solid"><div dir=3D"ltr"><div>A few queries:</div><div><b=
r></div><div>What exactly are the semantics of the mem-initializer-list, pa=
rticularly with regard to omitted, duplicated or misplaced bases/members:<b=
r></div><div><br></div><div style=3D"border:1px solid rgb(187,187,187);back=
ground-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)=
">struct</span><span style=3D"color:rgb(0,0,0)"> A </span><span style=3D"co=
lor:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=
=A0 std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"=
color:rgb(0,0,136)">string</span><span style=3D"color:rgb(0,0,0)"> q</span>=
<span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0=
)"> r</span><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"col=
or:rgb(0,0,0)"> s</span><span style=3D"color:rgb(102,102,0)">;</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rg=
b(102,102,0)">>></span><span style=3D"color:rgb(0,0,0)">A</span><span=
style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">A<=
/span><span style=3D"color:rgb(102,102,0)">&</span><span style=3D"color=
:rgb(0,0,0)"> x</span><span style=3D"color:rgb(102,102,0)">)</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">:</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,10=
2,0)">>></span><span style=3D"color:rgb(0,0,0)">r</span><span style=
=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">x</span>=
<span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,0=
)">r</span><span style=3D"color:rgb(102,102,0)">),</span><span style=3D"col=
or:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">>></span>=
<span style=3D"color:rgb(0,0,0)">s</span><span style=3D"color:rgb(102,102,0=
)">(</span><span style=3D"color:rgb(0,0,0)">x</span><span style=3D"color:rg=
b(102,102,0)">.</span><span style=3D"color:rgb(0,0,0)">r</span><span style=
=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(136,0,0)">/* oops */</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span>=
<span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,10=
2,0)">};</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code></d=
iv><div><br></div><div>Is it ever legitimate for a mem-initializer to be om=
itted or to take any form other than <font face=3D"courier new, monospace">=
>>id(<a href=3D"http://x.id" rel=3D"nofollow" target=3D"_blank">x.id<=
/a>)</font> where the two identifiers are equivalent? If so, whose responsi=
bility is it to call the destructor on the corresponding member of the sour=
ce object? If not, would it be better to omit the mem-initializer-list enti=
rely, as with destructors?</div><div><br></div><div>Within the body of the =
relocator special member function, what are the lifetime statuses of the so=
urce and destination objects, particularly with regard to [class.cdtor]? Is=
it permissible to form lvalues to the bases and members of the source obje=
ct, or is this undefined behavior as they are destructed? If the type is po=
lymorphic, is it permissible to dynamic_cast or invoke virtual functions on=
the source? Indeed, is it permissible to invoke any member functions on th=
e source?</div><div><br></div><div>In particular, I'd like to make this=
utility class legal (noting that aligned_storage_t is a POD but my utility=
class is not):</div><div><br></div><div><div style=3D"border:1px solid rgb=
(187,187,187);background-color:rgb(250,250,250)"><code><div><span style=3D"=
color:rgb(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)"><=
;</span><span style=3D"color:rgb(0,0,136)">class</span><span style=3D"color=
:rgb(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">></span><span=
style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)">s=
truct</span><span style=3D"color:rgb(0,0,0)"> relocate_wrapper </span><span=
style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><b=
r>=C2=A0 </span><span style=3D"color:rgb(0,0,136)">template</span><span sty=
le=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(0,0,136)">c=
lass</span><span style=3D"color:rgb(102,102,0)">...</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">Args</span><sp=
an style=3D"color:rgb(102,102,0)">></span><span style=3D"color:rgb(0,0,0=
)"> relocate_wrapper</span><span style=3D"color:rgb(102,102,0)">(</span><sp=
an style=3D"color:rgb(102,0,102)">Args</span><span style=3D"color:rgb(102,1=
02,0)">&&...</span><span style=3D"color:rgb(0,0,0)"> args</span><sp=
an style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)">=
</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:r=
gb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">new<=
/span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102=
,102,0)">(&</span><span style=3D"color:rgb(0,0,0)">buf</span><span styl=
e=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> T</spa=
n><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0=
,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D=
"color:rgb(0,0,0)">forward</span><span style=3D"color:rgb(102,102,0)"><<=
/span><span style=3D"color:rgb(102,0,102)">Args</span><span style=3D"color:=
rgb(102,102,0)">>(</span><span style=3D"color:rgb(0,0,0)">args</span><sp=
an style=3D"color:rgb(102,102,0)">)...);</span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 </span><span style=3D"color:rgb(102,102,0)">}</span><span s=
tyle=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(102,10=
2,0)">~</span><span style=3D"color:rgb(0,0,0)">relocate_wrapper</span><span=
style=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">reinterpret_cast</span=
><span style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(0=
,0,0)">T</span><span style=3D"color:rgb(102,102,0)">&>(</span><span =
style=3D"color:rgb(0,0,0)">buf</span><span style=3D"color:rgb(102,102,0)">)=
..~</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb(=
102,102,0)">();</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=
=A0 </span><span style=3D"color:rgb(102,102,0)">>></span><span style=
=3D"color:rgb(0,0,0)">relocate_wrapper</span><span style=3D"color:rgb(102,1=
02,0)">(</span><span style=3D"color:rgb(0,0,0)">relocate_wrapper</span><spa=
n style=3D"color:rgb(102,102,0)">&</span><span style=3D"color:rgb(0,0,0=
)"> rhs</span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"c=
olor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span=
style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:r=
gb(0,0,136)">new</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">(&</span><span style=3D"color:rgb(0,0,0)">buf=
</span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rg=
b(0,0,0)"> T</span><span style=3D"color:rgb(102,102,0)">(</span><span style=
=3D"color:rgb(0,0,136)">reinterpret_cast</span><span style=3D"color:rgb(102=
,102,0)"><</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D=
"color:rgb(102,102,0)">&&>(</span><span style=3D"color:rgb(0,0,0=
)">rhs</span><span style=3D"color:rgb(102,102,0)">.</span><span style=3D"co=
lor:rgb(0,0,0)">buf</span><span style=3D"color:rgb(102,102,0)">));</span><s=
pan style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r:rgb(0,0,136)">reinterpret_cast</span><span style=3D"color:rgb(102,102,0)"=
><</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:r=
gb(102,102,0)">&>(</span><span style=3D"color:rgb(0,0,0)">rhs</span>=
<span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,0=
)">buf</span><span style=3D"color:rgb(102,102,0)">).~</span><span style=3D"=
color:rgb(0,0,0)">T</span><span style=3D"color:rgb(102,102,0)">();</span><s=
pan style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(1=
02,102,0)">}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 std</span><s=
pan style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)=
">aligned_storage_t</span><span style=3D"color:rgb(102,102,0)"><</span><=
span style=3D"color:rgb(0,0,136)">sizeof</span><span style=3D"color:rgb(102=
,102,0)">(</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"co=
lor:rgb(102,102,0)">),</span><span style=3D"color:rgb(0,0,0)"> </span><span=
style=3D"color:rgb(0,0,136)">alignof</span><span style=3D"color:rgb(102,10=
2,0)">(</span><span style=3D"color:rgb(0,0,0)">T</span><span style=3D"color=
:rgb(102,102,0)">)></span><span style=3D"color:rgb(0,0,0)"> buf</span><s=
pan style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"=
><br></span><span style=3D"color:rgb(102,102,0)">};</span></div></code></di=
v><div><br></div></div><div>Hm... it might be nice to ensure that the reloc=
ator doesn't do any unnecessary work copying the buffer that's just=
going to be placement new moved into. Is that an argument against an impli=
cit mem-initializer-list?</div></div></blockquote></div></blockquote></div>=
</blockquote></div></div></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--089e010d89dafa9359051d04faf5--
.
Author: isocppgroup@denisbider.com
Date: Tue, 11 Aug 2015 04:05:56 -0700 (PDT)
Raw View
------=_Part_242_928082258.1439291156908
Content-Type: multipart/alternative;
boundary="----=_Part_243_344741560.1439291156908"
------=_Part_243_344741560.1439291156908
Content-Type: text/plain; charset=UTF-8
You're probably right. I was thinking a static T::>>T could be an anchor
for static analysis tools; but I see no reason an std::relocate cannot also
serve this purpose.
I have modified the proposal to make the wrapper a library function.
I still believe each facility should do one thing, so I do not propose
bundling of copy/move construction into std::relocate. I propose that this
be implemented by expanding std::move_if_noexcept, or an alternative such
method.
On Monday, August 10, 2015 at 5:17:46 PM UTC-6, Thiago Macieira wrote:
> On Monday 10 August 2015 09:00:02 isocp...@denisbider.com <javascript:>
> wrote:
> > T* newArray = T::>>T(newStorage, oldArray, n);
>
> I don't think this should be a built-in function. Instead, the array move
> should be an external, template function in the std namespace.
>
> T *newArray = std::relocate(newStorage, oldArray, n);
>
> Internally, it should just DTRT and either:
> 1) memcpy / memmove if T is trivially movable and trivially destructible
> 2) memcpy / memmove OR call the relocating constructor for the array
> [The effect should be the same, so it's a QoI detail how it's
> implemented]
> 3) call the move constructor + destructor
>
> I'd also be ok if #3 weren't implemented and caused a compilation error.
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_243_344741560.1439291156908
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>You're probably right. I was thinking=C2=A0a=C2=
=A0static T::>>T could be an=C2=A0anchor for static analysis tools; b=
ut=C2=A0I see=C2=A0no reason an=C2=A0<font face=3D"courier new,monospace">s=
td::relocate</font> cannot also serve this purpose.</div><div><br></div><di=
v>I have modified the proposal to make the wrapper a library function.</div=
><div><br></div><div>I still believe each facility should do one thing, so =
I do not propose bundling of copy/move construction=C2=A0into <font face=3D=
"courier new,monospace">std::relocate</font>. I propose that this be implem=
ented by expanding <font face=3D"courier new,monospace">std::move_if_noexce=
pt</font>, or an alternative such method.</div><div><br><br>On Monday, Augu=
st 10, 2015 at 5:17:46 PM UTC-6, Thiago Macieira wrote:</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; =
border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-=
style: solid;">On Monday 10 August 2015 09:00:02 <a onmousedown=3D"this.hre=
f=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofol=
low" gdf-obfuscated-mailto=3D"Kz1IW4aMAQAJ">isocp...@denisbider.com</a> wro=
te:
<br>> T* newArray =3D T::>>T(newStorage, oldArray, n);
<br>
<br>I don't think this should be a built-in function. Instead, the arra=
y move=20
<br>should be an external, template function in the std namespace.
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0T *newArray =3D std::re=
locate(newStorage, oldArray, n);
<br>
<br>Internally, it should just DTRT and either:
<br>=C2=A01) memcpy / memmove if T is trivially movable and trivially destr=
uctible
<br>=C2=A02) memcpy / memmove OR call the relocating constructor for the ar=
ray
<br>=C2=A0 =C2=A0 [The effect should be the same, so it's a QoI detail =
how it's implemented]
<br>=C2=A03) call the move constructor + destructor
<br>
<br>I'd also be ok if #3 weren't implemented and caused a compilati=
on error.
<br>--=20
<br>Thiago Macieira - thiago (AT) <a onmousedown=3D"this.href=3D'http:/=
/www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\7=
5D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag';return true;=
" href=3D"http://macieira.info" target=3D"_blank" rel=3D"nofollow">macieira=
..info</a> - thiago (AT) <a onmousedown=3D"this.href=3D'http://www.googl=
e.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJd=
o5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'http=
://www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;" href=3D"http://kde.o=
rg" target=3D"_blank" rel=3D"nofollow">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
5358
<br>
<br></blockquote></div>
<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 />
------=_Part_243_344741560.1439291156908--
------=_Part_242_928082258.1439291156908--
.
Author: isocppgroup@denisbider.com
Date: Tue, 11 Aug 2015 04:09:12 -0700 (PDT)
Raw View
------=_Part_5352_1274161025.1439291352695
Content-Type: multipart/alternative;
boundary="----=_Part_5353_81014760.1439291352696"
------=_Part_5353_81014760.1439291352696
Content-Type: text/plain; charset=UTF-8
You're right. I have updated the proposal as follows:
http://denisbider.com/Relocator.pdf
The latest versions now also include an Annex discussing the need for
in-place reallocation, as pointed out by Vitali Lovich.
On Tuesday, August 11, 2015 at 2:35:15 AM UTC-6, Edward Catmur wrote:
> Right; so it's the implementer's responsibility to ensure that all source
> subobjects with non-trivial destructor are destructed, either by deferring
> to the subobject relocator or by calling the destructor on the subobject.
> So we end up writing:
>
> >>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { x.B::~B(); a = this; }
>
> There's a highly compelling reason to allow arbitrary mem-initializers:
> reference members. These have to be initialized within the
> mem-initializer-list, as they can't be reseated within the body of the
> relocator:
>
> struct A { int i; int& r = i; >>A(A& x) : >>i, r(i) {} };
>
>
> With regard to noexcept, I think this has to be kept; otherwise you have
> to be able to rollback the relocation which might not be feasible (e.g. if
> pointers elsewhere have already been updated to point to relocated objects
> or subobjects); or destruct the source object which would also be very
> difficult and would rarely be the desired behavior.
>
> On Mon, Aug 10, 2015 at 11:45 PM, <isocp...@denisbider.com <javascript:>>
> wrote:
>
> Actually, if we want to give the implementer this much control, there's no
> reason we shouldn't put the burden of calling ~B on the implementer.
>
> I thought this would be a problem if ~B is virtual, but it turns out the
> following is legal:
>
>
>
> *struct* A { *virtual* ~A() { cout << "~A()" << endl; } };
>
> *struct* B : A { *virtual* ~B() { cout << "~B()" << endl; } };
>
> *struct* C : B { *virtual* ~C() { cout << "~C()" << endl; } };
>
>
>
> *void* DestroySubobject(B* b) { b->B::~B(); }
>
>
>
> It turns out, this calls ~A and ~B, but not ~C.
>
> It seems to me it follows: if we allow >>A to initialize the subobjects in
> whatever fashion; including with copy or move construction; then it would
> make sense to expect the author of >>A to call B::~B.
>
>
> On Monday, August 10, 2015 at 4:17:01 PM UTC-6, isocp...@denisbider.com
> wrote:
>
> However, if there's real desire for the wrapper you show to be legal, a
> better way to do it would probably be to allow this:
>
>
>
> >>A(A& x) : B(std::move(x)), >>c(x.c), >>i(x.i) { a = this; }
>
>
>
> But this means we:
>
> - say goodbye to the noexcept guarantee;
>
> - define the point when ~B is called in the original location -
> probably when >>A returns;
>
> - introduce another type trait, is_nothrow_relocatable
>
> I would have preferred to avoid this, but - I guess, if people *really*
> want to merge move and copy construction into relocation... *(shudder :)*
>
>
> On Monday, August 10, 2015 at 3:59:07 PM UTC-6, isocp...@denisbider.com
> wrote:
>
> Hmm, good points.
>
> There are definitely situations where you don't want to mem-initialize a
> trivial member, such as in the example:
>
> >>A(A& x) : >>B(x), >>c(x.c), >>i(x.i)
>
> { a = *this*; }
>
> However, one might definitely argue that situations where you want to
> mem-initialize a base or a member, but with a non-corresponding member, are
> practically nonexistent. So, we may in fact prefer the following:
>
> >>A(A& x) : >>B, >>c, >>i
>
> { a = *this*; }
>
> The relocate_wrapper you suggest I think looks neat, and should be legal.
> I don't see a reason why it wouldn't be legal, if the mem-initializer-list
> is not implicit.
>
> It seems to me, intuitively, that there's no reason to make it illegal to
> access any data member of the moved-from subobject until the outermost
> relocator exits.
>
> I see no obvious reason why virtual methods shouldn't continue to work, as
> well. But this is not to say, of course, that one should call them.
>
> In general, anything that's const ought to be safe to call. Which is an
> argument in favor of making the signature >>T(T const&) - except that would
> prevent zeroing out of members.
>
>
> On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wrote:
>
> A few queries:
>
> What exactly are the semantics of the mem-initializer-list, particularly
> with regard to omitted, duplicated or misplaced bases/members:
>
> struct A {
> std::string q, r, s;
> >>A(A& x) : >>r(x.r), >>s(x.r) { /* oops */ }
> };
>
> Is it ever legitimate for a mem-initializer to be omitted or to take any
> form other than >>id(x.id) where the two identifiers are equivalent? If
> so, whose responsibility is it to call the destructor on the corresponding
> member of the source object? If not, would it be better to omit the
> mem-initializer-list entirely, as with destructors?
>
> Within the body of the relocator special member function, what are the
> lifetime statuses of the source and destination objects, particularly with
> regard to [class.cdtor]? Is it permissible to form lvalues to the bases and
> members of the source object, or is this undefined behavior as they are
> destructed? If the type is polymorphic, is it permissible to dynamic_cast
> or invoke virtual functions on the source? Indeed, is it permissible to
> invoke any member functions on the source?
>
> In particular, I'd like to make this utility class legal (noting that
> aligned_storage_t is a POD but my utility class is not):
>
> template<class T>
> struct relocate_wrapper {
> template<class... Args> relocate_wrapper(Args&&... args) {
> new (&buf) T(std::forward<Args>(args)...);
> }
> ~relocate_wrapper() { reinterpret_cast<T&>(buf).~T(); }
> >>relocate_wrapper(relocate_wrapper& rhs) {
> new (&buf) T(reinterpret_cast<T&&>(rhs.buf));
> reinterpret_cast<T&>(rhs.buf).~T();
> }
> std::aligned_storage_t<sizeof(T), alignof(T)> buf;
> };
>
> Hm... it might be nice to ensure that the relocator doesn't do any
> unnecessary work copying the buffer that's just going to be placement new
> moved into. Is that an argument against an implicit mem-initializer-list?
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> Visit this group at http://groups.google.com/a/isocpp.org/group/s
> <http://groups.google.com/a/isocpp.org/group/std-proposals/>
>
> ...
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5353_81014760.1439291352696
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>You're right. I have updated the proposal as foll=
ows:</div><div><br></div><div><a href=3D"http://denisbider.com/Relocator.pd=
f">http://denisbider.com/Relocator.pdf</a><br></div><div><br></div><div>The=
latest versions now also include an Annex discussing the need for in-place=
reallocation, as=C2=A0pointed out=C2=A0by=C2=A0Vitali Lovich.</div><div><b=
r></div><div><br>On Tuesday, August 11, 2015 at 2:35:15 AM UTC-6, Edward Ca=
tmur wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr">Right; so it=
's the implementer's responsibility to ensure that all source subob=
jects with non-trivial destructor are destructed, either by deferring to th=
e subobject relocator or by calling the destructor on the subobject. So we =
end up writing:<div><br></div><div><p style=3D"margin: 0in 0in 0pt;"><span =
style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; =
background-color: rgb(246, 248, 255);">=C2=A0=C2=A0>></span><span sty=
le=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; backgro=
und-color: rgb(246, 248, 255);">A</span><span style=3D"color: rgb(48, 128, =
128); font-family: Consolas; font-size: 10pt; background-color: rgb(246, 24=
8, 255);">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consola=
s; font-size: 10pt; background-color: rgb(246, 248, 255);">A</span><span st=
yle=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; ba=
ckground-color: rgb(246, 248, 255);">&</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt; background-color: rgb(24=
6, 248, 255);">=C2=A0x</span><span style=3D"color: rgb(48, 128, 128); font-=
family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">)=
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; background-color: rgb(246, 248, 255);">=C2=A0</span><span style=3D=
"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; backgroun=
d-color: rgb(246, 248, 255);">:</span><span style=3D"color: rgb(0, 0, 32); =
font-family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255=
);">=C2=A0B</span><span style=3D"color: rgb(48, 128, 128); font-family: Con=
solas; font-size: 10pt; background-color: rgb(246, 248, 255);">(</span><spa=
n style=3D"color: rgb(0, 102, 238); font-family: Consolas; font-size: 10pt;=
background-color: rgb(246, 248, 255);">std</span><span style=3D"color: rgb=
(64, 96, 128); font-family: Consolas; font-size: 10pt; background-color: rg=
b(246, 248, 255);">::</span><span style=3D"color: rgb(0, 0, 32); font-famil=
y: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">move</=
span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-s=
ize: 10pt; background-color: rgb(246, 248, 255);">(</span><span style=3D"co=
lor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; background-colo=
r: rgb(246, 248, 255);">x</span><span style=3D"color: rgb(48, 128, 128); fo=
nt-family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);=
">))</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; f=
ont-size: 10pt; background-color: rgb(246, 248, 255);">,</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; backgroun=
d-color: rgb(246, 248, 255);"><wbr>=C2=A0</span><span style=3D"color: rgb(4=
8, 128, 128); font-family: Consolas; font-size: 10pt; background-color: rgb=
(246, 248, 255);">>></span><span style=3D"color: rgb(0, 0, 32); font-=
family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">c=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; background-color: rgb(246, 248, 255);">(</span><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; background-co=
lor: rgb(246, 248, 255);">x</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255=
);">.</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fon=
t-size: 10pt; background-color: rgb(246, 248, 255);">c</span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; backgrou=
nd-color: rgb(246, 248, 255);">)</span><span style=3D"color: rgb(64, 96, 12=
8); font-family: Consolas; font-size: 10pt; background-color: rgb(246, 248,=
255);">,=C2=A0</span><span style=3D"color: rgb(48, 128, 128); font-family:=
Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">>>=
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; background-color: rgb(246, 248, 255);">i</span><span style=3D"colo=
r: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; background-co=
lor: rgb(246, 248, 255);">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">=
x</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt; background-color: rgb(246, 248, 255);">.</span><span style=3D=
"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; background-c=
olor: rgb(246, 248, 255);">i</span><span style=3D"color: rgb(48, 128, 128);=
font-family: Consolas; font-size: 10pt; background-color: rgb(246, 248, 25=
5);">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fo=
nt-size: 10pt; background-color: rgb(246, 248, 255);">=C2=A0</span><span st=
yle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; bac=
kground-color: rgb(246, 248, 255);">{=C2=A0</span><span style=3D"font-famil=
y: Consolas; font-size: 10pt; background-color: rgb(255, 255, 0);"><font co=
lor=3D"#000000">x.B::~B(<wbr>);</font></span><span style=3D"color: rgb(64, =
96, 128); font-family: Consolas; font-size: 10pt; background-color: rgb(246=
, 248, 255);">=C2=A0</span><span style=3D"color: rgb(0, 0, 32); font-family=
: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">a=C2=A0=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; background-color: rgb(246, 248, 255);">=3D</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; backgroun=
d-color: rgb(246, 248, 255);">=C2=A0</span><span style=3D"color: rgb(48, 12=
8, 128); font-family: Consolas; font-size: 10pt; background-color: rgb(246,=
248, 255);">this</span><span style=3D"color: rgb(64, 96, 128); font-family=
: Consolas; font-size: 10pt; background-color: rgb(246, 248, 255);">; }</sp=
an></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3"></font><=
div><br></div><div>There's a highly compelling reason to allow arbitrar=
y mem-initializers: reference members. These have to be initialized within =
the mem-initializer-list, as they can't be reseated within the body of =
the relocator:</div><div><br></div></div><blockquote style=3D"margin: 0px 0=
px 0px 40px; padding: 0px; border: currentColor; border-image: none;"><div>=
<div><font face=3D"monospace, monospace">struct A { int i; <span style=3D"b=
ackground-color: rgb(255, 255, 0);">int& r =3D i;</span> >>A(A&am=
p; x) : >>i, <span style=3D"background-color: rgb(255, 255, 0);">r(i)=
</span> {} };</font></div></div></blockquote><div><div><br></div><div>With =
regard to noexcept, I think this has to be kept; otherwise you have to be a=
ble to rollback the relocation which might not be feasible (e.g. if pointer=
s elsewhere have already been updated to point to relocated objects or subo=
bjects); or destruct the source object which would also be very difficult a=
nd would rarely be the desired behavior.</div><div><br></div><div>On Mon, A=
ug 10, 2015 at 11:45 PM, <span dir=3D"ltr"><<a onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofoll=
ow" gdf-obfuscated-mailto=3D"R2wyd_KqAQAJ">isocp...@denisbider.com</a>><=
/span> wrote:<br></div><div><div><blockquote style=3D"margin: 0px 0px 0px 0=
..8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left=
-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><div>Actually, if =
we want to give the implementer this much control, there's no reason we=
shouldn't put the burden of calling ~B on the implementer.</div><div><=
br></div><div>I thought this would be a problem if ~B is virtual, but it tu=
rns out the following is legal:</div><div><br></div><div><font color=3D"#00=
0000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><b><span style=3D"color: rgb(32, 0, 128); font-family: C=
onsolas; font-size: 10pt;">struct</span></b><span style=3D"color: rgb(0, 0,=
32); font-family: Consolas; font-size: 10pt;"> A<span>=C2=A0=C2=A0=C2=A0=
=C2=A0 </span></span><span style=3D"color: rgb(64, 96, 128); font-family: C=
onsolas; font-size: 10pt;">{</span><span style=3D"color: rgb(0, 0, 32); fon=
t-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb(=
32, 0, 128); font-family: Consolas; font-size: 10pt;">virtual</span></b><sp=
an style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">~</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">()</span><span style=3D"color: rgb=
(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=3D=
"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">{</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;"> </span><span style=3D"color: rgb(0, 48, 96); font-family: Consolas; fon=
t-size: 10pt;">cout</span><span style=3D"color: rgb(0, 0, 32); font-family:=
Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128=
); font-family: Consolas; font-size: 10pt;"><<</span><span style=3D"c=
olor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span=
style=3D"color: maroon; font-family: Consolas; font-size: 10pt;">"</s=
pan><span style=3D"color: rgb(16, 96, 182); font-family: Consolas; font-siz=
e: 10pt;">~A()</span><span style=3D"color: maroon; font-family: Consolas; f=
ont-size: 10pt;">"</span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128,=
128); font-family: Consolas; font-size: 10pt;"><<</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span>=
<span style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10p=
t;">endl</span><span style=3D"color: rgb(64, 96, 128); font-family: Consola=
s; font-size: 10pt;">;</span><span style=3D"color: rgb(0, 0, 32); font-fami=
ly: Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 1=
28); font-family: Consolas; font-size: 10pt;">}</span><span style=3D"color:=
rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span styl=
e=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">};</=
span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><b><span style=3D"color: rgb(32, 0, 128); font-family: C=
onsolas; font-size: 10pt;">struct</span></b><span style=3D"color: rgb(0, 0,=
32); font-family: Consolas; font-size: 10pt;"> B </span><span style=3D"col=
or: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">:</span><spa=
n style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> =
A </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fon=
t-size: 10pt;">{</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb(32, 0, 128);=
font-family: Consolas; font-size: 10pt;">virtual</span></b><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><spa=
n style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt=
;">~</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt;">B</span><span style=3D"color: rgb(48, 128, 128); font-family:=
Consolas; font-size: 10pt;">()</span><span style=3D"color: rgb(0, 0, 32); =
font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(=
64, 96, 128); font-family: Consolas; font-size: 10pt;">{</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span>=
<span style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10p=
t;">cout</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;"><<</span><span style=3D"color: rgb(0=
, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"c=
olor: maroon; font-family: Consolas; font-size: 10pt;">"</span><span s=
tyle=3D"color: rgb(16, 96, 182); font-family: Consolas; font-size: 10pt;">~=
B()</span><span style=3D"color: maroon; font-family: Consolas; font-size: 1=
0pt;">"</span><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128); font=
-family: Consolas; font-size: 10pt;"><<</span><span style=3D"color: r=
gb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=
=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt;">endl</s=
pan><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-siz=
e: 10pt;">;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consola=
s; font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-f=
amily: Consolas; font-size: 10pt;">}</span><span style=3D"color: rgb(0, 0, =
32); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color:=
rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">};</span></p><f=
ont color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><b><span style=3D"color: rgb(32, 0, 128); font-family: C=
onsolas; font-size: 10pt;">struct</span></b><span style=3D"color: rgb(0, 0,=
32); font-family: Consolas; font-size: 10pt;"> C </span><span style=3D"col=
or: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">:</span><spa=
n style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> =
B </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fon=
t-size: 10pt;">{</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb(32, 0, 128);=
font-family: Consolas; font-size: 10pt;">virtual</span></b><span style=3D"=
color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><spa=
n style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt=
;">~</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt;">C</span><span style=3D"color: rgb(48, 128, 128); font-family:=
Consolas; font-size: 10pt;">()</span><span style=3D"color: rgb(0, 0, 32); =
font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(=
64, 96, 128); font-family: Consolas; font-size: 10pt;">{</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span>=
<span style=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10p=
t;">cout</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;"><<</span><span style=3D"color: rgb(0=
, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"c=
olor: maroon; font-family: Consolas; font-size: 10pt;">"</span><span s=
tyle=3D"color: rgb(16, 96, 182); font-family: Consolas; font-size: 10pt;">~=
C()</span><span style=3D"color: maroon; font-family: Consolas; font-size: 1=
0pt;">"</span><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128); font=
-family: Consolas; font-size: 10pt;"><<</span><span style=3D"color: r=
gb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=
=3D"color: rgb(0, 48, 96); font-family: Consolas; font-size: 10pt;">endl</s=
pan><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-siz=
e: 10pt;">;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consola=
s; font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-f=
amily: Consolas; font-size: 10pt;">}</span><span style=3D"color: rgb(0, 0, =
32); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color:=
rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">};</span></p><f=
ont color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><b><span style=3D"color: rgb(32, 0, 128); font-family: C=
onsolas; font-size: 10pt;">void</span></b><span style=3D"color: rgb(0, 0, 3=
2); font-family: Consolas; font-size: 10pt;"> DestroySubobject</span><span =
style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;"=
>(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-s=
ize: 10pt;">B</span><span style=3D"color: rgb(48, 128, 128); font-family: C=
onsolas; font-size: 10pt;">*</span><span style=3D"color: rgb(0, 0, 32); fon=
t-family: Consolas; font-size: 10pt;"> b</span><span style=3D"color: rgb(48=
, 128, 128); font-family: Consolas; font-size: 10pt;">)</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span>=
<span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 1=
0pt;">{</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; f=
ont-size: 10pt;"> b</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;">-></span><span style=3D"color: rgb(0, 0=
, 32); font-family: Consolas; font-size: 10pt;">B</span><span style=3D"colo=
r: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">::</span><spa=
n style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt=
;">~</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font=
-size: 10pt;">B</span><span style=3D"color: rgb(48, 128, 128); font-family:=
Consolas; font-size: 10pt;">()</span><span style=3D"color: rgb(64, 96, 128=
); font-family: Consolas; font-size: 10pt;">;</span><span style=3D"color: r=
gb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">}</sp=
an></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font></div><div><br></div><div>It turns out, this calls ~A and ~B, but no=
t ~C.</div><div><br></div><div>It seems to me it follows:=C2=A0if we allow =
>>A to initialize the subobjects in whatever fashion; including with =
copy or move construction; then it would make sense to expect the author of=
>>A to call B::~B.</div><div><div><div><br><br>On Monday, August 10,=
2015 at 4:17:01 PM UTC-6, <a>isocp...@denisbider.com</a> wrote:</div><bloc=
kquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-c=
olor: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;=
"><div dir=3D"ltr"><div>However,=C2=A0if there's real desire for the wr=
apper you show to be legal, a better way to do it would probably be to allo=
w this:</div><div><br></div><div><font color=3D"#000000" face=3D"Times New =
Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"font-family: Consolas; font-size: 10pt;">=
<font color=3D"#000000">=C2=A0</font></span></p><font color=3D"#000000" fac=
e=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;"><span>=C2=A0 </span>>></span><span style=3D=
"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">A</span><sp=
an style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10p=
t;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fon=
t-size: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family=
: Consolas; font-size: 10pt;">&</span><span style=3D"color: rgb(0, 0, 3=
2); font-family: Consolas; font-size: 10pt;"> x</span><span style=3D"color:=
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span><span =
style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </=
span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-si=
ze: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"> B</span><span style=3D"color: rgb(48, 128, 128); fon=
t-family: Consolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, =
102, 238); font-family: Consolas; font-size: 10pt;">std</span><span style=
=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">::</s=
pan><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: =
10pt;">move</span><span style=3D"color: rgb(48, 128, 128); font-family: Con=
solas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-=
family: Consolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 1=
28, 128); font-family: Consolas; font-size: 10pt;">))</span><span style=3D"=
color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">,</span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
"> </span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; f=
ont-size: 10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-f=
amily: Consolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 12=
8, 128); font-family: Consolas; font-size: 10pt;">(</span><span style=3D"co=
lor: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">x</span><span =
style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;"=
>.</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-s=
ize: 10pt;">c</span><span style=3D"color: rgb(48, 128, 128); font-family: C=
onsolas; font-size: 10pt;">)</span><span style=3D"color: rgb(64, 96, 128); =
font-family: Consolas; font-size: 10pt;">, </span><span style=3D"color: rgb=
(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><sp=
an style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">=
i</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">.</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">i</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; f=
ont-size: 10pt;">{ </span><span style=3D"color: rgb(0, 0, 32); font-family:=
Consolas; font-size: 10pt;">a </span><span style=3D"color: rgb(48, 128, 12=
8); font-family: Consolas; font-size: 10pt;">=3D</span><span style=3D"color=
: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span sty=
le=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">th=
is</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fon=
t-size: 10pt;">; }</span></p><font color=3D"#000000" face=3D"Times New Roma=
n" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font></div><div><br></div><div>But this means we:</div><div><br></div><di=
v>- say goodbye to the noexcept guarantee;</div><div><br></div><div>- defin=
e the point when=C2=A0~B is called=C2=A0in the original location - probably=
=C2=A0when >>A returns;</div><div><br></div><div>- introduce another =
type trait, <font face=3D"courier new,monospace">is_nothrow_relocatable</fo=
nt></div><div><br></div><div>I would have preferred to avoid this, but - I =
guess, if people <em>really</em> want to merge move and copy=C2=A0construct=
ion into relocation... <em>(shudder :)</em></div><div><br></div><div><br>On=
Monday, August 10, 2015 at 3:59:07 PM UTC-6, <a>isocp...@denisbider.com</a=
> wrote:</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left:=
1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border=
-left-style: solid;"><div dir=3D"ltr"><div>Hmm, good points.</div><div><br>=
</div><div>There are definitely situations where you don't want to mem-=
initialize a trivial member, such as in the example:</div><div><br></div><d=
iv><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; f=
ont-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: =
Consolas; font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128)=
; font-family: Consolas; font-size: 10pt;">)</span><span style=3D"color: rg=
b(64, 96, 128); font-family: Consolas; font-size: 10pt;">,</span><span styl=
e=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-family: Co=
nsolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt;">(</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">x</span><span style=3D"=
color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">.</span>=
<span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt=
;">c</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; =
font-size: 10pt;">)</span><span style=3D"color: rgb(64, 96, 128); font-fami=
ly: Consolas; font-size: 10pt;">, </span><span style=3D"color: rgb(48, 128,=
128); font-family: Consolas; font-size: 10pt;">>></span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">i</span>=
<span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: =
10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; =
font-size: 10pt;">x</span><span style=3D"color: rgb(48, 128, 128); font-fam=
ily: Consolas; font-size: 10pt;">.</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;">i</span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span></p><fon=
t color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>However, one might definitely argue that s=
ituations where you want to mem-initialize a base or a member, but with a n=
on-corresponding member,=C2=A0are practically nonexistent. So, we may in fa=
ct=C2=A0prefer the following:</div><div><br></div><div><font color=3D"#0000=
00" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0 </span></span><span style=3D=
"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>>=
;</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-si=
ze: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;">A</span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">&</span><span style=
=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> x</span=
><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size:=
10pt;">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas;=
font-size: 10pt;"> </span><span style=3D"color: rgb(64, 96, 128); font-fam=
ily: Consolas; font-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: r=
gb(48, 128, 128); font-family: Consolas; font-size: 10pt;">>></span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
">B</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fo=
nt-size: 10pt;">,</span><span style=3D"color: rgb(0, 0, 32); font-family: C=
onsolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128);=
font-family: Consolas; font-size: 10pt;">>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">c</span><span s=
tyle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">,=
</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt;">>></span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt;">i</span></p><font color=3D"#000000" face=
=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;"><span>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span></span><s=
pan style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10p=
t;">{
</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt;">a </span><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=3D</span><span style=3D"color: rgb(0, 0, 32); fo=
nt-family: Consolas; font-size: 10pt;"> </span><b><span style=3D"color: rgb=
(32, 0, 128); font-family: Consolas; font-size: 10pt;">this</span></b><span=
style=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;"=
>; }</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div>The relocate_wrapper you suggest I think l=
ooks neat, and should be legal. I don't see a reason why it wouldn'=
t be legal, if the mem-initializer-list is not implicit.</div><div><br></di=
v><div>It seems to me,=C2=A0intuitively,=C2=A0that there's no reason to=
make it illegal to access any data member of the moved-from subobject unti=
l the outermost relocator exits.</div><div><br></div><div>I see no obvious =
reason why virtual methods shouldn't continue to work, as well. But thi=
s is not to say, of course, that one should call them.</div><div><br></div>=
<div>In general, anything that's const ought to be safe to call. Which =
is an argument in favor of making the signature >>T(T const&) -=
=C2=A0except that would prevent zeroing out of members.</div><div><br></div=
><div><br>On Monday, August 10, 2015 at 2:20:28 PM UTC-6, Edward Catmur wro=
te:</div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex;=
border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left=
-style: solid;"><div dir=3D"ltr"><div>A few queries:</div><div><br></div><d=
iv>What exactly are the semantics of the mem-initializer-list, particularly=
with regard to omitted, duplicated or misplaced bases/members:<br></div><d=
iv><br></div><div style=3D"border: 1px solid rgb(187, 187, 187); border-ima=
ge: none; background-color: rgb(250, 250, 250);"><code><div><span style=3D"=
color: rgb(0, 0, 136);">struct</span><span style=3D"color: rgb(0, 0, 0);"> =
A </span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"co=
lor: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: rgb(1=
02, 102, 0);">::</span><span style=3D"color: rgb(0, 0, 136);">string</span>=
<span style=3D"color: rgb(0, 0, 0);"> q</span><span style=3D"color: rgb(102=
, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);"> r</span><span sty=
le=3D"color: rgb(102, 102, 0);">,</span><span style=3D"color: rgb(0, 0, 0);=
"> s</span><span style=3D"color: rgb(102, 102, 0);">;</span><span style=3D"=
color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><span style=3D"color: rgb(10=
2, 102, 0);">>></span><span style=3D"color: rgb(0, 0, 0);">A</span><s=
pan style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0,=
0, 0);">A</span><span style=3D"color: rgb(102, 102, 0);">&</span><span=
style=3D"color: rgb(0, 0, 0);"> x</span><span style=3D"color: rgb(102, 102=
, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"=
color: rgb(102, 102, 0);">:</span><span style=3D"color: rgb(0, 0, 0);"> </s=
pan><span style=3D"color: rgb(102, 102, 0);">>></span><span style=3D"=
color: rgb(0, 0, 0);">r</span><span style=3D"color: rgb(102, 102, 0);">(</s=
pan><span style=3D"color: rgb(0, 0, 0);">x</span><span style=3D"color: rgb(=
102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">r</span><span s=
tyle=3D"color: rgb(102, 102, 0);">),</span><span style=3D"color: rgb(0, 0, =
0);"> </span><span style=3D"color: rgb(102, 102, 0);">>></span><span =
style=3D"color: rgb(0, 0, 0);">s</span><span style=3D"color: rgb(102, 102, =
0);">(</span><span style=3D"color: rgb(0, 0, 0);">x</span><span style=3D"co=
lor: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">r</spa=
n><span style=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rg=
b(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">{</span><span=
style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(136, 0, 0=
);">/* oops */</span><span style=3D"color: rgb(0, 0, 0);"> </span><span sty=
le=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);=
"><br></span><span style=3D"color: rgb(102, 102, 0);">};</span><span style=
=3D"color: rgb(0, 0, 0);"><br></span></div></code></div><div><br></div><div=
>Is it ever legitimate for a mem-initializer to be omitted or to take any f=
orm other than <font face=3D"courier new, monospace">>>id(<a onmoused=
own=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fx.id\46s=
a\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB69ZOU5okYoDl3uhnQkQ';return tr=
ue;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2=
Fx.id\46sa\75D\46sntz\0751\46usg\75AFQjCNG_YifSOWB69ZOU5okYoDl3uhnQkQ';=
return true;" href=3D"http://x.id" target=3D"_blank" rel=3D"nofollow">x.id<=
/a>)</font> where the two identifiers are equivalent? If so, whose responsi=
bility is it to call the destructor on the corresponding member of the sour=
ce object? If not, would it be better to omit the mem-initializer-list enti=
rely, as with destructors?</div><div><br></div><div>Within the body of the =
relocator special member function, what are the lifetime statuses of the so=
urce and destination objects, particularly with regard to [class.cdtor]? Is=
it permissible to form lvalues to the bases and members of the source obje=
ct, or is this undefined behavior as they are destructed? If the type is po=
lymorphic, is it permissible to dynamic_cast or invoke virtual functions on=
the source? Indeed, is it permissible to invoke any member functions on th=
e source?</div><div><br></div><div>In particular, I'd like to make this=
utility class legal (noting that aligned_storage_t is a POD but my utility=
class is not):</div><div><br></div><div><div style=3D"border: 1px solid rg=
b(187, 187, 187); border-image: none; background-color: rgb(250, 250, 250);=
"><code><div><span style=3D"color: rgb(0, 0, 136);">template</span><span st=
yle=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0,=
136);">class</span><span style=3D"color: rgb(0, 0, 0);"> T</span><span sty=
le=3D"color: rgb(102, 102, 0);">></span><span style=3D"color: rgb(0, 0, =
0);"><br></span><span style=3D"color: rgb(0, 0, 136);">struct</span><span s=
tyle=3D"color: rgb(0, 0, 0);"> relocate_wrapper </span><span style=3D"color=
: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=
=A0 </span><span style=3D"color: rgb(0, 0, 136);">template</span><span styl=
e=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, 1=
36);">class</span><span style=3D"color: rgb(102, 102, 0);">...</span><span =
style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 0, 10=
2);">Args</span><span style=3D"color: rgb(102, 102, 0);">></span><span s=
tyle=3D"color: rgb(0, 0, 0);"> relocate_wrapper</span><span style=3D"color:=
rgb(102, 102, 0);">(</span><span style=3D"color: rgb(102, 0, 102);">Args</=
span><span style=3D"color: rgb(102, 102, 0);">&&...</span><span sty=
le=3D"color: rgb(0, 0, 0);"> args</span><span style=3D"color: rgb(102, 102,=
0);">)</span><span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"c=
olor: rgb(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color: rgb(0, 0, 136);">new</span><span=
style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102,=
0);">(&</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span sty=
le=3D"color: rgb(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);=
"> T</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"=
color: rgb(0, 0, 0);">std</span><span style=3D"color: rgb(102, 102, 0);">::=
</span><span style=3D"color: rgb(0, 0, 0);">forward</span><span style=3D"co=
lor: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(102, 0, 102);"=
>Args</span><span style=3D"color: rgb(102, 102, 0);">>(</span><span styl=
e=3D"color: rgb(0, 0, 0);">args</span><span style=3D"color: rgb(102, 102, 0=
);">)...)<wbr>;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </spa=
n><span style=3D"color: rgb(102, 102, 0);">}</span><span style=3D"color: rg=
b(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);">~</=
span><span style=3D"color: rgb(0, 0, 0);">relocate_wrapper</span><span styl=
e=3D"color: rgb(102, 102, 0);">()</span><span style=3D"color: rgb(0, 0, 0);=
"> </span><span style=3D"color: rgb(102, 102, 0);">{</span><span style=3D"c=
olor: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">reinter=
pret_cast</span><span style=3D"color: rgb(102, 102, 0);"><</span><span s=
tyle=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0=
);">&>(</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span s=
tyle=3D"color: rgb(102, 102, 0);">).~</span><span style=3D"color: rgb(0, 0,=
0);">T</span><span style=3D"color: rgb(102, 102, 0);">()<wbr>;</span><span=
style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102,=
0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span =
style=3D"color: rgb(102, 102, 0);">>></span><span style=3D"color: rgb=
(0, 0, 0);">relocate_wrapper</span><span style=3D"color: rgb(102, 102, 0);"=
>(</span><span style=3D"color: rgb(0, 0, 0);">relocate_<wbr>wrapper</span><=
span style=3D"color: rgb(102, 102, 0);">&</span><span style=3D"color: r=
gb(0, 0, 0);"> rhs</span><span style=3D"color: rgb(102, 102, 0);">)</span><=
span style=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, =
102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color: rgb(0, 0, 136);">new</span><span style=3D"color:=
rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0);">(&</sp=
an><span style=3D"color: rgb(0, 0, 0);">buf</span><span style=3D"color: rgb=
(102, 102, 0);">)</span><span style=3D"color: rgb(0, 0, 0);"> T</span><span=
style=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0,=
136);">reinterpret_cast</span><span style=3D"color: rgb(102, 102, 0);"><=
;</span><span style=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: =
rgb(102, 102, 0);">&&>(</span><span style=3D"color: rgb(0, 0, 0)=
;">rhs</span><span style=3D"color: rgb(102, 102, 0);">.</span><span style=
=3D"color: rgb(0, 0, 0);">bu<wbr>f</span><span style=3D"color: rgb(102, 102=
, 0);">));</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: rgb(0, 0, 136);">reinterpret_cast</span><span sty=
le=3D"color: rgb(102, 102, 0);"><</span><span style=3D"color: rgb(0, 0, =
0);">T</span><span style=3D"color: rgb(102, 102, 0);">&>(</span><spa=
n style=3D"color: rgb(0, 0, 0);">rhs</span><span style=3D"color: rgb(102, 1=
02, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">buf</span><span style=
=3D"color: rgb(102, 102, 0);">).<wbr>~</span><span style=3D"color: rgb(0, 0=
, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">();</span><span sty=
le=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(102=
, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 std</sp=
an><span style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: =
rgb(0, 0, 0);">aligned_storage_t</span><span style=3D"color: rgb(102, 102, =
0);"><</span><span style=3D"color: rgb(0, 0, 136);">sizeof</span><span s=
tyle=3D"color: rgb(102, 102, 0);">(</span><span style=3D"color: rgb(0, 0, 0=
);"><wbr>T</span><span style=3D"color: rgb(102, 102, 0);">),</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);"=
>alignof</span><span style=3D"color: rgb(102, 102, 0);">(</span><span style=
=3D"color: rgb(0, 0, 0);">T</span><span style=3D"color: rgb(102, 102, 0);">=
)></span><span style=3D"color: rgb(0, 0, 0);"> buf</span><span style=3D"=
color: rgb(102, 102, 0);">;</span><span style=3D"color: rgb(0, 0, 0);"><br>=
</span><span style=3D"color: rgb(102, 102, 0);">};</span></div></code></div=
><div><br></div></div><div>Hm... it might be nice to ensure that the reloca=
tor doesn't do any unnecessary work copying the buffer that's just =
going to be placement new moved into. Is that an argument against an implic=
it mem-initializer-list?</div></div></blockquote></div></blockquote></div><=
/blockquote></div></div></div><div><div>
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this topic, visit <a onmousedown=3D"this.href=3D'ht=
tps://groups.google.com/a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0/unsu=
bscribe';return true;" onclick=3D"this.href=3D'https://groups.googl=
e.com/a/isocpp.org/d/topic/std-proposals/f1zaOjyUem0/unsubscribe';retur=
n true;" href=3D"https://groups.google.com/a/isocpp.org/d/topic/std-proposa=
ls/f1zaOjyUem0/unsubscribe" target=3D"_blank" rel=3D"nofollow">https://grou=
ps.google.com/a/<wbr>isocpp.org/d/topic/std-<wbr>proposals/f1zaOjyUem0/<wbr=
>unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a onmo=
usedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.=
href=3D'javascript:';return true;" href=3D"javascript:" target=3D"_=
blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"R2wyd_KqAQAJ">std-proposal=
....@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D'jav=
ascript:';return true;" onclick=3D"this.href=3D'javascript:';re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"R2wyd_KqAQAJ">std-pr...@isocpp.org</a>.<br>
Visit this group at <a onmousedown=3D"this.href=3D'http://groups.google=
..com/a/isocpp.org/group/std-proposals/';return true;" onclick=3D"this.h=
ref=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/';=
return true;" href=3D"http://groups.google.com/a/isocpp.org/group/std-propo=
sals/" target=3D"_blank" rel=3D"nofollow">http://groups.google.com/a/<wbr>i=
socpp.org/group/s</a></div></div></blockquote></div></div></div></div>...</=
blockquote></div>
<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 />
------=_Part_5353_81014760.1439291352696--
------=_Part_5352_1274161025.1439291352695--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 11 Aug 2015 10:22:29 -0400
Raw View
On 2015-08-08 04:37, isocppgroup@denisbider.com wrote:
> I have published an updated draft:
> http://www.denisbider.com/Relocator.pdf
>
>> In the defaulted example, s.b. ~int(int&).
>
> Good point, done that.
Thanks!
>> The multiple object helper should work
>> on overlapping memory.
>
> It should indeed. :) Fixed!
Thanks!
>> Should(n't) the cting-dtor be implicit-default if the
>> class has a) a *default* move ctor *or copy ctor*,
>> *and* b) a default dtor, whether or not such are declared?
>
> Hmm. I wouldn't necessarily mind, but [...]
>
> For consistency as well as safety, it would make sense to me to use the
> same rules for the relocator.
To revisit this, my main "concern" is to not suppress relocatability for
classes that are trivially relocatable, merely because a copy/move ctor
or dtor was explicitly defaulted. IOW, relocation should always be
available if the default implementation is provably correct. Otherwise
we are penalizing existing code needlessly.
Er... on that note, I just realized, we probably should make it UB to
invoke the relocator on an object's base class outside of the relocator
itself doing
IOW, this is UB:
class Foo { public: virtual ~Foo(); ... };
class Bar : public Foo { ... };
auto pfoo1 = new Bar;
auto pfoo2 = (Foo*)malloc(sizeof(Foo));
pfoo1-> >>(*pfoo2);
I don't see that this should be a problem with the proposal, since the
main use case is containers where the final type is definitely known and
the same on both ends of the relocation, but it would be possible to
write code like the above, and I don't see offhand how such code could
be made to do anything reasonable.
>> I feel fairly strongly that there should be a cutoff point
>> for which we can use the same syntax to relocate
>> objects that can't be simply relocated.
>
> I agree, but I think it should be at a level above this. I have added a
> discussion in the Rationales section.
I can live with it, I guess. I'd feel better if the proposal also
specified such function, though. (std::relocate?)
>> I'm not entirely confident that the composition case is
>> solved. As worded, the class members are relocated
>> after the base class has been destroyed
>
> The relocator performs the tasks of both a constructor and a destructor, so
> one of the two orders have to be chosen. I have added a section for this in
> the Rationales section.
>
> I hope also that calling the special member a "relocator"; expressing its
> duality and impartiality, rather than a bias toward construction or
> destruction; might also help alleviate this concern.
The only "true" solution I can envision is that the old base is not
destroyed until the new object is fully constructed. This would conflict
with the notion of relocation destroying the (old copy of the) thing
relocated.
On the other hand, it's expected that relocation does not change the
actual bytes of the old object, so if relocation of the derived type
needs to read those, it can. (Which also makes me wonder if relocation
should be const w.r.t. the old object?)
Anyway, still just thinking out loud, really...
Okay, on to the new draft...
I'm not sure I agree that argument order for a cting-dtor is
counterintuitive :-). Basically, the question here is if we use push
order (source first) or pull order (destination first). You're using
pull order, which honestly, IMHO is counterintuitive :-). OTOH, memcpy
also uses pull order. Essentially this is the same as the AT&T vs. Intel
assembly dialect... as much a matter of personal taste as anything.
That said, I'd probably keep the static operator order as-is for
consistency with memcpy. The only other comment I'd make is that I feel
like there should be some indication that the source is destroyed by the
call. This is accomplished by cting-dtor, as you're calling a dtor. It's
also accomplished by e.g. 'T const~' (not sure if there should also be a
'&' there, or if '~' should imply by-reference...).
Pedantic: I want to say I've seen try_realloc more often than
realloc_in_place. Not terribly important however since AFAIK neither
exists yet.
Last, and not a comment on the paper as such, we really could use such a
function. Besides allowing us to work around using straight realloc (and
thus as mentioned, causing problems for static analysis tools), it may
be the case that a realloc is less efficient. As I just pointed out on
the Qt list, if you are growing a container in order to do a middle
insertion, and cannot grow in place, it is more efficient to allocate
uninitialized memory and do a piecewise move (which we can do with the
proposal in a "correct" manner) of the portions before and after the
insertion point to their correct final locations.
p.s. FWIW I do prefer the type trait names 'is_[trivially_]relocatable' :-).
--
Matthew
--
---
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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 11 Aug 2015 10:39:04 -0400
Raw View
> On 2015-08-08 18:27, Vitali Lovich wrote:
>> can you clarify why there is a distinction between the multiple &=20
>> single relocators? Am I correct in guessing that it=E2=80=99s to try & a=
void
>> the loop overhead when you only have a single object?
That could be one reason. I'd also suggest that they should be different
for some of the same reasons that delete and delete[] are different.
Which brings up another point... cosmetic, but the second form should
take an 'A[]' rather than an 'A*'. (Which is the same thing, I know,
hence why it's a cosmetic change, but writing it that way makes it more
clear that the argument is expected to be an array of objects.)
>> If construction order is indeed more appropriate (which I think you
>> are correct on), doesn=E2=80=99t it speak that this is more naturally th=
ought
>> of as a destructive move constructor?
Riiiight, that reminds me of another comment I forgot. Namely, this
looks strange:
dt-> >>A(*s);
....because you are calling what looks like a member function on
something that hasn't been constructed yet. It seems it would "feel"
better if this was written as some form of placement new.
On 2015-08-09 06:57, isocppgroup@denisbider.com wrote:
> Yes, I think you're very right!
> [...]
> If folks like this, I'm leaning to promote constructor-like syntax from t=
he=20
> annex, and place it in the center of the proposal.
This brings us back to destructive move :-). (And I'll reiterate my
comments on the argument being somehow marked.) Although... I'd consider
calling it instead a "relocating ctor". Same thing, but possibly better
terminology.
>> While discussion relocation, there is what amounts to a footnote=20
>> mentioning realloc. Is it correct that this is the language proposal=20
>> that would complement any eventual library features that would
>> enable the use of realloc within containers?
Yes, and see also my other e-mail.
>> it sounds like this is trying to solve the memcpy problem but it
>> seems like it solves both that & realloc, no?
Yes and no... it doesn't really solve realloc, because realloc doesn't
specify anything w.r.t. object lifetime. Again, see also my other
e-mail. What it *would* solve is being able to do something sensible and
maximally efficient *if* we had try_realloc / realloc_in_place.
--=20
Matthew
--=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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 11 Aug 2015 10:42:17 -0400
Raw View
On 2015-08-09 21:14, jgottman6@gmail.com wrote:
> Very nice, but I have one question. How do you handle member variables
> that might or might not be self-references? For instance, in your example,
> if the variable a is guaranteed to be either equal to this or a pointer to
> an object allocated with new, how would you write the relocator function?
> Most other members of class A could have code like
>
> if (a == this) {
> //do something
> } else {
> //do something else
> }
>
> but in the case of the relocator function, by the time we get to the a
> variable half the object has been relocated and it's not at all obvious
> what needs to be tested.
You would compare to the old object location rather than 'this'.
Examples like these are why if we were to have a separate fix-up
operator (i.e. able to "mostly" construct the new objects via memcpy),
it would need the original object address and *possibly* also need for
that memory to be unmodified.
With a one-at-a-time relocation operator/ctor/whatever you don't run
into these sorts of problems, although it does penalize the case of such
classes somewhat.
--
Matthew
--
---
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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 11 Aug 2015 11:04:44 -0400
Raw View
On 2015-08-10 17:59, isocppgroup@denisbider.com wrote:
> However, one might definitely argue that situations where you want to
> mem-initialize a base or a member, but with a non-corresponding member, are
> practically nonexistent. So, we may in fact prefer the following:
>
> >>A(A& x) : >>B, >>c, >>i
I like that... but I might consider deferring it. Besides that it might
be contentious, if we allow this for relocation, it would be nice to
allow it for move/copy also at the same time.
IOW, for a copy/move/relocate ctor, these:
T(T /*...*/ other) : a /*...*/
T(T /*...*/ other) : >>a /*...*/
....are equivalent to these:
T(T /*...*/ other) : a{other.a} /*...*/
T(T /*...*/ other) : >>a(other.a) /*...*/
> It seems to me, intuitively, that there's no reason to make it illegal to
> access any data member of the moved-from subobject until the outermost
> relocator exits.
D'oh! Why didn't I think of that earlier? If we define relocation as
making the old object destroyed *when the OUTERMOST relocation exits*,
and *not* destroying the thing being relocated as soon as that thing's
relocation operation exits, this also solves the composition problems!
I think you've covered the ins and outs of how and why to allow
non-relocations. On that note, I'll just say that I agree with those.
(And in particular, only allow them if they are noexcept.)
It seems like this might also allow relaxing some of the inhibitions on
implicitly defined relocate-ctors?
--
Matthew
--
---
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: isocppgroup@denisbider.com
Date: Tue, 11 Aug 2015 12:45:55 -0700 (PDT)
Raw View
------=_Part_5883_731942981.1439322355380
Content-Type: multipart/alternative;
boundary="----=_Part_5884_61882751.1439322355381"
------=_Part_5884_61882751.1439322355381
Content-Type: text/plain; charset=UTF-8
Good points, thank you!
I have uploaded a new version of the draft addressing the following:
- proposed single object invocation is now similar to placement new
- there is now an Annex 2 defining a proposed std::relocate_or_move
- proposed implicit declaration rules have been relaxed, so that explicitly
defaulting a special member does not block implicit relocator declaration
- added explicit statement that lifetime of object in original location
ceases when outermost relocator completes
- added explicit statement that invocation of subobject relocator outside
of outer object relocation is undefined behavior
New version:
http://denisbider.com/Relocator.pdf
> the second form should take an 'A[]' rather than an 'A*'.
I have decided against this because the argument may in fact be a slice of
an array, not a whole array. Overlapping memory is also explicitly
supported, so I would not like to suggest that only a whole array may be
passed.
> (Which also makes me wonder if relocation
> should be const w.r.t. the old object?)
I think not, because:
- the user may want to explicitly destroy subobjects if initializing their
counterparts via means other than relocation;
- the user may want to zero out memory being moved from.
> I'm not sure I agree that argument order for a cting-dtor
> is counterintuitive :-).
Besides whether or not cting-dtor syntax is intuitive - there's the
additional issue that it doesn't blend well with this:
>>A(A& x) : B(std::move(x)) { x.B::~B(); }
Providing a way to do this with destructor-like syntax would be inventing
alternate syntax for something we already have.
> I've seen try_realloc more often than realloc_in_place.
I find realloc_in_place more descriptive. Strictly speaking, the existing
realloc already has "try" implied, since it won't block or abort the
program if it fails. So the "try" is implied, and what one really wants to
express is which sub-step of realloc one is attempting.
> if you are growing a container in order to do a
> middle insertion, and cannot grow in place,
> it is more efficient to allocate uninitialized
> memory and do a piecewise move
Interesting point, very true.
On Tuesday, August 11, 2015 at 8:22:44 AM UTC-6, Matthew Woehlke wrote:
> On 2015-08-08 04:37, isocp...@denisbider.com <javascript:> wrote:
> > I have published an updated draft:
> > http://www.denisbider.com/Relocator.pdf
> >
> >> In the defaulted example, s.b. ~int(int&).
> >
> > Good point, done that.
>
> Thanks!
>
> >> The multiple object helper should work
> >> on overlapping memory.
> >
> > It should indeed. :) Fixed!
>
> Thanks!
>
> >> Should(n't) the cting-dtor be implicit-default if the
> >> class has a) a *default* move ctor *or copy ctor*,
> >> *and* b) a default dtor, whether or not such are declared?
> >
> > Hmm. I wouldn't necessarily mind, but [...]
> >
> > For consistency as well as safety, it would make sense to me to use the
> > same rules for the relocator.
>
> To revisit this, my main "concern" is to not suppress relocatability for
> classes that are trivially relocatable, merely because a copy/move ctor
> or dtor was explicitly defaulted. IOW, relocation should always be
> available if the default implementation is provably correct. Otherwise
> we are penalizing existing code needlessly.
>
>
> Er... on that note, I just realized, we probably should make it UB to
> invoke the relocator on an object's base class outside of the relocator
> itself doing
>
> IOW, this is UB:
>
> class Foo { public: virtual ~Foo(); ... };
> class Bar : public Foo { ... };
>
> auto pfoo1 = new Bar;
> auto pfoo2 = (Foo*)malloc(sizeof(Foo));
> pfoo1-> >>(*pfoo2);
>
> I don't see that this should be a problem with the proposal, since the
> main use case is containers where the final type is definitely known and
> the same on both ends of the relocation, but it would be possible to
> write code like the above, and I don't see offhand how such code could
> be made to do anything reasonable.
>
> >> I feel fairly strongly that there should be a cutoff point
> >> for which we can use the same syntax to relocate
> >> objects that can't be simply relocated.
> >
> > I agree, but I think it should be at a level above this. I have added a
> > discussion in the Rationales section.
>
> I can live with it, I guess. I'd feel better if the proposal also
> specified such function, though. (std::relocate?)
>
> >> I'm not entirely confident that the composition case is
> >> solved. As worded, the class members are relocated
> >> after the base class has been destroyed
> >
> > The relocator performs the tasks of both a constructor and a destructor,
> so
> > one of the two orders have to be chosen. I have added a section for this
> in
> > the Rationales section.
> >
> > I hope also that calling the special member a "relocator"; expressing
> its
> > duality and impartiality, rather than a bias toward construction or
> > destruction; might also help alleviate this concern.
>
> The only "true" solution I can envision is that the old base is not
> destroyed until the new object is fully constructed. This would conflict
> with the notion of relocation destroying the (old copy of the) thing
> relocated.
>
> On the other hand, it's expected that relocation does not change the
> actual bytes of the old object, so if relocation of the derived type
> needs to read those, it can. (Which also makes me wonder if relocation
> should be const w.r.t. the old object?)
>
> Anyway, still just thinking out loud, really...
>
>
>
> Okay, on to the new draft...
>
> I'm not sure I agree that argument order for a cting-dtor is
> counterintuitive :-). Basically, the question here is if we use push
> order (source first) or pull order (destination first). You're using
> pull order, which honestly, IMHO is counterintuitive :-). OTOH, memcpy
> also uses pull order. Essentially this is the same as the AT&T vs. Intel
> assembly dialect... as much a matter of personal taste as anything.
>
> That said, I'd probably keep the static operator order as-is for
> consistency with memcpy. The only other comment I'd make is that I feel
> like there should be some indication that the source is destroyed by the
> call. This is accomplished by cting-dtor, as you're calling a dtor. It's
> also accomplished by e.g. 'T const~' (not sure if there should also be a
> '&' there, or if '~' should imply by-reference...).
>
> Pedantic: I want to say I've seen try_realloc more often than
> realloc_in_place. Not terribly important however since AFAIK neither
> exists yet.
>
> Last, and not a comment on the paper as such, we really could use such a
> function. Besides allowing us to work around using straight realloc (and
> thus as mentioned, causing problems for static analysis tools), it may
> be the case that a realloc is less efficient. As I just pointed out on
> the Qt list, if you are growing a container in order to do a middle
> insertion, and cannot grow in place, it is more efficient to allocate
> uninitialized memory and do a piecewise move (which we can do with the
> proposal in a "correct" manner) of the portions before and after the
> insertion point to their correct final locations.
>
>
> p.s. FWIW I do prefer the type trait names 'is_[trivially_]relocatable'
> :-).
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5884_61882751.1439322355381
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Good points, thank you!</div><div><br></div><div>I ha=
ve uploaded a new version of the draft addressing the following:</div><div>=
<br></div><div>- proposed single object invocation is now similar to placem=
ent new</div><div><br></div><div>- there is now an Annex 2 defining a propo=
sed <font face=3D"courier new,monospace">std::relocate_or_move</font></div>=
<div><br></div><div>- proposed implicit declaration rules have been relaxed=
, so that explicitly defaulting a special member does not block implicit re=
locator declaration</div><div><br></div><div>- added explicit statement tha=
t lifetime of object in original location ceases when outermost=C2=A0reloca=
tor completes</div><div><br></div><div>- added explicit statement that invo=
cation of subobject relocator outside of outer object relocation is undefin=
ed behavior</div><div><br></div><div>New version:</div><div><br></div><div>=
<a href=3D"http://denisbider.com/Relocator.pdf">http://denisbider.com/Reloc=
ator.pdf</a></div><div><br></div><div><br></div><div>> the second form s=
hould take an 'A[]' rather than an 'A*'.</div><div><br></di=
v><div>I have decided against this because the argument may in fact be a sl=
ice of an array, not a whole array. Overlapping=C2=A0memory is also explici=
tly supported, so=C2=A0I would not like to suggest that only a whole array =
may be passed.</div><div><br></div><div><br></div><div>>=C2=A0 (Which al=
so makes me wonder if relocation <br>> should be const w.r.t. the old ob=
ject?) <br></div><div><br></div><div>I think not, because:</div><div><br></=
div><div>- the user may want to explicitly destroy subobjects if initializi=
ng their counterparts via means other than relocation;</div><div><br></div>=
<div>- the user may want to zero out memory being moved from.</div><div><br=
></div><div><br></div><div>> I'm not sure I agree that argument orde=
r for a cting-dtor</div><div>> is=C2=A0counterintuitive :-).</div><div><=
br></div><div>Besides whether or not=C2=A0cting-dtor syntax is intuitive -=
=C2=A0there's the additional issue that it doesn't blend well with =
this:</div><div><br></div><div>>>A(A& x) : B(std::move(x)) { x.B:=
:~B(); }</div><div><br></div><div>Providing a way to do this with destructo=
r-like syntax would=C2=A0be inventing alternate syntax for something=C2=A0w=
e already have.</div><div><br></div><div><br></div><div>> I've seen =
try_realloc more often than realloc_in_place.</div><div><br></div><div>I fi=
nd <font face=3D"courier new,monospace">realloc_in_place</font> more descri=
ptive. Strictly speaking, the existing <font face=3D"courier new,monospace"=
>realloc</font> already has "try" implied, since it won't blo=
ck or abort the program if it fails. So the "try" is implied, and=
what one really wants to express is which sub-step of <font face=3D"courie=
r new,monospace">realloc</font> one is attempting.</div><div><br></div><div=
><br></div><div>>=C2=A0if you are growing a container in order to do a</=
div><div>> middle insertion, and cannot grow in place,</div><div>> it=
is more efficient to allocate uninitialized</div><div>> memory and do a=
piecewise move </div><div><br></div><div>Interesting point, very true.</di=
v><div><br><br>On Tuesday, August 11, 2015 at 8:22:44 AM UTC-6, Matthew Woe=
hlke wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;">On 2015-08-08 04:37, <a onmou=
sedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.h=
ref=3D'javascript:';return true;" href=3D"javascript:" target=3D"_b=
lank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"-Hz7uui9AQAJ">isocp...@deni=
sbider.com</a> wrote:
<br>> I have published an updated draft:
<br>> <a onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.denisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ';return true;" onclick=3D"this.href=
=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.denisbider.com%2FRel=
ocator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNHgUlQIpAeID2fhoohuUg7hdvVOsQ&=
#39;;return true;" href=3D"http://www.denisbider.com/Relocator.pdf" target=
=3D"_blank" rel=3D"nofollow">http://www.denisbider.com/<wbr>Relocator.pdf</=
a>
<br>>=20
<br>>> In the defaulted example, s.b. ~int(int&).
<br>>=20
<br>> Good point, done that.
<br>
<br>Thanks!
<br>
<br>>> The multiple object helper should work
<br>>> on overlapping memory.
<br>>=20
<br>> It should indeed. :) Fixed!
<br>
<br>Thanks!
<br>
<br>>> Should(n't) the cting-dtor be implicit-default if the
<br>>> class has a) a *default* move ctor *or copy ctor*,
<br>>> *and* b) a default dtor, whether or not such are declared?
<br>>=20
<br>> Hmm. I wouldn't necessarily mind, but [...]
<br>>=20
<br>> For consistency as well as safety, it would make sense to me to us=
e the=20
<br>> same rules for the relocator.
<br>
<br>To revisit this, my main "concern" is to not suppress relocat=
ability for
<br>classes that are trivially relocatable, merely because a copy/move ctor
<br>or dtor was explicitly defaulted. IOW, relocation should always be
<br>available if the default implementation is provably correct. Otherwise
<br>we are penalizing existing code needlessly.
<br>
<br>
<br>Er... on that note, I just realized, we probably should make it UB to
<br>invoke the relocator on an object's base class outside of the reloc=
ator
<br>itself doing
<br>
<br>IOW, this is UB:
<br>
<br>=C2=A0 class Foo { public: virtual ~Foo(); ... };
<br>=C2=A0 class Bar : public Foo { ... };
<br>
<br>=C2=A0 auto pfoo1 =3D new Bar;
<br>=C2=A0 auto pfoo2 =3D (Foo*)malloc(sizeof(Foo));
<br>=C2=A0 pfoo1-> >>(*pfoo2);
<br>
<br>I don't see that this should be a problem with the proposal, since =
the
<br>main use case is containers where the final type is definitely known an=
d
<br>the same on both ends of the relocation, but it would be possible to
<br>write code like the above, and I don't see offhand how such code co=
uld
<br>be made to do anything reasonable.
<br>
<br>>> I feel fairly strongly that there should be a cutoff point
<br>>> for which we can use the same syntax to relocate
<br>>> objects that can't be simply relocated.
<br>>=20
<br>> I agree, but I think it should be at a level above this. I have ad=
ded a=20
<br>> discussion in the Rationales section.
<br>
<br>I can live with it, I guess. I'd feel better if the proposal also
<br>specified such function, though. (std::relocate?)
<br>
<br>>> I'm not entirely confident that the composition case is
<br>>> solved. As worded, the class members are relocated
<br>>> after the base class has been destroyed
<br>>=20
<br>> The relocator performs the tasks of both a constructor and a destr=
uctor, so=20
<br>> one of the two orders have to be chosen. I have added a section fo=
r this in=20
<br>> the Rationales section.
<br>>=20
<br>> I hope also that calling the special member a "relocator"=
;; expressing its=20
<br>> duality and impartiality, rather than a bias toward construction o=
r=20
<br>> destruction; might also help alleviate this concern.
<br>
<br>The only "true" solution I can envision is that the old base =
is not
<br>destroyed until the new object is fully constructed. This would conflic=
t
<br>with the notion of relocation destroying the (old copy of the) thing
<br>relocated.
<br>
<br>On the other hand, it's expected that relocation does not change th=
e
<br>actual bytes of the old object, so if relocation of the derived type
<br>needs to read those, it can. (Which also makes me wonder if relocation
<br>should be const w.r.t. the old object?)
<br>
<br>Anyway, still just thinking out loud, really...
<br>
<br>
<br>
<br>Okay, on to the new draft...
<br>
<br>I'm not sure I agree that argument order for a cting-dtor is
<br>counterintuitive :-). Basically, the question here is if we use push
<br>order (source first) or pull order (destination first). You're usin=
g
<br>pull order, which honestly, IMHO is counterintuitive :-). OTOH, memcpy
<br>also uses pull order. Essentially this is the same as the AT&T vs. =
Intel
<br>assembly dialect... as much a matter of personal taste as anything.
<br>
<br>That said, I'd probably keep the static operator order as-is for
<br>consistency with memcpy. The only other comment I'd make is that I =
feel
<br>like there should be some indication that the source is destroyed by th=
e
<br>call. This is accomplished by cting-dtor, as you're calling a dtor.=
It's
<br>also accomplished by e.g. 'T const~' (not sure if there should =
also be a
<br>'&' there, or if '~' should imply by-reference...).
<br>
<br>Pedantic: I want to say I've seen try_realloc more often than
<br>realloc_in_place. Not terribly important however since AFAIK neither
<br>exists yet.
<br>
<br>Last, and not a comment on the paper as such, we really could use such =
a
<br>function. Besides allowing us to work around using straight realloc (an=
d
<br>thus as mentioned, causing problems for static analysis tools), it may
<br>be the case that a realloc is less efficient. As I just pointed out on
<br>the Qt list, if you are growing a container in order to do a middle
<br>insertion, and cannot grow in place, it is more efficient to allocate
<br>uninitialized memory and do a piecewise move (which we can do with the
<br>proposal in a "correct" manner) of the portions before and af=
ter the
<br>insertion point to their correct final locations.
<br>
<br>
<br>p.s. FWIW I do prefer the type trait names 'is_[trivially_]relocata=
ble' :-).
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_5884_61882751.1439322355381--
------=_Part_5883_731942981.1439322355380--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 13 Aug 2015 12:12:03 -0400
Raw View
On 2015-08-11 15:45, isocppgroup@denisbider.com wrote:
> Good points, thank you!
>
> I have uploaded a new version of the draft addressing the following:
Finally read it; sorry it took so long.
Thanks for the improved examples section!
I still wonder if the indirection for the relocation operator shouldn't
somehow indicate that the parameter will be destroyed when the outermost
relocation completes. (If not 'T~'/'T~&', I wonder if it should at least
be a 'T&&'? Not sure though...)
> - proposed single object invocation is now similar to placement new
Cool :-).
> - there is now an Annex 2 defining a proposed std::relocate_or_move
Cool :-).
I wonder if there should also be single-object versions?
Nit: Might want to say, instead of "std::relocate, defined as" with
"might be defined as", in case implementations need to insert some
compiler voodoo to denote creation and deletion of objects in the
memmove case. (Presumably, the relocation operator has this built in,
but the trivial case isn't calling that...) Or, just if libraries come
up with some better implementation. I don't think the actual definition
needs to be codified, just the effect.
> - proposed implicit declaration rules have been relaxed, so that explicitly
> defaulting a special member does not block implicit relocator declaration
Cool; thanks :-).
> - added explicit statement that lifetime of object in original location
> ceases when outermost relocator completes
Cool :-). I think we needed this, and your wording LGTM. Thanks.
> - added explicit statement that invocation of subobject relocator outside
> of outer object relocation is undefined behavior
Erk... yes, it had better be ;-). Good catch; thanks.
Other comments:
I think this isn't exactly an omission vs. a language loophole that
should be closed, but the relocator should also be deleted if any
subobject *lacks* a relocator (i.e. "not declared"). Or if not declared
and the conditions for implicit declaration are not met. (Both will
close the loophole, the former might be preferred however.)
I'm not sure this is as tightly coupled to realloc_in_place as is
suggested. If we have realloc_in_place, we don't need relocation for the
case where that succeeds. If we assume that realloc always fails, we
don't see any benefit from realloc_in_place. (That's not to say that we
don't *want* realloc_in_place, just that Annex 1 makes it sound like
both are significantly less useful without the other, which I don't
believe is true. I think they are closer to orthogonal.)
Overall, looks very good; thanks again!
>> the second form should take an 'A[]' rather than an 'A*'.
>
> I have decided against this because the argument may in fact be a slice of
> an array, not a whole array. Overlapping memory is also explicitly
> supported, so I would not like to suggest that only a whole array may be
> passed.
Okay, I can follow that.
>> (Which also makes me wonder if relocation should be const w.r.t.
>> the old object?)
>
> I think not, because:
>
> - the user may want to explicitly destroy subobjects if initializing their
> counterparts via means other than relocation;
>
> - the user may want to zero out memory being moved from.
These are good points, but can cut both ways. Where you run into
problems is if the base class relocator fiddles with memory that the
derived class still needed.
I'm not saying I feel strongly about it either way, just trying to
explore the possible consequences of either decision.
>> I've seen try_realloc more often than realloc_in_place.
>
> I find realloc_in_place more descriptive.
Fair enough; I meant it more as an observation.
--
Matthew
--
---
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: isocppgroup@denisbider.com
Date: Thu, 13 Aug 2015 19:54:16 -0700 (PDT)
Raw View
------=_Part_199_895213537.1439520856870
Content-Type: multipart/alternative;
boundary="----=_Part_200_1376500474.1439520856871"
------=_Part_200_1376500474.1439520856871
Content-Type: text/plain; charset=UTF-8
Thanks for your reply!
> Finally read it; sorry it took so long.
No worries at all.
I have uploaded a new version again, based on this feedback:
http://denisbider.com/Relocator.pdf
- It now has a proper proposal number, P0023, currently R0.
- It adds a single-object version of relocate_or_move, as suggested.
- It switches around Annex 1 and Annex 2, so that relocate_or_move is in
Annex 1, reflecting it's more central.
- Changed wording related to realloc_in_place, now in Annex 2, to make it
clearer that it's related to, but not essential to the proposal.
- Added discussion headings "Why not a const reference?" and "Why not an
rvalue reference?"
> I still wonder if the indirection for the relocation
> operator shouldn't somehow indicate that the
> parameter will be destroyed when the outermost
> relocation completes. (If not 'T~'/'T~&', I wonder
> if it should at least be a 'T&&'? Not sure though...)
The problem with an rvalue reference is that you then have to consistently
do this:
>>A(A&& x) : >>B(std::move(x)), >>c(std::move(x.c)) {}
I think this would be inconvenience for the sake of inconvenience alone.
Not much is gained, since an rvalue reference is not needed to e.g. resolve
an overload conflict.
A new reference type is a whole new animal altogether and probably not
warranted as long as this would be the only usage case. There is no
technical problem we'd be solving with a new reference type, just a
subjective problem of indication.
I would argue that indication is already handled sufficiently by the syntax
>>A, so that there's no need to handle it additionally via reference type,
also.
> Might want to say, instead of "std::relocate,
> defined as" with "might be defined as",
Good point. I have changed that to "behaving as follows".
> the relocator should also be deleted if any
> subobject *lacks* a relocator (i.e. "not declared").
Good point. I have added this stipulation.
> I'm not sure this is as tightly coupled to
> realloc_in_place as is suggested.
I agree, the championing of realloc_in_place was overdone. I have toned it
down to make it clear that the relocator proposal stands on its own,
without it. :-)
> Where you run into problems is if the base
> class relocator fiddles with memory that the
> derived class still needed.
True. However, I'd prefer for modification of the original object to be
defined behavior, and to let the user beware and not shoot themselves in
the foot; rather than to preclude access "for yer protection". :-)
On Thursday, August 13, 2015 at 10:12:15 AM UTC-6, Matthew Woehlke wrote:
> On 2015-08-11 15:45, isocp...@denisbider.com <javascript:> wrote:
> > Good points, thank you!
> >
> > I have uploaded a new version of the draft addressing the following:
>
> Finally read it; sorry it took so long.
>
> Thanks for the improved examples section!
>
> I still wonder if the indirection for the relocation operator shouldn't
> somehow indicate that the parameter will be destroyed when the outermost
> relocation completes. (If not 'T~'/'T~&', I wonder if it should at least
> be a 'T&&'? Not sure though...)
>
> > - proposed single object invocation is now similar to placement new
>
> Cool :-).
>
> > - there is now an Annex 2 defining a proposed std::relocate_or_move
>
> Cool :-).
>
> I wonder if there should also be single-object versions?
>
> Nit: Might want to say, instead of "std::relocate, defined as" with
> "might be defined as", in case implementations need to insert some
> compiler voodoo to denote creation and deletion of objects in the
> memmove case. (Presumably, the relocation operator has this built in,
> but the trivial case isn't calling that...) Or, just if libraries come
> up with some better implementation. I don't think the actual definition
> needs to be codified, just the effect.
>
> > - proposed implicit declaration rules have been relaxed, so that
> explicitly
> > defaulting a special member does not block implicit relocator
> declaration
>
> Cool; thanks :-).
>
> > - added explicit statement that lifetime of object in original location
> > ceases when outermost relocator completes
>
> Cool :-). I think we needed this, and your wording LGTM. Thanks.
>
> > - added explicit statement that invocation of subobject relocator
> outside
> > of outer object relocation is undefined behavior
>
> Erk... yes, it had better be ;-). Good catch; thanks.
>
>
> Other comments:
>
> I think this isn't exactly an omission vs. a language loophole that
> should be closed, but the relocator should also be deleted if any
> subobject *lacks* a relocator (i.e. "not declared"). Or if not declared
> and the conditions for implicit declaration are not met. (Both will
> close the loophole, the former might be preferred however.)
>
> I'm not sure this is as tightly coupled to realloc_in_place as is
> suggested. If we have realloc_in_place, we don't need relocation for the
> case where that succeeds. If we assume that realloc always fails, we
> don't see any benefit from realloc_in_place. (That's not to say that we
> don't *want* realloc_in_place, just that Annex 1 makes it sound like
> both are significantly less useful without the other, which I don't
> believe is true. I think they are closer to orthogonal.)
>
> Overall, looks very good; thanks again!
>
> >> the second form should take an 'A[]' rather than an 'A*'.
> >
> > I have decided against this because the argument may in fact be a slice
> of
> > an array, not a whole array. Overlapping memory is also explicitly
> > supported, so I would not like to suggest that only a whole array may be
> > passed.
>
> Okay, I can follow that.
>
> >> (Which also makes me wonder if relocation should be const w.r.t.
> >> the old object?)
> >
> > I think not, because:
> >
> > - the user may want to explicitly destroy subobjects if initializing
> their
> > counterparts via means other than relocation;
> >
> > - the user may want to zero out memory being moved from.
>
> These are good points, but can cut both ways. Where you run into
> problems is if the base class relocator fiddles with memory that the
> derived class still needed.
>
> I'm not saying I feel strongly about it either way, just trying to
> explore the possible consequences of either decision.
>
> >> I've seen try_realloc more often than realloc_in_place.
> >
> > I find realloc_in_place more descriptive.
>
> Fair enough; I meant it more as an observation.
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_200_1376500474.1439520856871
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Thanks for your reply!</div><div><br></div><div>> =
Finally read it; sorry it took so long. </div><div><br></div><div>No worrie=
s at all.</div><div><br></div><div>I have uploaded a new=C2=A0version again=
, based on this feedback:</div><div><br></div><div><a href=3D"http://denisb=
ider.com/Relocator.pdf">http://denisbider.com/Relocator.pdf</a></div><div><=
br></div><div>- It now has a proper proposal number, P0023, currently R0.</=
div><div><br></div><div>- It adds a single-object version of <font face=3D"=
courier new,monospace">relocate_or_move</font>, as suggested.</div><div><br=
></div><div>- It switches around Annex 1 and Annex 2, so that <font face=3D=
"courier new,monospace">relocate_or_move</font> is in Annex 1,=C2=A0reflect=
ing it's=C2=A0more central.</div><div><br></div><div>- Changed wording =
related to <font face=3D"courier new,monospace">realloc_in_place</font>, no=
w in=C2=A0Annex 2, to make it clearer that it's related to, but not ess=
ential to the proposal.</div><div><br></div><div>- Added discussion heading=
s "Why not a const reference?" and "Why not an rvalue refere=
nce?"</div><div><br></div><div><br></div><div><br></div><div>> I st=
ill wonder if the indirection for the relocation</div><div>> operator sh=
ouldn't=C2=A0somehow indicate that the</div><div>> parameter will be=
destroyed when the outermost <br>> relocation completes. (If not 'T=
~'/'T~&', I wonder</div><div>> if it should at least=C2=
=A0be a 'T&&'? Not sure though...) <br></div><div><br></div=
><div>The problem with an rvalue reference is that you then have to consist=
ently do this:</div><div><br></div><div><font color=3D"#000000" face=3D"Tim=
es New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0<=
/span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font=
-size: 10pt; mso-fareast-font-family: "Times New Roman";"><span s=
tyle=3D"mso-spacerun: yes;">=C2=A0 </span>>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font=
-family: "Times New Roman";">A</span><span style=3D"color: rgb(48=
, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-famil=
y: "Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "T=
imes New Roman";">A</span><span style=3D"color: rgb(48, 128, 128); fon=
t-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times N=
ew Roman";">&&</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times Ne=
w Roman";"> x</span><span style=3D"color: rgb(48, 128, 128); font-fami=
ly: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Rom=
an";">)</span><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt; mso-fareast-font-family: "Times New Roman";"=
> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">:</spa=
n><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10=
pt; mso-fareast-font-family: "Times New Roman";"> </span><span st=
yle=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; ms=
o-fareast-font-family: "Times New Roman";">>></span><span s=
tyle=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";">B</span><span style=3D"co=
lor: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-fareast=
-font-family: "Times New Roman";">(</span><span style=3D"color: r=
gb(0, 102, 238); font-family: Consolas; font-size: 10pt; mso-fareast-font-f=
amily: "Times New Roman";">std</span><span style=3D"color: rgb(64=
, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family=
: "Times New Roman";">::</span><span style=3D"color: rgb(0, 0, 32=
); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "T=
imes New Roman";">move</span><span style=3D"color: rgb(48, 128, 128); =
font-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Time=
s New Roman";">(</span><span style=3D"color: rgb(0, 0, 32); font-famil=
y: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roma=
n";">x</span><span style=3D"color: rgb(48, 128, 128); font-family: Con=
solas; font-size: 10pt; mso-fareast-font-family: "Times New Roman"=
;;">))</span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas;=
font-size: 10pt; mso-fareast-font-family: "Times New Roman";">,<=
/span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size=
: 10pt; mso-fareast-font-family: "Times New Roman";"> </span><spa=
n style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt=
; mso-fareast-font-family: "Times New Roman";">>></span><sp=
an style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt; m=
so-fareast-font-family: "Times New Roman";">c</span><span style=
=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt; mso-f=
areast-font-family: "Times New Roman";">(</span><span style=3D"co=
lor: rgb(0, 102, 238); font-family: Consolas; font-size: 10pt; mso-fareast-=
font-family: "Times New Roman";">std</span><span style=3D"color: =
rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; mso-fareast-font-=
family: "Times New Roman";">::</span><span style=3D"color: rgb(0,=
0, 32); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &=
quot;Times New Roman";">move</span><span style=3D"color: rgb(48, 128, =
128); font-family: Consolas; font-size: 10pt; mso-fareast-font-family: &quo=
t;Times New Roman";">(</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt; mso-fareast-font-family: "Times Ne=
w Roman";">x</span><span style=3D"color: rgb(48, 128, 128); font-famil=
y: Consolas; font-size: 10pt; mso-fareast-font-family: "Times New Roma=
n";">.</span><span style=3D"color: rgb(0, 0, 32); font-family: Consola=
s; font-size: 10pt; mso-fareast-font-family: "Times New Roman";">=
c</span><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; fon=
t-size: 10pt; mso-fareast-font-family: "Times New Roman";">))</sp=
an><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 1=
0pt; mso-fareast-font-family: "Times New Roman";"> </span><span s=
tyle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt; ms=
o-fareast-font-family: "Times New Roman";">{}</span></p><font col=
or=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt =
320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732=
..8pt;"><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-siz=
e: 10pt; mso-fareast-font-family: "Times New Roman";">=C2=A0</spa=
n></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font></div><div><br></div><div><div>I think this would be inconvenience f=
or the sake of inconvenience alone. Not much is gained, since an rvalue ref=
erence is not needed to e.g. resolve an overload conflict.</div><div><br></=
div><div>A new reference type is a whole new animal altogether and probably=
not warranted as long as this would be the only usage case. There is no te=
chnical problem we'd be solving with a new reference type, just a subje=
ctive problem of indication.</div><div><br></div><div>I would argue that in=
dication is already handled sufficiently by the syntax <font face=3D"courie=
r new,monospace">>>A</font>, so that there's no need to handle it=
additionally via reference type, also.</div><div><br></div><div><br></div>=
<div>> Might want to say, instead of "std::relocate,</div><div>>=
defined as" with=C2=A0"might be defined as",</div><div><br>=
</div><div>Good point. I have changed that to "behaving as follows&quo=
t;.</div><div><br></div><div><br></div><div>> the relocator should also =
be deleted if any <br>> subobject *lacks* a relocator (i.e. "not de=
clared").</div><div><br></div><div>Good point. I have added this stipu=
lation.</div><div><br></div><div><br></div><div>> I'm not sure this =
is as tightly coupled to</div><div>> realloc_in_place as is suggested.</=
div><div><br></div><div>I agree, the championing of <font face=3D"courier n=
ew,monospace">realloc_in_place</font> was overdone. I have toned it down to=
make it clear that the relocator proposal stands on its own, without it. :=
-)</div><div><br></div><div><br></div><div>> Where you run into problems=
is if the base</div><div>> class relocator fiddles with memory that the=
<br>> derived class still needed. <br></div><div><br></div><div>True. H=
owever, I'd prefer for modification of the original object to be define=
d behavior, and to let the user beware and not shoot themselves=C2=A0in the=
foot; rather than to preclude access "for yer protection". :-)</=
div></div><div><br></div><div><br>On Thursday, August 13, 2015 at 10:12:15 =
AM UTC-6, Matthew Woehlke wrote:</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(=
204, 204, 204); border-left-width: 1px; border-left-style: solid;">On 2015-=
08-11 15:45, <a onmousedown=3D"this.href=3D'javascript:';return tru=
e;" onclick=3D"this.href=3D'javascript:';return true;" href=3D"java=
script:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"-0cZvA=
thAgAJ">isocp...@denisbider.com</a> wrote:
<br>> Good points, thank you!
<br>>=20
<br>> I have uploaded a new version of the draft addressing the followin=
g:
<br>
<br>Finally read it; sorry it took so long.
<br>
<br>Thanks for the improved examples section!
<br>
<br>I still wonder if the indirection for the relocation operator shouldn&#=
39;t
<br>somehow indicate that the parameter will be destroyed when the outermos=
t
<br>relocation completes. (If not 'T~'/'T~&', I wonder =
if it should at least
<br>be a 'T&&'? Not sure though...)
<br>
<br>> - proposed single object invocation is now similar to placement ne=
w
<br>
<br>Cool :-).
<br>
<br>> - there is now an Annex 2 defining a proposed std::relocate_or_mov=
e
<br>
<br>Cool :-).
<br>
<br>I wonder if there should also be single-object versions?
<br>
<br>Nit: Might want to say, instead of "std::relocate, defined as"=
; with
<br>"might be defined as", in case implementations need to insert=
some
<br>compiler voodoo to denote creation and deletion of objects in the
<br>memmove case. (Presumably, the relocation operator has this built in,
<br>but the trivial case isn't calling that...) Or, just if libraries c=
ome
<br>up with some better implementation. I don't think the actual defini=
tion
<br>needs to be codified, just the effect.
<br>
<br>> - proposed implicit declaration rules have been relaxed, so that e=
xplicitly=20
<br>> defaulting a special member does not block implicit relocator decl=
aration
<br>
<br>Cool; thanks :-).
<br>
<br>> - added explicit statement that lifetime of object in original loc=
ation=20
<br>> ceases when outermost relocator completes
<br>
<br>Cool :-). I think we needed this, and your wording LGTM. Thanks.
<br>
<br>> - added explicit statement that invocation of subobject relocator =
outside=20
<br>> of outer object relocation is undefined behavior
<br>
<br>Erk... yes, it had better be ;-). Good catch; thanks.
<br>
<br>
<br>Other comments:
<br>
<br>I think this isn't exactly an omission vs. a language loophole that
<br>should be closed, but the relocator should also be deleted if any
<br>subobject *lacks* a relocator (i.e. "not declared"). Or if no=
t declared
<br>and the conditions for implicit declaration are not met. (Both will
<br>close the loophole, the former might be preferred however.)
<br>
<br>I'm not sure this is as tightly coupled to realloc_in_place as is
<br>suggested. If we have realloc_in_place, we don't need relocation fo=
r the
<br>case where that succeeds. If we assume that realloc always fails, we
<br>don't see any benefit from realloc_in_place. (That's not to say=
that we
<br>don't *want* realloc_in_place, just that Annex 1 makes it sound lik=
e
<br>both are significantly less useful without the other, which I don't
<br>believe is true. I think they are closer to orthogonal.)
<br>
<br>Overall, looks very good; thanks again!
<br>
<br>>> the second form should take an 'A[]' rather than an &#=
39;A*'.
<br>>=20
<br>> I have decided against this because the argument may in fact be a =
slice of=20
<br>> an array, not a whole array. Overlapping memory is also explicitly=
=20
<br>> supported, so I would not like to suggest that only a whole array =
may be=20
<br>> passed.
<br>
<br>Okay, I can follow that.
<br>
<br>>> (Which also makes me wonder if relocation should be const w.r.=
t.
<br>>> the old object?)
<br>>=20
<br>> I think not, because:
<br>>=20
<br>> - the user may want to explicitly destroy subobjects if initializi=
ng their=20
<br>> counterparts via means other than relocation;
<br>>=20
<br>> - the user may want to zero out memory being moved from.
<br>
<br>These are good points, but can cut both ways. Where you run into
<br>problems is if the base class relocator fiddles with memory that the
<br>derived class still needed.
<br>
<br>I'm not saying I feel strongly about it either way, just trying to
<br>explore the possible consequences of either decision.
<br>
<br>>> I've seen try_realloc more often than realloc_in_place.
<br>>=20
<br>> I find realloc_in_place more descriptive.
<br>
<br>Fair enough; I meant it more as an observation.
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<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 />
------=_Part_200_1376500474.1439520856871--
------=_Part_199_895213537.1439520856870--
.
Author: isocppgroup@denisbider.com
Date: Thu, 13 Aug 2015 19:58:53 -0700 (PDT)
Raw View
------=_Part_185_1486388530.1439521133556
Content-Type: multipart/alternative;
boundary="----=_Part_186_1888314699.1439521133557"
------=_Part_186_1888314699.1439521133557
Content-Type: text/plain; charset=UTF-8
Ville informs me that someone needs to champion this proposal in front of
the Evolution WG.
I reckon, if someone isn't found, the alternative is that it will be simply
disregarded.
Is anyone going to the next WG meeting who is super passionate about
efficient relocation, and wants to present this proposal?
If no one volunteers, I'll have to go to Hawaii, and you know how much I
would hate that. :)
I believe such a volunteer should be sufficiently comfortable with the
current state of the proposal as to be comfortable putting their name on
it. Since this person would be presenting and defending the proposal in
front of the EWG, I imagine they would be added to the proposal as
co-author.
On Thursday, August 13, 2015 at 8:54:17 PM UTC-6, isocp...@denisbider.com
wrote:
> Thanks for your reply!
>
> > Finally read it; sorry it took so long.
>
> No worries at all.
>
> I have uploaded a new version again, based on this feedback:
>
> http://denisbider.com/Relocator.pdf
>
> - It now has a proper proposal number, P0023, currently R0.
>
> - It adds a single-object version of relocate_or_move, as suggested.
>
> - It switches around Annex 1 and Annex 2, so that relocate_or_move is in
> Annex 1, reflecting it's more central.
>
> - Changed wording related to realloc_in_place, now in Annex 2, to make it
> clearer that it's related to, but not essential to the proposal.
>
> - Added discussion headings "Why not a const reference?" and "Why not an
> rvalue reference?"
>
>
>
> > I still wonder if the indirection for the relocation
> > operator shouldn't somehow indicate that the
> > parameter will be destroyed when the outermost
> > relocation completes. (If not 'T~'/'T~&', I wonder
> > if it should at least be a 'T&&'? Not sure though...)
>
> The problem with an rvalue reference is that you then have to consistently
> do this:
>
>
>
> >>A(A&& x) : >>B(std::move(x)), >>c(std::move(x.c)) {}
>
>
>
> I think this would be inconvenience for the sake of inconvenience alone.
> Not much is gained, since an rvalue reference is not needed to e.g. resolve
> an overload conflict.
>
> A new reference type is a whole new animal altogether and probably not
> warranted as long as this would be the only usage case. There is no
> technical problem we'd be solving with a new reference type, just a
> subjective problem of indication.
>
> I would argue that indication is already handled sufficiently by the
> syntax >>A, so that there's no need to handle it additionally via
> reference type, also.
>
>
> > Might want to say, instead of "std::relocate,
> > defined as" with "might be defined as",
>
> Good point. I have changed that to "behaving as follows".
>
>
> > the relocator should also be deleted if any
> > subobject *lacks* a relocator (i.e. "not declared").
>
> Good point. I have added this stipulation.
>
>
> > I'm not sure this is as tightly coupled to
> > realloc_in_place as is suggested.
>
> I agree, the championing of realloc_in_place was overdone. I have toned
> it down to make it clear that the relocator proposal stands on its own,
> without it. :-)
>
>
> > Where you run into problems is if the base
> > class relocator fiddles with memory that the
> > derived class still needed.
>
> True. However, I'd prefer for modification of the original object to be
> defined behavior, and to let the user beware and not shoot themselves in
> the foot; rather than to preclude access "for yer protection". :-)
>
>
> On Thursday, August 13, 2015 at 10:12:15 AM UTC-6, Matthew Woehlke wrote:
>
>> On 2015-08-11 15:45, isocp...@denisbider.com wrote:
>> > Good points, thank you!
>> >
>> > I have uploaded a new version of the draft addressing the following:
>>
>> Finally read it; sorry it took so long.
>>
>> Thanks for the improved examples section!
>>
>> I still wonder if the indirection for the relocation operator shouldn't
>> somehow indicate that the parameter will be destroyed when the outermost
>> relocation completes. (If not 'T~'/'T~&', I wonder if it should at least
>> be a 'T&&'? Not sure though...)
>>
>> > - proposed single object invocation is now similar to placement new
>>
>> Cool :-).
>>
>> > - there is now an Annex 2 defining a proposed std::relocate_or_move
>>
>> Cool :-).
>>
>> I wonder if there should also be single-object versions?
>>
>> Nit: Might want to say, instead of "std::relocate, defined as" with
>> "might be defined as", in case implementations need to insert some
>> compiler voodoo to denote creation and deletion of objects in the
>> memmove case. (Presumably, the relocation operator has this built in,
>> but the trivial case isn't calling that...) Or, just if libraries come
>> up with some better implementation. I don't think the actual definition
>> needs to be codified, just the effect.
>>
>> > - proposed implicit declaration rules have been relaxed, so that
>> explicitly
>> > defaulting a special member does not block implicit relocator
>> declaration
>>
>> Cool; thanks :-).
>>
>> > - added explicit statement that lifetime of object in original location
>> > ceases when outermost relocator completes
>>
>> Cool :-). I think we needed this, and your wording LGTM. Thanks.
>>
>> > - added explicit statement that invocation of subobject relocator
>> outside
>> > of outer object relocation is undefined behavior
>>
>> Erk... yes, it had better be ;-). Good catch; thanks.
>>
>>
>> Other comments:
>>
>> I think this isn't exactly an omission vs. a language loophole that
>> should be closed, but the relocator should also be deleted if any
>> subobject *lacks* a relocator (i.e. "not declared"). Or if not declared
>> and the conditions for implicit declaration are not met. (Both will
>> close the loophole, the former might be preferred however.)
>>
>> I'm not sure this is as tightly coupled to realloc_in_place as is
>> suggested. If we have realloc_in_place, we don't need relocation for the
>> case where that succeeds. If we assume that realloc always fails, we
>> don't see any benefit from realloc_in_place. (That's not to say that we
>> don't *want* realloc_in_place, just that Annex 1 makes it sound like
>> both are significantly less useful without the other, which I don't
>> believe is true. I think they are closer to orthogonal.)
>>
>> Overall, looks very good; thanks again!
>>
>> >> the second form should take an 'A[]' rather than an 'A*'.
>> >
>> > I have decided against this because the argument may in fact be a slice
>> of
>> > an array, not a whole array. Overlapping memory is also explicitly
>> > supported, so I would not like to suggest that only a whole array may
>> be
>> > passed.
>>
>> Okay, I can follow that.
>>
>> >> (Which also makes me wonder if relocation should be const w.r.t.
>> >> the old object?)
>> >
>> > I think not, because:
>> >
>> > - the user may want to explicitly destroy subobjects if initializing
>> their
>> > counterparts via means other than relocation;
>> >
>> > - the user may want to zero out memory being moved from.
>>
>> These are good points, but can cut both ways. Where you run into
>> problems is if the base class relocator fiddles with memory that the
>> derived class still needed.
>>
>> I'm not saying I feel strongly about it either way, just trying to
>> explore the possible consequences of either decision.
>>
>> >> I've seen try_realloc more often than realloc_in_place.
>> >
>> > I find realloc_in_place more descriptive.
>>
>> Fair enough; I meant it more as an observation.
>>
>> --
>> Matthew
>>
>>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_186_1888314699.1439521133557
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Ville informs me that someone needs to champion this =
proposal in front of the Evolution WG.</div><div><br></div><div>I reckon, i=
f someone isn't found,=C2=A0the alternative is that it will be simply d=
isregarded.</div><div><br></div><div>Is anyone going to the next WG meeting=
who is super passionate about efficient relocation, and wants to present t=
his proposal?</div><div><br></div><div>If no one volunteers, I'll have =
to go to Hawaii, and you know how much I would hate that. :)</div><div><br>=
</div><div>I believe such a volunteer should be sufficiently comfortable wi=
th the current state of the proposal as to be comfortable putting their nam=
e on it. Since this person would be presenting and defending the proposal i=
n front of the EWG, I imagine they would be=C2=A0added to the proposal=C2=
=A0as co-author.</div><div><br><br>On Thursday, August 13, 2015 at 8:54:17 =
PM UTC-6, isocp...@denisbider.com wrote:</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-col=
or: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">=
<div dir=3D"ltr"><div>Thanks for your reply!</div><div><br></div><div>> =
Finally read it; sorry it took so long. </div><div><br></div><div>No worrie=
s at all.</div><div><br></div><div>I have uploaded a new=C2=A0version again=
, based on this feedback:</div><div><br></div><div><a onmousedown=3D"this.h=
ref=3D'http://www.google.com/url?q\75http%3A%2F%2Fdenisbider.com%2FRelo=
cator.pdf\46sa\75D\46sntz\0751\46usg\75AFQjCNGRaVpviwtOSXhpXtDNRASkBLXVYw&#=
39;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fdenisbider.com%2FRelocator.pdf\46sa\75D\46sntz\0751\46usg\75A=
FQjCNGRaVpviwtOSXhpXtDNRASkBLXVYw';return true;" href=3D"http://denisbi=
der.com/Relocator.pdf" target=3D"_blank" rel=3D"nofollow">http://denisbider=
..com/<wbr>Relocator.pdf</a></div><div><br></div><div>- It now has a proper =
proposal number, P0023, currently R0.</div><div><br></div><div>- It adds a =
single-object version of <font face=3D"courier new,monospace">relocate_or_m=
ove</font>, as suggested.</div><div><br></div><div>- It switches around Ann=
ex 1 and Annex 2, so that <font face=3D"courier new,monospace">relocate_or_=
move</font> is in Annex 1,=C2=A0reflecting it's=C2=A0more central.</div=
><div><br></div><div>- Changed wording related to <font face=3D"courier new=
,monospace">realloc_in_place</font>, now in=C2=A0Annex 2, to make it cleare=
r that it's related to, but not essential to the proposal.</div><div><b=
r></div><div>- Added discussion headings "Why not a const reference?&q=
uot; and "Why not an rvalue reference?"</div><div><br></div><div>=
<br></div><div><br></div><div>> I still wonder if the indirection for th=
e relocation</div><div>> operator shouldn't=C2=A0somehow indicate th=
at the</div><div>> parameter will be destroyed when the outermost <br>&g=
t; relocation completes. (If not 'T~'/'T~&', I wonder</=
div><div>> if it should at least=C2=A0be a 'T&&'? Not su=
re though...) <br></div><div><br></div><div>The problem with an rvalue refe=
rence is that you then have to consistently do this:</div><div><br></div><d=
iv><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"=
Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(48, 128, 128); font-family: Co=
nsolas; font-size: 10pt;"><span>=C2=A0 </span>>></span><span style=3D=
"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">A</span><sp=
an style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10p=
t;">(</span><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; fon=
t-size: 10pt;">A</span><span style=3D"color: rgb(48, 128, 128); font-family=
: Consolas; font-size: 10pt;">&&</span><span style=3D"color: rgb(0,=
0, 32); font-family: Consolas; font-size: 10pt;"> x</span><span style=3D"c=
olor: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">)</span><=
span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;=
"> </span><span style=3D"color: rgb(64, 96, 128); font-family: Consolas; fo=
nt-size: 10pt;">:</span><span style=3D"color: rgb(0, 0, 32); font-family: C=
onsolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, 128, 128);=
font-family: Consolas; font-size: 10pt;">>></span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">B</span><span s=
tyle=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">=
(</span><span style=3D"color: rgb(0, 102, 238); font-family: Consolas; font=
-size: 10pt;">std</span><span style=3D"color: rgb(64, 96, 128); font-family=
: Consolas; font-size: 10pt;">::</span><span style=3D"color: rgb(0, 0, 32);=
font-family: Consolas; font-size: 10pt;">move</span><span style=3D"color: =
rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">(</span><span s=
tyle=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">x</s=
pan><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-si=
ze: 10pt;">))</span><span style=3D"color: rgb(64, 96, 128); font-family: Co=
nsolas; font-size: 10pt;">,</span><span style=3D"color: rgb(0, 0, 32); font=
-family: Consolas; font-size: 10pt;"> </span><span style=3D"color: rgb(48, =
128, 128); font-family: Consolas; font-size: 10pt;">>></span><span st=
yle=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;">c</sp=
an><span style=3D"color: rgb(48, 128, 128); font-family: Consolas; font-siz=
e: 10pt;">(</span><span style=3D"color: rgb(0, 102, 238); font-family: Cons=
olas; font-size: 10pt;">std</span><span style=3D"color: rgb(64, 96, 128); f=
ont-family: Consolas; font-size: 10pt;">::</span><span style=3D"color: rgb(=
0, 0, 32); font-family: Consolas; font-size: 10pt;">move</span><span style=
=3D"color: rgb(48, 128, 128); font-family: Consolas; font-size: 10pt;">(</s=
pan><span style=3D"color: rgb(0, 0, 32); font-family: Consolas; font-size: =
10pt;">x</span><span style=3D"color: rgb(48, 128, 128); font-family: Consol=
as; font-size: 10pt;">.</span><span style=3D"color: rgb(0, 0, 32); font-fam=
ily: Consolas; font-size: 10pt;">c</span><span style=3D"color: rgb(48, 128,=
128); font-family: Consolas; font-size: 10pt;">))</span><span style=3D"col=
or: rgb(0, 0, 32); font-family: Consolas; font-size: 10pt;"> </span><span s=
tyle=3D"color: rgb(64, 96, 128); font-family: Consolas; font-size: 10pt;">{=
}</span></p><font color=3D"#000000" face=3D"Times New Roman" size=3D"3">
</font><p style=3D"background: rgb(246, 248, 255); margin: 0in 0in 0pt; lin=
e-height: normal;"><span style=3D"color: rgb(0, 0, 32); font-family: Consol=
as; font-size: 10pt;">=C2=A0</span></p><font color=3D"#000000" face=3D"Time=
s New Roman" size=3D"3">
</font></div><div><br></div><div><div>I think this would be inconvenience f=
or the sake of inconvenience alone. Not much is gained, since an rvalue ref=
erence is not needed to e.g. resolve an overload conflict.</div><div><br></=
div><div>A new reference type is a whole new animal altogether and probably=
not warranted as long as this would be the only usage case. There is no te=
chnical problem we'd be solving with a new reference type, just a subje=
ctive problem of indication.</div><div><br></div><div>I would argue that in=
dication is already handled sufficiently by the syntax <font face=3D"courie=
r new,monospace">>>A</font>, so that there's no need to handle it=
additionally via reference type, also.</div><div><br></div><div><br></div>=
<div>> Might want to say, instead of "std::relocate,</div><div>>=
defined as" with=C2=A0"might be defined as",</div><div><br>=
</div><div>Good point. I have changed that to "behaving as follows&quo=
t;.</div><div><br></div><div><br></div><div>> the relocator should also =
be deleted if any <br>> subobject *lacks* a relocator (i.e. "not de=
clared").</div><div><br></div><div>Good point. I have added this stipu=
lation.</div><div><br></div><div><br></div><div>> I'm not sure this =
is as tightly coupled to</div><div>> realloc_in_place as is suggested.</=
div><div><br></div><div>I agree, the championing of <font face=3D"courier n=
ew,monospace">realloc_in_place</font> was overdone. I have toned it down to=
make it clear that the relocator proposal stands on its own, without it. :=
-)</div><div><br></div><div><br></div><div>> Where you run into problems=
is if the base</div><div>> class relocator fiddles with memory that the=
<br>> derived class still needed. <br></div><div><br></div><div>True. H=
owever, I'd prefer for modification of the original object to be define=
d behavior, and to let the user beware and not shoot themselves=C2=A0in the=
foot; rather than to preclude access "for yer protection". :-)</=
div></div><div><br></div><div><br>On Thursday, August 13, 2015 at 10:12:15 =
AM UTC-6, Matthew Woehlke wrote:</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(=
204, 204, 204); border-left-width: 1px; border-left-style: solid;">On 2015-=
08-11 15:45, <a rel=3D"nofollow">isocp...@denisbider.com</a> wrote:
<br>> Good points, thank you!
<br>>=20
<br>> I have uploaded a new version of the draft addressing the followin=
g:
<br>
<br>Finally read it; sorry it took so long.
<br>
<br>Thanks for the improved examples section!
<br>
<br>I still wonder if the indirection for the relocation operator shouldn&#=
39;t
<br>somehow indicate that the parameter will be destroyed when the outermos=
t
<br>relocation completes. (If not 'T~'/'T~&', I wonder =
if it should at least
<br>be a 'T&&'? Not sure though...)
<br>
<br>> - proposed single object invocation is now similar to placement ne=
w
<br>
<br>Cool :-).
<br>
<br>> - there is now an Annex 2 defining a proposed std::relocate_or_mov=
e
<br>
<br>Cool :-).
<br>
<br>I wonder if there should also be single-object versions?
<br>
<br>Nit: Might want to say, instead of "std::relocate, defined as"=
; with
<br>"might be defined as", in case implementations need to insert=
some
<br>compiler voodoo to denote creation and deletion of objects in the
<br>memmove case. (Presumably, the relocation operator has this built in,
<br>but the trivial case isn't calling that...) Or, just if libraries c=
ome
<br>up with some better implementation. I don't think the actual defini=
tion
<br>needs to be codified, just the effect.
<br>
<br>> - proposed implicit declaration rules have been relaxed, so that e=
xplicitly=20
<br>> defaulting a special member does not block implicit relocator decl=
aration
<br>
<br>Cool; thanks :-).
<br>
<br>> - added explicit statement that lifetime of object in original loc=
ation=20
<br>> ceases when outermost relocator completes
<br>
<br>Cool :-). I think we needed this, and your wording LGTM. Thanks.
<br>
<br>> - added explicit statement that invocation of subobject relocator =
outside=20
<br>> of outer object relocation is undefined behavior
<br>
<br>Erk... yes, it had better be ;-). Good catch; thanks.
<br>
<br>
<br>Other comments:
<br>
<br>I think this isn't exactly an omission vs. a language loophole that
<br>should be closed, but the relocator should also be deleted if any
<br>subobject *lacks* a relocator (i.e. "not declared"). Or if no=
t declared
<br>and the conditions for implicit declaration are not met. (Both will
<br>close the loophole, the former might be preferred however.)
<br>
<br>I'm not sure this is as tightly coupled to realloc_in_place as is
<br>suggested. If we have realloc_in_place, we don't need relocation fo=
r the
<br>case where that succeeds. If we assume that realloc always fails, we
<br>don't see any benefit from realloc_in_place. (That's not to say=
that we
<br>don't *want* realloc_in_place, just that Annex 1 makes it sound lik=
e
<br>both are significantly less useful without the other, which I don't
<br>believe is true. I think they are closer to orthogonal.)
<br>
<br>Overall, looks very good; thanks again!
<br>
<br>>> the second form should take an 'A[]' rather than an &#=
39;A*'.
<br>>=20
<br>> I have decided against this because the argument may in fact be a =
slice of=20
<br>> an array, not a whole array. Overlapping memory is also explicitly=
=20
<br>> supported, so I would not like to suggest that only a whole array =
may be=20
<br>> passed.
<br>
<br>Okay, I can follow that.
<br>
<br>>> (Which also makes me wonder if relocation should be const w.r.=
t.
<br>>> the old object?)
<br>>=20
<br>> I think not, because:
<br>>=20
<br>> - the user may want to explicitly destroy subobjects if initializi=
ng their=20
<br>> counterparts via means other than relocation;
<br>>=20
<br>> - the user may want to zero out memory being moved from.
<br>
<br>These are good points, but can cut both ways. Where you run into
<br>problems is if the base class relocator fiddles with memory that the
<br>derived class still needed.
<br>
<br>I'm not saying I feel strongly about it either way, just trying to
<br>explore the possible consequences of either decision.
<br>
<br>>> I've seen try_realloc more often than realloc_in_place.
<br>>=20
<br>> I find realloc_in_place more descriptive.
<br>
<br>Fair enough; I meant it more as an observation.
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div></blockquote></div>
<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 />
------=_Part_186_1888314699.1439521133557--
------=_Part_185_1486388530.1439521133556--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 14 Aug 2015 12:51:08 -0400
Raw View
On 2015-08-13 22:54, isocppgroup@denisbider.com wrote:
> I have uploaded a new version again, based on this feedback:
>
> - It adds a single-object version of relocate_or_move, as suggested.
Cool; thanks again.
> - It switches around Annex 1 and Annex 2, so that relocate_or_move is in
> Annex 1, reflecting it's more central.
>
> - Changed wording related to realloc_in_place, now in Annex 2, to make it
> clearer that it's related to, but not essential to the proposal.
Minor point: the second memcpy in the final example should be a memmove ;-).
>> I still wonder if the indirection for the relocation
>> operator shouldn't somehow indicate that the
>> parameter will be destroyed when the outermost
>> relocation completes. (If not 'T~'/'T~&', I wonder
>> if it should at least be a 'T&&'? Not sure though...)
>
> The problem with an rvalue reference is that you then have to consistently
> do this:
>
> >>A(A&& x) : >>B(std::move(x)), >>c(std::move(x.c)) {}
Yes. I was sort-of assuming that we would special-case the relocation
operator to do an implicit std::move. But I can imagine lots of
squawking about that.
Hmm... I was going to ask about the case of relocating a single item
received as an rvalue-reference, but I guess relocate_or_move makes that
moot?
Anyway, I think I am sufficiently convinced that, at least, it should
await the committee's thoughts, which are surely better informed than
mine :-).
>> Might want to say, instead of "std::relocate,
>> defined as" with "might be defined as",
>
> Good point. I have changed that to "behaving as follows".
That's good too, and probably better than my suggestion :-). Thanks.
> I agree, the championing of realloc_in_place was overdone. I have toned it
> down to make it clear that the relocator proposal stands on its own,
> without it. :-)
:-)
--
Matthew
--
---
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: mihailnajdenov@gmail.com
Date: Fri, 20 Jul 2018 09:55:38 -0700 (PDT)
Raw View
------=_Part_6003_986759114.1532105738702
Content-Type: multipart/alternative;
boundary="----=_Part_6004_375801352.1532105738702"
------=_Part_6004_375801352.1532105738702
Content-Type: text/plain; charset="UTF-8"
On Friday, August 14, 2015 at 7:51:50 PM UTC+3, Matthew Woehlke wrote:
>
> On 2015-08-13 22:54, isocp...@denisbider.com <javascript:> wrote:
> > I have uploaded a new version again, based on this feedback:
> >
> > - It adds a single-object version of relocate_or_move, as suggested.
>
> Cool; thanks again.
>
> > - It switches around Annex 1 and Annex 2, so that relocate_or_move is in
> > Annex 1, reflecting it's more central.
> >
> > - Changed wording related to realloc_in_place, now in Annex 2, to make
> it
> > clearer that it's related to, but not essential to the proposal.
>
> Minor point: the second memcpy in the final example should be a memmove
> ;-).
>
> >> I still wonder if the indirection for the relocation
> >> operator shouldn't somehow indicate that the
> >> parameter will be destroyed when the outermost
> >> relocation completes. (If not 'T~'/'T~&', I wonder
> >> if it should at least be a 'T&&'? Not sure though...)
> >
> > The problem with an rvalue reference is that you then have to
> consistently
> > do this:
> >
> > >>A(A&& x) : >>B(std::move(x)), >>c(std::move(x.c)) {}
>
> Yes. I was sort-of assuming that we would special-case the relocation
> operator to do an implicit std::move. But I can imagine lots of
> squawking about that.
>
> Hmm... I was going to ask about the case of relocating a single item
> received as an rvalue-reference, but I guess relocate_or_move makes that
> moot?
>
> Anyway, I think I am sufficiently convinced that, at least, it should
> await the committee's thoughts, which are surely better informed than
> mine :-).
>
> >> Might want to say, instead of "std::relocate,
> >> defined as" with "might be defined as",
> >
> > Good point. I have changed that to "behaving as follows".
>
> That's good too, and probably better than my suggestion :-). Thanks.
>
> > I agree, the championing of realloc_in_place was overdone. I have toned
> it
> > down to make it clear that the relocator proposal stands on its own,
> > without it. :-)
>
> :-)
>
> --
> Matthew
>
Does anyone know what happened to this proposal and destructive move in
general? It seems the current [[trivially relocatable]] covers similar
ground, but it is not the same - it can't, well, move-destruct (AFAICC).
Is destructive move dead now, in favor of just marking the types, already "trivially
relocatable"?
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/258bb255-f100-4667-bd25-af470b6d5d5f%40isocpp.org.
------=_Part_6004_375801352.1532105738702
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, August 14, 2015 at 7:51:50 PM UTC+3, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-08=
-13 22:54, <a onmousedown=3D"this.href=3D'javascript:';return true;=
" onclick=3D"this.href=3D'javascript:';return true;" href=3D"javasc=
ript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"YYw2RMmx=
AgAJ">isocp...@denisbider.com</a> wrote:
<br>> I have uploaded a new version again, based on this feedback:
<br>>=20
<br>> - It adds a single-object version of relocate_or_move, as suggeste=
d.
<br>
<br>Cool; thanks again.
<br>
<br>> - It switches around Annex 1 and Annex 2, so that relocate_or_move=
is in=20
<br>> Annex 1, reflecting it's more central.
<br>>=20
<br>> - Changed wording related to realloc_in_place, now in Annex 2, to =
make it=20
<br>> clearer that it's related to, but not essential to the proposa=
l.
<br>
<br>Minor point: the second memcpy in the final example should be a memmove=
;-).
<br>
<br>>> I still wonder if the indirection for the relocation
<br>>> operator shouldn't somehow indicate that the
<br>>> parameter will be destroyed when the outermost=20
<br>>> relocation completes. (If not 'T~'/'T~&', =
I wonder
<br>>> if it should at least be a 'T&&'? Not sure tho=
ugh...)=20
<br>>=20
<br>> The problem with an rvalue reference is that you then have to cons=
istently=20
<br>> do this:
<br>>=20
<br>> =C2=A0 >>A(A&& x) : >>B(std::move(x)), >>=
;c(std::move(x.c)) {}
<br>
<br>Yes. I was sort-of assuming that we would special-case the relocation
<br>operator to do an implicit std::move. But I can imagine lots of
<br>squawking about that.
<br>
<br>Hmm... I was going to ask about the case of relocating a single item
<br>received as an rvalue-reference, but I guess relocate_or_move makes tha=
t
<br>moot?
<br>
<br>Anyway, I think I am sufficiently convinced that, at least, it should
<br>await the committee's thoughts, which are surely better informed th=
an
<br>mine :-).
<br>
<br>>> Might want to say, instead of "std::relocate,
<br>>> defined as" with "might be defined as",
<br>>=20
<br>> Good point. I have changed that to "behaving as follows"=
..
<br>
<br>That's good too, and probably better than my suggestion :-). Thanks=
..
<br>
<br>> I agree, the championing of realloc_in_place was overdone. I have =
toned it=20
<br>> down to make it clear that the relocator proposal stands on its ow=
n,=20
<br>> without it. :-)
<br>
<br>:-)
<br>
<br>--=20
<br>Matthew
<br></blockquote><div><br></div><div><br></div><div>Does anyone know what h=
appened to this proposal and destructive move in general? It seems the curr=
ent [[trivially relocatable]] covers similar ground, but it is not the same=
- it can't, well, move-destruct (AFAICC).</div><div><br></div><div>Is =
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: "Arial","He=
lvetica",sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">destruc=
tive move dead now, in favor of just marking the types, already "<span=
style=3D"display: inline !important; float: none; background-color: transp=
arent; color: rgb(34, 34, 34); font-family: "Arial","Helveti=
ca",sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;">trivially </=
span>relocatable"?</span></div><div>=C2=A0</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/258bb255-f100-4667-bd25-af470b6d5d5f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/258bb255-f100-4667-bd25-af470b6d5d5f=
%40isocpp.org</a>.<br />
------=_Part_6004_375801352.1532105738702--
------=_Part_6003_986759114.1532105738702--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Fri, 20 Jul 2018 16:23:44 -0700 (PDT)
Raw View
------=_Part_6755_581585786.1532129024372
Content-Type: multipart/alternative;
boundary="----=_Part_6756_1699092616.1532129024372"
------=_Part_6756_1699092616.1532129024372
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Friday, July 20, 2018 at 9:55:38 AM UTC-7, mihailn...@gmail.com wrote:
>
>
> Does anyone know what happened to this proposal and destructive move in=
=20
> general? It seems the current [[trivially relocatable]] covers similar=20
> ground, but it is not the same - it can't, well, move-destruct (AFAICC).
>
> Is destructive move dead now, in favor of just marking the types, already=
=20
> "trivially relocatable"?=20
>
My impression is that previous proposals to introduce a new first-class=20
spelling (such as Denis's >>T(T&)) have not made much headway against the=
=20
Committee. Therefore, both my upcoming P1144=20
<https://quuxplusone.github.io/blog/2018/07/18/announcing-trivially-relocat=
able/>=20
"Object relocation in terms of move plus destroy" and Niall's P1029=20
"[[move_relocates]]" try to express the idea in terms of composing existing=
=20
operations:
- P1144 says "always (relocate =3D move + destroy), and sometimes (relocate=
=3D=20
memcpy + drop)"
- P1029 says "sometimes (move =3D memcpy + drop + default-construct)"
I'd be interested to talk more about "[P1144] can't, well, move-destruct" =
=E2=80=94=20
perhaps in a new dedicated thread, though.
I'd also like to hear from anyone who was involved in actual discussions of=
=20
N4158, P0023, etc.
I have just now found the LEWG discussion of Pablo's N4034 (June 2014,=20
Rapperswil):
- http://wiki.edg.com/bin/view/Wg21rapperswil2014/N4034
And the EWG discussion of Pablo's N4158 (November 2014, Urbana):
- http://wiki.edg.com/bin/view/Wg21urbana-champaign/EvolutionWorkingGroup#N=
4158_Destructive_Move_Rev_1
It looks like things were generally favorable: LEWG sent it quickly to LWG,=
=20
LWG bounced it back to EWG due to the unexploredness of std::bless/launder=
=20
at the time, EWG expressed concern with the lack of std::bless/launder but=
=20
"encouraged more work in this direction" (of course); and then it fell into=
=20
a black hole and never emerged again.
My hope, as you can tell, is that now that we have explored ways of=20
blessing "regions of storage" so that they become "objects" (so that=20
std::vector is almost implementable these days! ;)) that some of EWG's=20
concerns may have been alleviated. Also, N4158 lacked a public=20
implementation that provably worked with things like allocators, whereas=20
P1144 thinks the proper interaction with allocators is so easy=20
<https://godbolt.org/g/K2EqMx> the paper doesn't even talk about them.
=E2=80=93Arthur
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/fb8001ef-9dbc-4016-a60f-a4dfa55f275c%40isocpp.or=
g.
------=_Part_6756_1699092616.1532129024372
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, July 20, 2018 at 9:55:38 AM UTC-7, mihailn...@g=
mail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div><br></div><div>Does anyone know what happened to this proposal and d=
estructive move in general? It seems the current [[trivially relocatable]] =
covers similar ground, but it is not the same - it can't, well, move-de=
struct (AFAICC).</div><div><br></div><div>Is <span style=3D"display:inline!=
important;float:none;background-color:transparent;color:rgb(34,34,34);font-=
family:"Arial","Helvetica",sans-serif;font-size:13px;fo=
nt-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;t=
ext-align:left;text-decoration:none;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px">destructive move dead now, in favor of ju=
st marking the types, already "<span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial","Helvetica",sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px">trivially </span>relocatable"?</span>=C2=A0</=
div></div></blockquote><div><br></div><div>My impression is that previous p=
roposals to introduce a new first-class spelling (such as Denis's <font=
face=3D"courier new, monospace">>>T(T&)</font>) have not made mu=
ch headway against the Committee. Therefore, both my upcoming <a href=3D"ht=
tps://quuxplusone.github.io/blog/2018/07/18/announcing-trivially-relocatabl=
e/">P1144</a> "Object relocation in terms of move plus destroy" a=
nd Niall's P1029 "[[move_relocates]]" try to express the idea=
in terms of composing existing operations:</div><div>- P1144 says "al=
ways (relocate =3D move + destroy), and sometimes (relocate =3D memcpy + dr=
op)"</div><div>- P1029 says "sometimes (move =3D memcpy + drop + =
default-construct)"</div><div><br></div><div>I'd be interested to =
talk more about "[P1144] can't, well, move-destruct" =E2=80=
=94 perhaps in a new dedicated thread, though.</div><div><br></div><div>I&#=
39;d also like to hear from anyone who was involved in actual discussions o=
f N4158, P0023, etc.</div><div><br></div><div>I have just now found the LEW=
G discussion of Pablo's N4034 (June 2014, Rapperswil):</div><div>-=C2=
=A0http://wiki.edg.com/bin/view/Wg21rapperswil2014/N4034</div><div>And the =
EWG discussion of Pablo's N4158 (November 2014, Urbana):</div><div>-=C2=
=A0http://wiki.edg.com/bin/view/Wg21urbana-champaign/EvolutionWorkingGroup#=
N4158_Destructive_Move_Rev_1</div><div><br></div><div>It looks like things =
were generally favorable: LEWG sent it quickly to LWG, LWG bounced it back =
to EWG due to the unexploredness of std::bless/launder at the time, EWG exp=
ressed concern with the lack of std::bless/launder but "encouraged mor=
e work in this direction" (of course); and then it fell into a black h=
ole and never emerged again.</div><div><br></div><div>My hope, as you can t=
ell, is that now that we have explored ways of blessing "regions of st=
orage" so that they become "objects" (so that std::vector is=
almost implementable these days! ;)) that some of EWG's concerns may h=
ave been alleviated. =C2=A0Also, N4158 lacked a public implementation that =
provably worked with things like allocators, whereas P1144 thinks the prope=
r interaction with allocators is=C2=A0<a href=3D"https://godbolt.org/g/K2Eq=
Mx">so easy</a> the paper doesn't even talk about them.</div><div><br><=
/div><div>=E2=80=93Arthur</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fb8001ef-9dbc-4016-a60f-a4dfa55f275c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fb8001ef-9dbc-4016-a60f-a4dfa55f275c=
%40isocpp.org</a>.<br />
------=_Part_6756_1699092616.1532129024372--
------=_Part_6755_581585786.1532129024372--
.
Author: mihailnajdenov@gmail.com
Date: Sat, 21 Jul 2018 08:25:38 -0700 (PDT)
Raw View
------=_Part_4199_509661726.1532186739049
Content-Type: multipart/alternative;
boundary="----=_Part_4200_974697302.1532186739050"
------=_Part_4200_974697302.1532186739050
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Thanks for the heads up! I will start a new topic about trivially reloc, as=
=20
I have few questions (and few concerns).
On Saturday, July 21, 2018 at 2:23:44 AM UTC+3, Arthur O'Dwyer wrote:
>
> On Friday, July 20, 2018 at 9:55:38 AM UTC-7, mihailn...@gmail.com wrote:
>>
>>
>> Does anyone know what happened to this proposal and destructive move in=
=20
>> general? It seems the current [[trivially relocatable]] covers similar=
=20
>> ground, but it is not the same - it can't, well, move-destruct (AFAICC).
>>
>> Is destructive move dead now, in favor of just marking the types,=20
>> already "trivially relocatable"?=20
>>
>
> My impression is that previous proposals to introduce a new first-class=
=20
> spelling (such as Denis's >>T(T&)) have not made much headway against the=
=20
> Committee. Therefore, both my upcoming P1144=20
> <https://quuxplusone.github.io/blog/2018/07/18/announcing-trivially-reloc=
atable/>=20
> "Object relocation in terms of move plus destroy" and Niall's P1029=20
> "[[move_relocates]]" try to express the idea in terms of composing existi=
ng=20
> operations:
> - P1144 says "always (relocate =3D move + destroy), and sometimes (reloca=
te=20
> =3D memcpy + drop)"
> - P1029 says "sometimes (move =3D memcpy + drop + default-construct)"
>
> I'd be interested to talk more about "[P1144] can't, well, move-destruct"=
=20
> =E2=80=94 perhaps in a new dedicated thread, though.
>
> I'd also like to hear from anyone who was involved in actual discussions=
=20
> of N4158, P0023, etc.
>
> I have just now found the LEWG discussion of Pablo's N4034 (June 2014,=20
> Rapperswil):
> - http://wiki.edg.com/bin/view/Wg21rapperswil2014/N4034
> And the EWG discussion of Pablo's N4158 (November 2014, Urbana):
> -=20
> http://wiki.edg.com/bin/view/Wg21urbana-champaign/EvolutionWorkingGroup#N=
4158_Destructive_Move_Rev_1
>
> It looks like things were generally favorable: LEWG sent it quickly to=20
> LWG, LWG bounced it back to EWG due to the unexploredness of=20
> std::bless/launder at the time, EWG expressed concern with the lack of=20
> std::bless/launder but "encouraged more work in this direction" (of=20
> course); and then it fell into a black hole and never emerged again.
>
> My hope, as you can tell, is that now that we have explored ways of=20
> blessing "regions of storage" so that they become "objects" (so that=20
> std::vector is almost implementable these days! ;)) that some of EWG's=20
> concerns may have been alleviated. Also, N4158 lacked a public=20
> implementation that provably worked with things like allocators, whereas=
=20
> P1144 thinks the proper interaction with allocators is so easy=20
> <https://godbolt.org/g/K2EqMx> the paper doesn't even talk about them.
>
> =E2=80=93Arthur
>
--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/777928c0-ca77-4e38-ade1-debe63e90910%40isocpp.or=
g.
------=_Part_4200_974697302.1532186739050
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Thanks for the heads up! I will start a new topic abo=
ut trivially reloc, as I have few questions (and few concerns).</div><div><=
br></div><div><br></div><br>On Saturday, July 21, 2018 at 2:23:44 AM UTC+3,=
Arthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
dir=3D"ltr">On Friday, July 20, 2018 at 9:55:38 AM UTC-7, <a>mihailn...@gm=
ail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div><br></div><div>Does anyone know what happened to this proposal and des=
tructive move in general? It seems the current [[trivially relocatable]] co=
vers similar ground, but it is not the same - it can't, well, move-dest=
ruct (AFAICC).</div><div><br></div><div>Is <span style=3D"display:inline!im=
portant;float:none;background-color:transparent;color:rgb(34,34,34);font-fa=
mily:"Arial","Helvetica",sans-serif;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">destructive move dead now, in favor of just=
marking the types, already "<span style=3D"display:inline!important;f=
loat:none;background-color:transparent;color:rgb(34,34,34);font-family:&quo=
t;Arial","Helvetica",sans-serif;font-size:13px;font-style:no=
rmal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:l=
eft;text-decoration:none;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px">trivially </span>relocatable"?</span>=C2=A0</di=
v></div></blockquote><div><br></div><div>My impression is that previous pro=
posals to introduce a new first-class spelling (such as Denis's <font f=
ace=3D"courier new, monospace">>>T(T&)</font>) have not made much=
headway against the Committee. Therefore, both my upcoming <a onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplus=
one.github.io%2Fblog%2F2018%2F07%2F18%2Fannouncing-trivially-relocatable%2F=
\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGEA9QMgWs5WBFLICjqL2WLBLKLIg';=
return true;" onclick=3D"this.href=3D'https://www.google.com/url?q\x3dh=
ttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2F2018%2F07%2F18%2Fannouncing-tri=
vially-relocatable%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGEA9QMgWs5WBF=
LICjqL2WLBLKLIg';return true;" href=3D"https://quuxplusone.github.io/bl=
og/2018/07/18/announcing-trivially-relocatable/" target=3D"_blank" rel=3D"n=
ofollow">P1144</a> "Object relocation in terms of move plus destroy&qu=
ot; and Niall's P1029 "[[move_relocates]]" try to express the=
idea in terms of composing existing operations:</div><div>- P1144 says &qu=
ot;always (relocate =3D move + destroy), and sometimes (relocate =3D memcpy=
+ drop)"</div><div>- P1029 says "sometimes (move =3D memcpy + dr=
op + default-construct)"</div><div><br></div><div>I'd be intereste=
d to talk more about "[P1144] can't, well, move-destruct" =E2=
=80=94 perhaps in a new dedicated thread, though.</div><div><br></div><div>=
I'd also like to hear from anyone who was involved in actual discussion=
s of N4158, P0023, etc.</div><div><br></div><div>I have just now found the =
LEWG discussion of Pablo's N4034 (June 2014, Rapperswil):</div><div>-=
=C2=A0<a onmousedown=3D"this.href=3D'http://www.google.com/url?q\x3dhtt=
p%3A%2F%2Fwiki.edg.com%2Fbin%2Fview%2FWg21rapperswil2014%2FN4034\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNHVWHV3zpAkwvd89fY5ZvHro3BJWg';return true=
;" onclick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2F=
wiki.edg.com%2Fbin%2Fview%2FWg21rapperswil2014%2FN4034\x26sa\x3dD\x26sntz\x=
3d1\x26usg\x3dAFQjCNHVWHV3zpAkwvd89fY5ZvHro3BJWg';return true;" href=3D=
"http://wiki.edg.com/bin/view/Wg21rapperswil2014/N4034" target=3D"_blank" r=
el=3D"nofollow">http://wiki.edg.com/bin/<wbr>view/Wg21rapperswil2014/N4034<=
/a></div><div>And the EWG discussion of Pablo's N4158 (November 2014, U=
rbana):</div><div>-=C2=A0<a onmousedown=3D"this.href=3D'http://www.goog=
le.com/url?q\x3dhttp%3A%2F%2Fwiki.edg.com%2Fbin%2Fview%2FWg21urbana-champai=
gn%2FEvolutionWorkingGroup%23N4158_Destructive_Move_Rev_1\x26sa\x3dD\x26snt=
z\x3d1\x26usg\x3dAFQjCNHOOvdJIqXsOFKinX3qd1OsitWdfA';return true;" oncl=
ick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwiki.ed=
g.com%2Fbin%2Fview%2FWg21urbana-champaign%2FEvolutionWorkingGroup%23N4158_D=
estructive_Move_Rev_1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHOOvdJIqXsOFK=
inX3qd1OsitWdfA';return true;" href=3D"http://wiki.edg.com/bin/view/Wg2=
1urbana-champaign/EvolutionWorkingGroup#N4158_Destructive_Move_Rev_1" targe=
t=3D"_blank" rel=3D"nofollow">http://wiki.edg.com/bin/<wbr>view/Wg21urbana-=
champaign/<wbr>EvolutionWorkingGroup#N4158_<wbr>Destructive_Move_Rev_1</a><=
/div><div><br></div><div>It looks like things were generally favorable: LEW=
G sent it quickly to LWG, LWG bounced it back to EWG due to the unexploredn=
ess of std::bless/launder at the time, EWG expressed concern with the lack =
of std::bless/launder but "encouraged more work in this direction"=
; (of course); and then it fell into a black hole and never emerged again.<=
/div><div><br></div><div>My hope, as you can tell, is that now that we have=
explored ways of blessing "regions of storage" so that they beco=
me "objects" (so that std::vector is almost implementable these d=
ays! ;)) that some of EWG's concerns may have been alleviated. =C2=A0Al=
so, N4158 lacked a public implementation that provably worked with things l=
ike allocators, whereas P1144 thinks the proper interaction with allocators=
is=C2=A0<a onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3=
dhttps%3A%2F%2Fgodbolt.org%2Fg%2FK2EqMx\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNEziBbz6NfOZyIUEXpG-k-ywyfV4Q';return true;" onclick=3D"this.href=
=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgodbolt.org%2Fg%2FK2E=
qMx\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEziBbz6NfOZyIUEXpG-k-ywyfV4Q=
9;;return true;" href=3D"https://godbolt.org/g/K2EqMx" target=3D"_blank" re=
l=3D"nofollow">so easy</a> the paper doesn't even talk about them.</div=
><div><br></div><div>=E2=80=93Arthur</div></div></blockquote></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/777928c0-ca77-4e38-ade1-debe63e90910%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/777928c0-ca77-4e38-ade1-debe63e90910=
%40isocpp.org</a>.<br />
------=_Part_4200_974697302.1532186739050--
------=_Part_4199_509661726.1532186739049--
.