220 24765 <fd64d8c9-703d-45d8-a9b2-4b8a222c02f0@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: "Components" template with implicitly defined partial
 specializations for all classes
Date: Sat, 27 Feb 2016 13:18:34 -0800 (PST)
Lines: 224
Approved: news@gmane.org
Message-ID: <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_291_1848091743.1456607914116"
X-Trace: ger.gmane.org 1456607921 22707 80.91.229.3 (27 Feb 2016 21:18:41 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sat, 27 Feb 2016 21:18:41 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDFLZXWOVYIBBKVFZC3AKGQEPE6XZQA@isocpp.org Sat Feb 27 22:18:37 2016
Return-path: <std-proposals+bncBDFLZXWOVYIBBKVFZC3AKGQEPE6XZQA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yk0-f199.google.com ([209.85.160.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDFLZXWOVYIBBKVFZC3AKGQEPE6XZQA@isocpp.org>)
	id 1aZmG4-0005td-LH
	for gclcip-std-proposals@m.gmane.org; Sat, 27 Feb 2016 22:18:36 +0100
Original-Received: by mail-yk0-f199.google.com with SMTP id r207sf185635003ykd.0
        for <gclcip-std-proposals@m.gmane.org>; Sat, 27 Feb 2016 13:18:36 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id: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=c2ZI1T0TfML8lsFhXaAQ++XbgXbBfbdTOdIw+laZhac=;
        b=1BgCQXErY6T8YHBZYn4w4Y+ICjlfHjYh0CfymRB4b0gJ5uu084zDHHNDq767RGShsq
         cA3P+U2Xk0j/Cti/CjL8yBDJAgQ4FWnrZ0/fRnvCXCGosj44oWIAK8zWEVOg6350RbGA
         XjsEQwqGPzwaXw/wcTFj/HrZLeiYWPzhqZRyCDCvAPHl21+BURu1v2PrMAVBQwaQ4WxC
         GD8TxRtvmZiNaFVGBzGevsHCkHWd9QOm33yamEodVdqyARdKL4m9Waci3Qh1zdazGx2X
         cO2kgSyZcu5Up0Hk3HOCjBcoJLajgYFQzgQdWzqkVcarZ1IQErCI85TLphLjqd4ys9LU
         FRSg==
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: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=c2ZI1T0TfML8lsFhXaAQ++XbgXbBfbdTOdIw+laZhac=;
        b=bzFZBMLNdHjYuKQVO0d9v9suys7utzxLQ+JnA8t0Va8lXYlbKI+UYLysJyOkuUKSsZ
         2O5kAoBXVHiEERuexSixJiOeR/BabXZOa85Zz+KfPaqdNDSVKc64pDVp0ipo/HlowK7Y
         F7v0GceO2mi7hDbuVCF8ESEQVYMerWzeA7QvHFV6DZOmHY9EDebVRCGymA+0GB6Q4FXf
         k33PCqEMsl8C4zDAa/Wusx5m1gDgv7J5W0pGZswS+KryHRrkxqyzRnsB2DbgGSnRltJ2
         k7tHh9sQR2zg2hS7lN2d0NrSg2jaqKwzQ1zERk5K/B9m0NOt8v/CF/EqShQLbeiABVUk
         uEpg==
X-Gm-Message-State: AD7BkJLZ3Vbyh83SLDQTQrXZZF6vsW+9qI5f3gL9VtHkwh28ziXBsLKuxCwGEHk/cqo4Ig==
X-Received: by 10.129.155.201 with SMTP id s192mr6997548ywg.4.1456607915730;
        Sat, 27 Feb 2016 13:18:35 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.159.143 with SMTP id i137ls1031996ioe.15.gmail; Sat, 27
 Feb 2016 13:18:34 -0800 (PST)
X-Received: by 10.50.118.73 with SMTP id kk9mr69090igb.8.1456607914756;
        Sat, 27 Feb 2016 13:18:34 -0800 (PST)
X-Original-Sender: 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>
X-Original-From: Walt Karas <wkaras@yahoo.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:24765
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/24765>

------=_Part_291_1848091743.1456607914116
Content-Type: multipart/alternative; 
	boundary="----=_Part_292_435338990.1456607914121"

------=_Part_292_435338990.1456607914121
Content-Type: text/plain; charset=UTF-8

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/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0%40isocpp.org.

------=_Part_292_435338990.1456607914121
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">A &quot;primitive&quot; template named &quot;Components&qu=
ot; 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 Compone=
nts<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=
:<br><br>Param &amp; param;<br>Op&lt;Member_type, &amp;Target::member&gt; o=
p; <br>bool b =3D op(param);<br><br>for all data members and base classes o=
f the class Target.=C2=A0 The function operator of Components would be gene=
rated implicitly.=C2=A0 It would instantiate Op for each component of Targe=
t, create an instance of the instantiated class, and call its function oper=
ator as shown in the constraint above, forwarding to it the parameter &#39;=
param&#39;.=C2=A0 If the call returned false, the function operator of Comp=
onents would return false immediately.=C2=A0 If all the calls for component=
s returned true, the Components operator would also return true.<br><br>For=
 example, for this class:<br><br>struct A { int i, j; double x; };<br><br>t=
he compiler would implicitly generate the equivalent of the following parti=
al specialization of Components:<br><br>template &lt;<br>=C2=A0 template &l=
t;typename Member_type, Member_type A::*mptr&gt; class Op,<br>=C2=A0 typena=
me 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;()=
(param) &amp;&amp;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 Op&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 po=
ssible to define a default operator =3D=3D as a library template:<br><br>te=
mplate &lt;class Target&gt;<br>class Equality_op;<br><br>template &lt;class=
 Target&gt;<br>class Equality_param<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 frien=
d class 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_par=
am(const 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=
 Target&gt;<br>struct Equality_op<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 templat=
e &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; &am=
p; 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(p=
aram.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 }=
;<br><br>template &lt;class Target&gt;<br>bool operator =3D=3D (const Targe=
t &amp;op1, const Target &amp;op2)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 Equali=
ty_param&lt;Target&gt; param(op1, op2);<br><br>=C2=A0=C2=A0=C2=A0 Component=
s&lt;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Target, Equality_op&lt;Target&gt;::=
template Op, Equality_param&lt;Target&gt; &gt; c;<br><br>=C2=A0=C2=A0=C2=A0=
 return(c(param));<br>=C2=A0 }<br><br>Likewise for default operators &gt; a=
nd &lt;.<br><br>This implies that member pointers can point to base classes=
, which 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><b=
r>Base Derived::*p =3D &amp;Derived::Base;<br><br>There would also be a nee=
d for another &quot;primitive&quot; template Components_no_virt_base that w=
ould skip over virtual base classes I think.<br><br>A nice thing about this=
 approach is that the default =3D=3D operator could sometimes be &quot;fixe=
d&quot; rather than discarded.=C2=A0 For example, suppose the default =3D=
=3D operator 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 han=
dle this with an overriding instantiation of &quot;Equality_op&quot;:<br><b=
r>template &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, &am=
p;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; &am=
p; 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 // ...<b=
r>=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>

<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/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fd64d8c9-703d-45d8-a9b2-4b8a222c02f0=
%40isocpp.org</a>.<br />

------=_Part_292_435338990.1456607914121--
------=_Part_291_1848091743.1456607914116--

.
