220 32843 <f50fbc34-4601-486b-8f56-b3cef5c6f2f3@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Mingxin Wang <wmx16835vv@163.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: The Proxies - A Language Feature Decoupling
 Implementations from Requirements of Polymorphism
Date: Thu, 22 Jun 2017 02:24:47 -0700 (PDT)
Lines: 288
Approved: news@gmane.org
Message-ID: <f50fbc34-4601-486b-8f56-b3cef5c6f2f3@isocpp.org>
References: <8d79a013-fe0e-4fb6-8278-d438ae9b4c64@isocpp.org>
 <d6138434-59ef-42d7-82d8-f2934c6f3bfb@isocpp.org>
 <20170622082445.GA5007@noemi.bahnhof.se>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_707_1375949212.1498123488035"
X-Trace: blaine.gmane.org 1498123492 8506 195.159.176.226 (22 Jun 2017 09:24:52 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 22 Jun 2017 09:24:52 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDNMBNHJWIGBBYEZV3FAKGQEBIJNWHQ@isocpp.org Thu Jun 22 11:24:44 2017
Return-path: <std-proposals+bncBDNMBNHJWIGBBYEZV3FAKGQEBIJNWHQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f71.google.com ([209.85.213.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDNMBNHJWIGBBYEZV3FAKGQEBIJNWHQ@isocpp.org>)
	id 1dNyM0-0001lt-CY
	for gclcip-std-proposals@m.gmane.org; Thu, 22 Jun 2017 11:24:44 +0200
Original-Received: by mail-vk0-f71.google.com with SMTP id y2sf1546451vkd.2
        for <gclcip-std-proposals@m.gmane.org>; Thu, 22 Jun 2017 02:24:50 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=ze8+96hrkCfSSqGVfLtTo6UxieEy/2gF+HloWLaozbw=;
        b=xhwb1FUQihpNkhNWB1xF5dPG1LEAqrUUzu27rgsTiKD5WZscrx6SrN/HxKqhOqGokx
         6uRPBUsqMF1jNZQUa8BHmagYEncEeufu5ho9BptPiW0NSL9zENkoiyRvBSBpKtjSeUjH
         XnfBlnEXVnTUBvmICnAyxEFZ+T/2+q6u8VwO+TJwVzGsxm0Bq5+hAOA9z0joYXbh/sIb
         uzPpxnahCCj5OFX4m7UNcni8xr9t4xwyyHZyTkovnkmORAcBurAOwD3UPnlxeygebg0q
         eiLuGTBnvz+FpQLgjt0lthWaA3+/pZjUlSbjLz10ZskV4j4eq796xzVRFFaHjdUqbxXe
         ULpg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version: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=ze8+96hrkCfSSqGVfLtTo6UxieEy/2gF+HloWLaozbw=;
        b=dMkssUpEPmEUey9QFmcQFSVe+z3tBWWjjDsCjJjC1ftW3s/1b/+N7SW2ON1iummVG8
         hvpBUnGfuuLALZku2PDy2zuj9RPZ1RGlVeF23p6Ds0A7/FL3dMih7iPcLV/9pZ65E/Xl
         7e5dfxzrAmlj9ypSdHpzlpMZXZus5kqstRXO3UTgwdodbMUDLO0bCa1oKfy2Jbyg474v
         RcbrY8QFPmqWesHAVCVrEX6edOCiireFGBkOtFgZx2wgYiaaYL2FJhEK27V9kn3stQoW
         TROvXxdxCkvCXXyCDfCLO1PkHv+eBcPsvcnwMNQUbHXzylE9Kz7ntbzV9lpstpcpZjLg
         2+xw==
X-Gm-Message-State: AKS2vOzEPWuT4r11JZtRiMLHJnceuI7pwn2q9foZBZ9wNpzTDJRMaYFQ
	szmz2JIDeUXBS05y
X-Received: by 10.159.61.85 with SMTP id m21mr664664uai.35.1498123489484;
        Thu, 22 Jun 2017 02:24:49 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.63.52 with SMTP id m49ls5755402otc.38.gmail; Thu, 22 Jun
 2017 02:24:48 -0700 (PDT)
X-Received: by 10.157.46.132 with SMTP id w4mr43852ota.18.1498123488586;
        Thu, 22 Jun 2017 02:24:48 -0700 (PDT)
In-Reply-To: <20170622082445.GA5007@noemi.bahnhof.se>
X-Original-Sender: wmx16835vv@163.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://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>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:32843
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32843>

------=_Part_707_1375949212.1498123488035
Content-Type: multipart/alternative; 
	boundary="----=_Part_708_1691306897.1498123488036"

------=_Part_708_1691306897.1498123488036
Content-Type: text/plain; charset="UTF-8"

On Thursday, June 22, 2017 at 4:24:51 PM UTC+8, Magnus Fromreide wrote:
>
> On Wed, Jun 21, 2017 at 08:02:35PM -0700, Mingxin Wang wrote: 
> > I designed another general wrapper type yesterday, which is intended for 
> > small and trivial types, as is shown below: 
> > 
> > template <std::size_t SIZE> 
> > class TrivialWrapper { 
> >  public: 
> >   /* Constructors */ 
> >   template <class T> 
> >   TrivialWrapper(T&& data) requires 
> >       !std::is_same<std::remove_cv_t<std::remove_reference_t<T>>, 
> > TrivialWrapper>::value && 
> >       
> std::is_trivial<std::remove_cv_t<std::remove_reference_t<T>>>::value 
> > && 
> >       (sizeof(std::remove_cv_t<std::remove_reference_t<T>>) <= SIZE) { 
>
> Why remove_cv_t here? 
>
> Because T may have const or volatile qualifiers, 
"std::remove_cv_t<std::remove_reference_t<T>>" represents the raw type of T.
 

> >     memcpy(data_.get(), &data, 
> > sizeof(std::remove_cv_t<std::remove_reference_t<T>>)); 
> >   } 
> >   TrivialWrapper() = default; 
> >   TrivialWrapper(const TrivialWrapper&) = default; 
> >   TrivialWrapper(TrivialWrapper&&) = default; 
> > 
> >   TrivialWrapper& operator=(const TrivialWrapper& rhs) = default; 
> >   TrivialWrapper& operator=(TrivialWrapper&&) = default; 
>
> This is generally broken. Consider the folloving trivial data structure: 
>
> struct c_list { 
>         struct c_list *next, *prev; 
>         int data; 
> }; 
>
> It is a trivial data structure but if you start moving (or copying) it 
> around 
> with your wrapper things will break badly. 
>
> Actually, I did not see the problem as the following client code is 
well-formed:

c_list head;
head.next = nullptr;
head.prev = nullptr;
head.data = 3;
TrivialWrapper<sizeof(c_list)> w(head);
printf("%d\n", static_cast<c_list*>(w.get())->data);

The code above is not elegent as there is a type cast. However, wrapper 
types are not directly used in this solution, they are designed for the 
proxies. Suppose there is a trivial callable type defined as below:

struct Demo {
  void operator()() {
    for (int i = 0; i < 10; ++i) {
      printf("%d\n", d[i]);
    }
  }

  int d[10];
};

The following cilent code is well-formed:

Demo x;
for (int i = 0; i < 10; ++i) {
  x.d[i] = i; /// Initialize x with 0~9
}
proxy<Callable<void()>, TrivialWrapper<sizeof(Demo)>> p1(x), p2; /// p1 and 
p2 are proxy types
p2 = p1;
p1(); /// Print 0~9
p2(); /// Print 0~9

When assign p1 to p2, the memory block of p1 is directly copied to p2. 
Then, p1 and p2 holds the same value.

Everything a TrivialWrapper can solve can be solved with DeepWrapper. The 
differences between the two are the performance and scope of application:

   - TrivialWrapper usually has higher runtime performance, because it is 
   not polymorphic, and
   - DeepWrapper usually has a wider scope of application, because it can 
   be converted from a type of any size and regardless of whether the type is 
   trivial or not.

I prefer to use TrivialWrapper in performance sensitive cases, and 
DeepWrapper is recommended to be used in generality sensitive cases.

 

> >   /* Meets the Wrapper requirements */ 
> >   void* get() { 
> >     // The address of the wrapped object is calculated with a constant 
> > offset 
> >     return data_.get(); 
> >   } 
> > 
> >  private: 
> >   MemoryBlock<SIZE> data_; 
> > }; 
> > 
> > 
> > I am wondering if these design for wrappers (DeferredWrapper, 
> DeepWrapper, 
> > SharedWrapper and TrivialWrapper) are adequate to be added to the 
> standard 
> > (discard of naming). 
>
> I think you need to put in a lot of more work on why they are generally 
> useful. 
>
> /MF 
>

-- 
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/f50fbc34-4601-486b-8f56-b3cef5c6f2f3%40isocpp.org.

------=_Part_708_1691306897.1498123488036
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, June 22, 2017 at 4:24:51 PM UTC+8, Magnus Fro=
mreide wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wed, Jun 21, 2=
017 at 08:02:35PM -0700, Mingxin Wang wrote:
<br>&gt; I designed another general wrapper type yesterday, which is intend=
ed for=20
<br>&gt; small and trivial types, as is shown below:
<br>&gt;=20
<br>&gt; template &lt;std::size_t SIZE&gt;
<br>&gt; class TrivialWrapper {
<br>&gt; =C2=A0public:
<br>&gt; =C2=A0 /* Constructors */
<br>&gt; =C2=A0 template &lt;class T&gt;
<br>&gt; =C2=A0 TrivialWrapper(T&amp;&amp; data) requires
<br>&gt; =C2=A0 =C2=A0 =C2=A0 !std::is_same&lt;std::remove_cv_<wbr>t&lt;std=
::remove_reference_t&lt;T&gt;&gt;,=20
<br>&gt; TrivialWrapper&gt;::value &amp;&amp;
<br>&gt; =C2=A0 =C2=A0 =C2=A0 std::is_trivial&lt;std::remove_<wbr>cv_t&lt;s=
td::remove_reference_t&lt;<wbr>T&gt;&gt;&gt;::value=20
<br>&gt; &amp;&amp;
<br>&gt; =C2=A0 =C2=A0 =C2=A0 (sizeof(std::remove_cv_t&lt;std::<wbr>remove_=
reference_t&lt;T&gt;&gt;) &lt;=3D SIZE) {
<br>
<br>Why remove_cv_t here?
<br>
<br></blockquote><div>Because T may have const or volatile=C2=A0qualifiers,=
 &quot;std::remove_cv_t&lt;std::<wbr>remove_reference_t&lt;T&gt;&gt;&quot; =
represents the raw type of T.</div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;">&gt; =C2=A0 =C2=A0 memcpy(data_.get(), &amp;data,=20
<br>&gt; sizeof(std::remove_cv_t&lt;std::<wbr>remove_reference_t&lt;T&gt;&g=
t;));
<br>&gt; =C2=A0 }
<br>&gt; =C2=A0 TrivialWrapper() =3D default;
<br>&gt; =C2=A0 TrivialWrapper(const TrivialWrapper&amp;) =3D default;
<br>&gt; =C2=A0 TrivialWrapper(TrivialWrapper&amp;<wbr>&amp;) =3D default;
<br>&gt;=20
<br>&gt; =C2=A0 TrivialWrapper&amp; operator=3D(const TrivialWrapper&amp; r=
hs) =3D default;
<br>&gt; =C2=A0 TrivialWrapper&amp; operator=3D(TrivialWrapper&amp;&amp;) =
=3D default;
<br>
<br>This is generally broken. Consider the folloving trivial data structure=
:
<br>
<br>struct c_list {
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct c_list *next, *p=
rev;
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0int data;
<br>};
<br>
<br>It is a trivial data structure but if you start moving (or copying) it =
around
<br>with your wrapper things will break badly.
<br>
<br></blockquote><div>Actually, I did not see the problem as the following =
client code is well-formed:</div><div><br></div><div><div class=3D"prettypr=
int" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; =
background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><div class=3D"subprettyprint">c_list head;</div><div =
class=3D"subprettyprint">head.next =3D nullptr;</div><div class=3D"subprett=
yprint">head.prev =3D nullptr;</div><div class=3D"subprettyprint">head.data=
 =3D 3;</div><div class=3D"subprettyprint">TrivialWrapper&lt;sizeof(c_list)=
&gt; w(head);</div><div class=3D"subprettyprint">printf(&quot;%d\n&quot;, s=
tatic_cast&lt;c_list*&gt;(w.get())-&gt;data);</div></div></code></div><div>=
<br></div><div>The code above is not elegent as there is a type cast. Howev=
er, wrapper types are not directly used in this solution, they are designed=
 for the proxies. Suppose there is a trivial callable type defined as below=
:</div></div><div><br></div><div><div class=3D"prettyprint" style=3D"border=
: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><font color=3D"#660066"><div class=3D"subprettyprint">struct Demo {</div>=
<div class=3D"subprettyprint">=C2=A0 void operator()() {</div><div class=3D=
"subprettyprint">=C2=A0 =C2=A0 for (int i =3D 0; i &lt; 10; ++i) {</div><di=
v class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 printf(&quot;%d\n&quot;, d[=
i]);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }</div><div class=3D"=
subprettyprint">=C2=A0 }</div><div class=3D"subprettyprint"><br></div><div =
class=3D"subprettyprint">=C2=A0 int d[10];</div><div class=3D"subprettyprin=
t">};</div></font></div></code></div><br>The following cilent code is well-=
formed:</div><div><br></div><div><div class=3D"prettyprint" style=3D"border=
: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><div class=3D"subprettyprint">Demo x;</div><div class=3D"subprettyprint">=
for (int i =3D 0; i &lt; 10; ++i) {</div><div class=3D"subprettyprint">=C2=
=A0 x.d[i] =3D i; /// Initialize x with 0~9</div><div class=3D"subprettypri=
nt">}</div><div class=3D"subprettyprint">proxy&lt;Callable&lt;void()&gt;, T=
rivialWrapper&lt;sizeof(Demo)&gt;&gt; p1(x), p2; /// p1 and p2 are proxy ty=
pes</div><div class=3D"subprettyprint">p2 =3D p1;</div><div class=3D"subpre=
ttyprint">p1(); /// Print 0~9</div><div class=3D"subprettyprint">p2(); /// =
Print 0~9</div></div></code></div><div><br></div>When assign p1 to p2, the =
memory block of p1 is directly copied to p2. Then, p1 and p2 holds the same=
 value.</div><div><br></div><div>Everything a TrivialWrapper can solve can =
be solved with DeepWrapper. The differences between the two are the perform=
ance and scope of application:</div><div><ul><li><span style=3D"line-height=
: normal;">TrivialWrapper usually has higher runtime performance, because i=
t is not polymorphic, and<br></span></li><li><span style=3D"line-height: no=
rmal;">DeepWrapper usually has a wider scope of application, because it can=
 be converted from a type of any size and=C2=A0regardless of whether the ty=
pe is trivial or not.</span></li></ul>I prefer to use TrivialWrapper in per=
formance sensitive cases, and DeepWrapper is recommended to be used in gene=
rality sensitive cases.</div><div><br></div><div>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;">&gt; =C2=A0 /* Meets the Wrapper requirement=
s */
<br>&gt; =C2=A0 void* get() {
<br>&gt; =C2=A0 =C2=A0 // The address of the wrapped object is calculated w=
ith a constant=20
<br>&gt; offset
<br>&gt; =C2=A0 =C2=A0 return data_.get();
<br>&gt; =C2=A0 }
<br>&gt;=20
<br>&gt; =C2=A0private:
<br>&gt; =C2=A0 MemoryBlock&lt;SIZE&gt; data_;
<br>&gt; };
<br>&gt;=20
<br>&gt;=20
<br>&gt; I am wondering if these design for wrappers (DeferredWrapper, Deep=
Wrapper,=20
<br>&gt; SharedWrapper and TrivialWrapper) are adequate to be added to the =
standard=20
<br>&gt; (discard of naming).
<br>
<br>I think you need to put in a lot of more work on why they are generally
<br>useful.
<br>
<br>/MF
<br></blockquote></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f50fbc34-4601-486b-8f56-b3cef5c6f2f3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f50fbc34-4601-486b-8f56-b3cef5c6f2f3=
%40isocpp.org</a>.<br />

------=_Part_708_1691306897.1498123488036--

------=_Part_707_1375949212.1498123488035--

.
