220 25750 <77c1b655-f29c-4836-aab9-334d6e77af73@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: "'Walt Karas' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: "Components" template with implicitly defined
 partial specializations for all classes
Date: Mon, 2 May 2016 14:38:34 -0700 (PDT)
Lines: 237
Approved: news@gmane.org
Message-ID: <77c1b655-f29c-4836-aab9-334d6e77af73@isocpp.org>
References: <fd64d8c9-703d-45d8-a9b2-4b8a222c02f0@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_769_1774317915.1462225115022"
X-Trace: ger.gmane.org 1462225120 17609 80.91.229.3 (2 May 2016 21:38:40 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 2 May 2016 21:38:40 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDFLZXWOVYIBBW4RT64QKGQEK6TCGVI@isocpp.org Mon May 02 23:38:40 2016
Return-path: <std-proposals+bncBDFLZXWOVYIBBW4RT64QKGQEK6TCGVI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qk0-f199.google.com ([209.85.220.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDFLZXWOVYIBBW4RT64QKGQEK6TCGVI@isocpp.org>)
	id 1axLY6-00052Q-17
	for gclcip-std-proposals@m.gmane.org; Mon, 02 May 2016 23:38:38 +0200
Original-Received: by mail-qk0-f199.google.com with SMTP id t184sf2626725qkh.3
        for <gclcip-std-proposals@m.gmane.org>; Mon, 02 May 2016 14:38:37 -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
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=ulPOPffmKfnmo1fBfQmjbMtDOhhPdU/BWM0yj3v74/E=;
        b=eguKRhk3IsMOmN9Y2j9NxqH8yGeW0Zdd5bKF9UGt9YVjGJdokAoDUrG02ogAyU7Q24
         hRrYtuKhPmh09I25/htxm/gio7IX1QPmOTNLiNe+CZdbscJgpMaB7uksdjb/vHMiKOq1
         jZ/T9RY7OJ6PI4+8twp/G4FEFavfFJpEfDiB6kzRq9yo+F21OSBLYv59eeFKzJjTQHhb
         PNrAYCeWtPf/J5f0/VqcuPTCR6tP7fMSoCLYf8qjZ8zQ3PGVXD2h1PJXYRWyCbMSQyIw
         mr6hNT1nciYax+QN8P/wEnzT1o+MXmS2qQxb/rTju4DQxq54ZVJ/nNQWZxXZWC18PgkK
         mkfQ==
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: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=ulPOPffmKfnmo1fBfQmjbMtDOhhPdU/BWM0yj3v74/E=;
        b=N/Pmv57/dd23rJG4etXxq0l4mcDOYZHKwA661N5QAXaq/kWKM/M0/0TLvLQkSjCkWl
         ps/K1Cqn34KIzTTycljOju9m3OcAw69XLjlGy8ouVmP9WsWMKUaUthoLvQPZOlO3bzxY
         dfNREunWa4yg+U+tYuxsO0grmKGZSgznAh13Gmfdpk0FCKKKGInSdlIhgTjrYBQq/Fi/
         CJg2d5akNGt19Sz6QNa6lVsmsBIN+6OG3iA/arYlNqTuRktRlgNLbt4mIeMbDBDZCTRJ
         DrkTLYAL7eOzSulLxBeNq8dHQGPSVQowc3qKgzIf0hLko3LDSOl/o0+inZzLt+jeJSIw
         BHlQ==
X-Gm-Message-State: AOPr4FUdEWQxhtCGzPFCWyX4Fxpn90T6DngTKN/XVGA5fpLom6JnKz9iupKPAn8hQb2GZg==
X-Received: by 10.141.41.70 with SMTP id s67mr26085199qhe.11.1462225117121;
        Mon, 02 May 2016 14:38:37 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.170.210 with SMTP id g79ls1818412ioj.61.gmail; Mon, 02 May
 2016 14:38:35 -0700 (PDT)
X-Received: by 10.50.90.5 with SMTP id bs5mr360388igb.5.1462225115721;
        Mon, 02 May 2016 14:38:35 -0700 (PDT)
In-Reply-To: <fd64d8c9-703d-45d8-a9b2-4b8a222c02f0@isocpp.org>
X-Original-Sender: wkaras@yahoo.com
X-Original-From: Walt Karas <wkaras@yahoo.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: <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:25750
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/25750>

------=_Part_769_1774317915.1462225115022
Content-Type: multipart/alternative; 
	boundary="----=_Part_770_819221775.1462225115022"

------=_Part_770_819221775.1462225115022
Content-Type: text/plain; charset=UTF-8

I took a stab at trying to implement something along these lines in the 
current language:

https://github.com/wkaras/C-plus-plus-library-default-operators

On Saturday, February 27, 2016 at 4:18:34 PM UTC-5, Walt Karas wrote:
>
> A "primitive" template named "Components" with this interface:
>
> template <
>   class Target,
>   template <typename Member_type, Member_type Target::*mptr>
>     class Op,
>   typename Param>
> struct Components
>   {
>     bool operator () (Param & param);
>   };
>
> The Op parameter is presumed to fulfill the constraint:
>
> Param & param;
> Op<Member_type, &Target::member> op; 
> bool b = op(param);
>
> for all data members and base classes of the class Target.  The function 
> operator of Components would be generated implicitly.  It would instantiate 
> Op for each component of Target, create an instance of the instantiated 
> class, and call its function operator as shown in the constraint above, 
> forwarding to it the parameter 'param'.  If the call returned false, the 
> function operator of Components would return false immediately.  If all the 
> calls for components returned true, the Components operator would also 
> return true.
>
> For example, for this class:
>
> struct A { int i, j; double x; };
>
> the compiler would implicitly generate the equivalent of the following 
> partial specialization of Components:
>
> template <
>   template <typename Member_type, Member_type A::*mptr> class Op,
>   typename Param>
> struct Components<A, Op, Param>
>   {
>     bool operator () (Param & param)
>       {
>         return(
>           Op<int, &A::i>()(param) &&
>           Op<int, &A::j>()(param) &&
>           Op<double, &A::x>()(param));
>       }
>   };
>
> This would make it possible to define a default operator == as a library 
> template:
>
> template <class Target>
> class Equality_op;
>
> template <class Target>
> class Equality_param
>   {
>     friend class Equality_op<Target>;
>
>     const Target &op1, &op2;
>
>   public:
>     Equality_param(const Target &op1_, const Target &op2_)
>       : op1(op1_), op2(op2_) { }
>   };
>
> template <class Target>
> struct Equality_op
>   {
>     template <typename Member_type, Member_type Target::*mptr>
>     struct Op
>       {
>         bool operator () (Equality_param<Target> & param)
>           {
>             return(param.op1.*mptr == param.op2.*mptr);
>           }
>       };
>   };
>
> template <class Target>
> bool operator == (const Target &op1, const Target &op2)
>   {
>     Equality_param<Target> param(op1, op2);
>
>     Components<
>       Target, Equality_op<Target>::template Op, Equality_param<Target> > c;
>
>     return(c(param));
>   }
>
> Likewise for default operators > and <.
>
> This implies that member pointers can point to base classes, which I'm 
> guessing is an idea that's been rejected before.  So doing this would 
> create "pressure" to accept the syntax:
>
> Base Derived::*p = &Derived::Base;
>
> There would also be a need for another "primitive" template 
> Components_no_virt_base that would skip over virtual base classes I think.
>
> A nice thing about this approach is that the default == operator could 
> sometimes be "fixed" rather than discarded.  For example, suppose the 
> default == operator worked for a class "Big" except for one data member 
> "argh", which was a pointer to a heap object.  One could handle this with 
> an overriding instantiation of "Equality_op":
>
> template <>
> struct Equality_op<Big>
>   {
>     template <>
>     struct Op<Argh, &Big::argh>
>       {
>         bool operator () (Equality_param<Target> & param)
>           {
>             // ...
>           }
>       };
>   };
>

-- 
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/77c1b655-f29c-4836-aab9-334d6e77af73%40isocpp.org.

------=_Part_770_819221775.1462225115022
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I took a stab at trying to implement something along these=
 lines in the current language:<br><br>https://github.com/wkaras/C-plus-plu=
s-library-default-operators<br><br>On Saturday, February 27, 2016 at 4:18:3=
4 PM UTC-5, Walt Karas wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr">A &quot;primitive&quot; template named &quot;Components&quo=
t; with this interface:<br><br>template &lt;<br>=C2=A0 class Target,<br>=C2=
=A0 template &lt;typename Member_type, Member_type Target::*mptr&gt;<br>=C2=
=A0=C2=A0=C2=A0 class Op,<br>=C2=A0 typename Param&gt;<br>struct Components=
<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 bool operator () (Param &amp; param);<br=
>=C2=A0 };<br><br>The Op parameter is presumed to fulfill the constraint:<b=
r><br>Param &amp; param;<br>Op&lt;Member_type, &amp;Target::member&gt; op; =
<br>bool b =3D op(param);<br><br>for all data members and base classes of t=
he class Target.=C2=A0 The function operator of Components would be generat=
ed implicitly.=C2=A0 It would instantiate Op for each component of Target, =
create an instance of the instantiated class, and call its function operato=
r as shown in the constraint above, forwarding to it the parameter &#39;par=
am&#39;.=C2=A0 If the call returned false, the function operator of Compone=
nts would return false immediately.=C2=A0 If all the calls for components r=
eturned true, the Components operator would also return true.<br><br>For ex=
ample, for this class:<br><br>struct A { int i, j; double x; };<br><br>the =
compiler would implicitly generate the equivalent of the following partial =
specialization of Components:<br><br>template &lt;<br>=C2=A0 template &lt;t=
ypename Member_type, Member_type A::*mptr&gt; class Op,<br>=C2=A0 typename =
Param&gt;<br>struct Components&lt;A, Op, Param&gt;<br>=C2=A0 {<br>=C2=A0=C2=
=A0=C2=A0 bool operator () (Param &amp; param)<br>=C2=A0=C2=A0=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=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;int, &amp;A::i&gt;()(pa=
ram) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 O=
p&lt;int, &amp;A::j&gt;()(param) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 Op&lt;double, &amp;A::x&gt;()(param));<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0 };<br><br>This would make it possib=
le to define a default operator =3D=3D as a library template:<br><br>templa=
te &lt;class Target&gt;<br>class Equality_op;<br><br>template &lt;class Tar=
get&gt;<br>class Equality_param<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 friend cl=
ass Equality_op&lt;Target&gt;;<br><br>=C2=A0=C2=A0=C2=A0 const Target &amp;=
op1, &amp;op2;<br><br>=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0 Equality_param(c=
onst Target &amp;op1_, const Target &amp;op2_)<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 : op1(op1_), op2(op2_) { }<br>=C2=A0 };<br><br>template &lt;class Ta=
rget&gt;<br>struct Equality_op<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 template &=
lt;typename Member_type, Member_type Target::*mptr&gt;<br>=C2=A0=C2=A0=C2=
=A0 struct Op<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 bool operator () (Equality_param&lt;Target&gt; &amp; =
param)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return(para=
m.op1.*mptr =3D=3D param.op2.*mptr);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 };<br>=C2=A0 };<b=
r><br>template &lt;class Target&gt;<br>bool operator =3D=3D (const Target &=
amp;op1, const Target &amp;op2)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 Equality_=
param&lt;Target&gt; param(op1, op2);<br><br>=C2=A0=C2=A0=C2=A0 Components&l=
t;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Target, Equality_op&lt;Target&gt;::tem=
plate Op, Equality_param&lt;Target&gt; &gt; c;<br><br>=C2=A0=C2=A0=C2=A0 re=
turn(c(param));<br>=C2=A0 }<br><br>Likewise for default operators &gt; and =
&lt;.<br><br>This implies that member pointers can point to base classes, w=
hich I&#39;m guessing is an idea that&#39;s been rejected before.=C2=A0 So =
doing this would create &quot;pressure&quot; to accept the syntax:<br><br>B=
ase Derived::*p =3D &amp;Derived::Base;<br><br>There would also be a need f=
or another &quot;primitive&quot; template Components_no_virt_base that woul=
d skip over virtual base classes I think.<br><br>A nice thing about this ap=
proach is that the default =3D=3D operator could sometimes be &quot;fixed&q=
uot; rather than discarded.=C2=A0 For example, suppose the default =3D=3D o=
perator worked for a class &quot;Big&quot; except for one data member &quot=
;argh&quot;, which was a pointer to a heap object.=C2=A0 One could handle t=
his with an overriding instantiation of &quot;Equality_op&quot;:<br><br>tem=
plate &lt;&gt;<br>struct Equality_op&lt;Big&gt;<br>=C2=A0 {<br>=C2=A0=C2=A0=
=C2=A0 template &lt;&gt;<br>=C2=A0=C2=A0=C2=A0 struct Op&lt;Argh, &amp;Big:=
:argh&gt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 bool operator () (Equality_param&lt;Target&gt; &amp; par=
am)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 {<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // ...<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 };<br>=C2=A0 };<br></div></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/77c1b655-f29c-4836-aab9-334d6e77af73%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/77c1b655-f29c-4836-aab9-334d6e77af73=
%40isocpp.org</a>.<br />

------=_Part_770_819221775.1462225115022--
------=_Part_769_1774317915.1462225115022--

.
