220 19181 <6852185c-9032-497c-bc85-313b58a560cb@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Myriachan <myriachan@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: New type of "new"/"delete" override
Date: Wed, 22 Jul 2015 17:00:57 -0700 (PDT)
Lines: 229
Approved: news@gmane.org
Message-ID: <6852185c-9032-497c-bc85-313b58a560cb@isocpp.org>
References: <2328a5fd-924c-4d02-ac18-6a225f786dec@isocpp.org>
 <CALDL7dH8xOOY-Jk1L0tv4Uns8Szxi9vY-tDiCDgiXVaDzswoUw@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_105_1375384339.1437609657292"
X-Trace: ger.gmane.org 1437609667 22987 80.91.229.3 (23 Jul 2015 00:01:07 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Thu, 23 Jul 2015 00:01:07 +0000 (UTC)
Cc: farid.mehrabi@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDKLT4PURQHRBOW5YCWQKGQEDK25NEY@isocpp.org Thu Jul 23 02:01:02 2015
Return-path: <std-proposals+bncBDKLT4PURQHRBOW5YCWQKGQEDK25NEY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ie0-f197.google.com ([209.85.223.197])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDKLT4PURQHRBOW5YCWQKGQEDK25NEY@isocpp.org>)
	id 1ZI3wZ-0001Sj-St
	for gclcip-std-proposals@m.gmane.org; Thu, 23 Jul 2015 02:01:00 +0200
Original-Received: by iebyd10 with SMTP id yd10sf180792284ieb.2
        for <gclcip-std-proposals@m.gmane.org>; Wed, 22 Jul 2015 17:00:59 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=hGpN531ODhG+QOUTg7ZZrX63l0FO9Y5Eic1n/81cA+M=;
        b=s7uvC65b7l/Unx8S0mEHK2Kn8lOCbZyg+sxzoIkZMQJTI/+yuhjh0uiMBIwRqFKXA8
         qbKX/s+nxlGLqkiNVG9DKHD0JMX3xCbNEaHqzFQ/gZYTSdpTnmukjYMbKE4hI4Hnms1I
         S44GVtnHnJfzvVEOQp4b9FuXwHk1S7PabWSAaEtz0UYKg62MyFhPikErIxkIcXoa2dzL
         4snZKe4aMheeLshEaUf+a+oOempnrKB33h3+ZlK/8eWUEuUv4vfaBx3IauUCEshZfjNo
         cHuYVR7pnDHbEzfMnTCr+r0H6AbrJjG/VyiNgk1o6OTO+sOTz8TfXiiONqHLLh8fMtFS
         o/AA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:content-type:x-original-sender
         :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=hGpN531ODhG+QOUTg7ZZrX63l0FO9Y5Eic1n/81cA+M=;
        b=Ng4KkbWA3ctc+LNmbHBbgZxiNx+8n9sfXSLKk6hS3Qh052efjW/UumRp4RolSj2n0A
         7cAruHKyxnAv2crvuSF/BmXMaWzyrEUxiXOCiwa9gqroL4AZYAFhhDBA/qC8jJXzL7N/
         cXtN/vhOg7KfY4vZm3DeayG3T4hm4SoZ8H15EJ/mNWCrJFuhXKQae4lW0+tyC00oUM2Q
         LojogjnZ1sKaWZ0a0btdTJLYz4oFR/4vUTOuuhoQrQ+yt8cBDgj93FsUL3JeM8R0E3bG
         T7VDSXqjtcLosB6d4wK8pnortegJhiDPZ++LsX41VAxdsYAKR675VsOfPVAlVeMU6vdh
         KPCQ==
X-Gm-Message-State: ALoCoQkW6GH1LkClsn7BrHqLwnkl3FCO4+DxEcK/uL0gE4PWY6oBP2XF8lB4enHX/IcoxcX3wNsH
X-Received: by 10.182.46.227 with SMTP id y3mr5331622obm.7.1437609658988;
        Wed, 22 Jul 2015 17:00:58 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.43.230 with SMTP id z6ls2090321igl.8.canary; Wed, 22 Jul
 2015 17:00:58 -0700 (PDT)
X-Received: by 10.50.142.99 with SMTP id rv3mr226955igb.3.1437609658373;
        Wed, 22 Jul 2015 17:00:58 -0700 (PDT)
In-Reply-To: <CALDL7dH8xOOY-Jk1L0tv4Uns8Szxi9vY-tDiCDgiXVaDzswoUw@mail.gmail.com>
X-Original-Sender: myriachan@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:19181
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/19181>

------=_Part_105_1375384339.1437609657292
Content-Type: multipart/alternative; 
	boundary="----=_Part_106_45744693.1437609657292"

------=_Part_106_45744693.1437609657292
Content-Type: text/plain; charset=UTF-8

On Tuesday, July 21, 2015 at 2:24:08 PM UTC-7, Richard Smith wrote:

> Can you explain a bit more about the problem? It's really not clear to me 
> what the motivation for this change is. Why can't you / don't you want to 
> use a custom placement operator new for this?
>

On Tuesday, July 21, 2015 at 5:14:55 PM UTC-7, Thiago Macieira wrote:
>
> Besides the need for extra typing, why can't you do: 
>
>         auto i = new (valloc) MyObject; 
>
>  
The problem with this is that there's no good way to delete the object.  
"delete i;" is incorrect, because it calls the wrong deallocator.  operator 
delete(void *, valloc_t) is only called when the constructor throws an 
exception, not for regular deallocation.

You would need a custom delete function in order to do this.  For example:

template <typename T>
void delete_valloc(T *object)
{
    if (!object)
    {
        return;
    }

    void *memory = const_cast<std::remove_cv_t<T> *>(object);
    if (std::is_polymorphic<T>::value)
    {
        memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<T> 
*>(object));
    }
    object->~T();
    operator delete(memory, valloc);
}

The problem with the above is that it does not work when T::~T() is private 
or protected.  There is a workaround using macros, though:

template <typename T>
void delete_valloc_internal(T *object, void (*destructor)(T *))
{
    if (!object)
    {
        return;
    }

    void *memory = const_cast<std::remove_cv_t<T> *>(object);
    if (std::is_polymorphic<T>::value)
    {
        memory = dynamic_cast<void *>(const_cast<std::remove_cv_t<T> 
*>(object));
    }
    object->~T();
    operator delete(memory, valloc);
}

#define delete_valloc(...) \
    ::delete_valloc_internal((__VA_ARGS__), [](decltype(__VA_ARGS__) 
object) { \
        typedef std::remove_cv_t<decltype(*object)> Type; \
        object->~Type(); \
    })

Now the problem becomes that you can't use a lambda-expression with 
delete_valloc(), due to the decltype().  For example, using a fake 
not-really-STL container type:

delete_valloc(*some_container.find([](some_type value) -> bool { return 
value == 1234; }));

However, this gets worse.  When you involve array allocations, you simply 
can't use "new[]" at all.  Array new stores the number of elements in an 
implementation-defined manner without telling the operator new[] function.  
Yet, when destructing, even though there's no way to invoke something like 
"delete[](valloc) object"--it isn't supported--you still need the number of 
elements for calling the destructors.  In order to reliably get that, you 
have to save it manually, meaning that you can't use standard "new[]".

There are a lot of different annoyances with this; just like with delete, a 
macro implementing "new" or "new[]" would need the lambda trick in order to 
call into private constructors.  Additionally, a macro would need to take 
the count value as a parameter.  Due to the potential for commas in the 
type name or in the count expression, and because you can't have two "..."s 
in macro parameter lists, the syntax can get awkward.

It is possible to do all this, but only using very awkward syntax, and with 
strange restrictions.  A fully-general solution like the one I suggested 
would allow everything to be done in a consistent manner.

On Wednesday, July 22, 2015 at 8:57:16 AM UTC-7, Farid Mehrabi wrote:
>
> none-public members can only be accesses via either a member or a subclass 
> or a friend, so if you need to access those functions in any generic 
> class/function you can just make the appropriate instance a friend. One 
> good implementation can be a generic class/function forwarding to a member 
> of its operand; thus allowing library user to control implementation 
> throughout sub-typing(similar to new/delete):
>
>  
It ought not be required to use "friend" like that.  That gets annoying 
quickly, and impedes reuse of libraries.

Melissa

-- 

--- 
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_106_45744693.1437609657292
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, July 21, 2015 at 2:24:08 PM UTC-7, Richard Smi=
th wrote:<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1=
px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><div=
>Can
 you explain a bit more about the problem? It&#39;s really not clear to me=
=20
what the motivation for this change is. Why can&#39;t you / don&#39;t you w=
ant=20
to use a custom placement operator new for this?</div></blockquote><br>On T=
uesday, July 21, 2015 at 5:14:55 PM UTC-7, Thiago Macieira wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">Besides the need for extra typing, why c=
an&#39;t you do:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0auto i =3D new (valloc)=
 MyObject;
<br><br></blockquote><div>=C2=A0<br>The problem with this is that there&#39=
;s no good way to delete the object.=C2=A0 &quot;delete i;&quot; is incorre=
ct, because it calls the wrong deallocator.=C2=A0 operator delete(void *, v=
alloc_t) is only called when the constructor throws an exception, not for r=
egular deallocation.<br><br>You would need a custom delete function in orde=
r to do this.=C2=A0 For example:<br><br>template &lt;typename T&gt;<br>void=
 delete_valloc(T *object)<br>{<br>=C2=A0=C2=A0=C2=A0 if (!object)<br>=C2=A0=
=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return;<br>=C2=
=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 void *memory =3D const_cast&lt;=
std::remove_cv_t&lt;T&gt; *&gt;(object);<br>=C2=A0=C2=A0=C2=A0 if (std::is_=
polymorphic&lt;T&gt;::value)<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 memory =3D dynamic_cast&lt;void *&gt;(const_cast&l=
t;std::remove_cv_t&lt;T&gt; *&gt;(object));<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=
=A0=C2=A0=C2=A0 object-&gt;~T();<br>=C2=A0=C2=A0=C2=A0 operator delete(memo=
ry, valloc);<br>}<br><br>The problem with the above is that it does not wor=
k when T::~T() is private or protected.=C2=A0 There is a workaround using m=
acros, though:<br><br>template &lt;typename T&gt;<br>void delete_valloc_int=
ernal(T *object, void (*destructor)(T *))<br>{<br>=C2=A0=C2=A0=C2=A0 if (!o=
bject)<br>=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 return;<br>=C2=A0=C2=A0=C2=A0 }<br><br>=C2=A0=C2=A0=C2=A0 void *memory =
=3D const_cast&lt;std::remove_cv_t&lt;T&gt; *&gt;(object);<br>=C2=A0=C2=A0=
=C2=A0 if (std::is_polymorphic&lt;T&gt;::value)<br>=C2=A0=C2=A0=C2=A0 {<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 memory =3D dynamic_cast&lt;void =
*&gt;(const_cast&lt;std::remove_cv_t&lt;T&gt; *&gt;(object));<br>=C2=A0=C2=
=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0 object-&gt;~T();<br>=C2=A0=C2=A0=C2=A0 op=
erator delete(memory, valloc);<br>}<br><br>#define delete_valloc(...) \<br>=
=C2=A0=C2=A0=C2=A0 ::delete_valloc_internal((__VA_ARGS__), [](decltype(__VA=
_ARGS__) object) { \<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 typedef =
std::remove_cv_t&lt;decltype(*object)&gt; Type; \<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 object-&gt;~Type(); \<br>=C2=A0=C2=A0=C2=A0 })<br><br=
>Now the problem becomes that you can&#39;t use a lambda-expression with de=
lete_valloc(), due to the decltype().=C2=A0 For example, using a fake not-r=
eally-STL container type:<br><br>delete_valloc(*some_container.find([](some=
_type value) -&gt; bool { return value =3D=3D 1234; }));<br><br>However, th=
is gets worse.=C2=A0 When you involve array allocations, you simply can&#39=
;t use &quot;new[]&quot; at all.=C2=A0 Array new stores the number of eleme=
nts in an implementation-defined manner without telling the operator new[] =
function.=C2=A0 Yet, when destructing, even though there&#39;s no way to in=
voke something like &quot;delete[](valloc) object&quot;--it isn&#39;t suppo=
rted--you still need the number of elements for calling the destructors.=C2=
=A0 In order to reliably get that, you have to save it manually, meaning th=
at you can&#39;t use standard &quot;new[]&quot;.<br><br>There are a lot of =
different annoyances with this; just like with delete, a macro implementing=
 &quot;new&quot; or &quot;new[]&quot; would need the lambda trick in order =
to call into private constructors.=C2=A0 Additionally, a macro would need t=
o take the count value as a parameter.=C2=A0 Due to the potential for comma=
s in the type name or in the count expression, and because you can&#39;t ha=
ve two &quot;...&quot;s in macro parameter lists, the syntax can get awkwar=
d.<br><br>It is possible to do all this, but only using very awkward syntax=
, and with strange restrictions.=C2=A0 A fully-general solution like the on=
e I suggested would allow everything to be done in a consistent manner.<br>=
<br></div>On Wednesday, July 22, 2015 at 8:57:16 AM UTC-7, Farid Mehrabi wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"rtl"><div styl=
e=3D"text-align: left;" dir=3D"ltr"><font size=3D"2"><span style=3D"font-fa=
mily: arial,sans-serif;">none-public members can only be accesses via eithe=
r a member or a subclass or a friend, so if you need to access those functi=
ons in any generic class/function you can just make the appropriate instanc=
e a friend. One good implementation can be a generic class/function forward=
ing to a member of its operand; thus allowing library user to control imple=
mentation throughout sub-typing(similar to new/delete):</span></font></div>=
<div style=3D"text-align:left;font-family:&#39;arial narrow&#39;,sans-serif=
;font-size:large" dir=3D"ltr"><br></div></div></blockquote><div>=C2=A0<br>I=
t ought not be required to use &quot;friend&quot; like that.=C2=A0 That get=
s annoying quickly, and impedes reuse of libraries.<br><br>Melissa<br></div=
></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_106_45744693.1437609657292--
------=_Part_105_1375384339.1437609657292--

.
