<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	
	>
<channel>
	<title>
	Comments on: Removing Duplicates in C++ CRTP Base Classes	</title>
	<atom:link href="https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/</link>
	<description>Jonathan Boccara&#039;s blog</description>
	<lastBuildDate>Wed, 12 Sep 2018 20:03:00 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.5</generator>
	<item>
		<title>
		By: David Riedel		</title>
		<link>https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/#comment-1291</link>

		<dc:creator><![CDATA[David Riedel]]></dc:creator>
		<pubDate>Wed, 12 Sep 2018 20:03:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4138#comment-1291</guid>

					<description><![CDATA[Since your mixin feature packs are template parameter packs, maybe you could use Boost MP11 or Hana to eliminate duplicates. Hana has a &#039;set&#039; functions which will eliminate duplicates and MP11 has a &#039;unique&#039; function which will do the same.

For example

template
class X
{
   using unique_types_ = mp11::mp_unique&#060;mp11::mp_list&#062;;

....
};]]></description>
			<content:encoded><![CDATA[<p>Since your mixin feature packs are template parameter packs, maybe you could use Boost MP11 or Hana to eliminate duplicates. Hana has a &#8216;set&#8217; functions which will eliminate duplicates and MP11 has a &#8216;unique&#8217; function which will do the same.</p>
<p>For example</p>
<p>template<br />
class X<br />
{<br />
   using unique_types_ = mp11::mp_unique&lt;mp11::mp_list&gt;;</p>
<p>&#8230;.<br />
};</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Sergio Adán		</title>
		<link>https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/#comment-1275</link>

		<dc:creator><![CDATA[Sergio Adán]]></dc:creator>
		<pubDate>Wed, 05 Sep 2018 09:45:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4138#comment-1275</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/#comment-1257&quot;&gt;Matthew Borkowski&lt;/a&gt;.

wow, I really like you point of view. This solution reduces the number of iterations and removes the limitations of my proposal. Thanks for your dropping your solution]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/#comment-1257">Matthew Borkowski</a>.</p>
<p>wow, I really like you point of view. This solution reduces the number of iterations and removes the limitations of my proposal. Thanks for your dropping your solution</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Matthew Borkowski		</title>
		<link>https://www.fluentcpp.com/2018/08/28/removing-duplicates-crtp-base-classes/#comment-1257</link>

		<dc:creator><![CDATA[Matthew Borkowski]]></dc:creator>
		<pubDate>Fri, 31 Aug 2018 01:26:00 +0000</pubDate>
		<guid isPermaLink="false">https://www.fluentcpp.com/?p=4138#comment-1257</guid>

					<description><![CDATA[Here&#039;s my solution that avoids recursion: http://coliru.stacked-crooked.com/a/463db3673b139429

The basic idea is to replace duplicate ExtraFeature base classes with empty dummy classes. This is because it&#039;s easy to map over a parameter pack with just expansions but difficult to filter things out or otherwise change the pack&#039;s size without recursion. Redundant comparisons between packs are avoid in a similar way.

There are several layers of indirection to deal with making index sequences and replacing things with dummy classes, so here&#039;s the sketch of all the layers of a basic example, though certainly ignore this if it&#039;s more confusing than the code itself:

The Pack struct wraps up parameter packs, and FeatureSets are just Packs of types (we instantiate ExtraFeature templates with Derived early for simplicity). Suppose we have extra feature classes F1,F2,F3, and feature sets A=Pack&#060;F1,F2&#062;; B=Pack&#060;F2,F3&#062;; C=Pack&#060;F1,F3&#062;

1) X inherits from UseFeatures, which just passes the buck to MergePacks: eg, UseFeatures&#060;X, A, B, C&#062; = MergePacks&#060;A&#060;X&#062;, B&#060;X&#062;, C&#060;X&#062;&#062;

2) which exists solely to add on an index sequence: MergePacks&#060;A,B,C&#062; = InheritPacks&#060;seq&#060;0,1,2&#062;, A, B, C&#062;

3) then InheritPacks has three base classes, to do the actual work of deduplicating: 
- InheritUnique&#060;0, A, seq&#060;0,1,2&#062;, A, B, C&#062;
- InheritUnique&#060;1, B, seq&#060;0,1,2&#062;, A, B, C&#062;
- InheritUnique&#060;2, C, seq&#060;0,1,2&#062;, A, B, C&#062;

4) and each InheritUnique inherits from multiple BlankIfDups, one for each type in its first Pack argument. It also uses the index and index sequence to replace Packs that would be redundant to test against with empty Packs. So,
- InheritUnique&#060;0, A, ...&#062; inherits from BlankIfDup&#060;F1, Pack&#060;&#062;, B, C&#062; and BlankIfDup&#060;F2, Pack&#060;&#062;, B, C&#062;
- InheritUnique&#060;1, B, ...&#062; inherits from BlankIfDup&#060;F2, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; and BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, C&#062;
- InheritUnique&#060;2, C, ...&#062; inherits from BlankIfDup&#060;F1, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; and BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062;

5) each BlankIfDup is either an alias for the type it is passed if the type in not present in any of the Packs it is passed, or else a Blank tagged with the type. So,
- BlankIfDup&#060;F1, Pack&#060;&#062;, B, C&#062; = Blank&#060;F1&#062; because F1 is in C
- BlankIfDup&#060;F2, Pack&#060;&#062;, B, C&#062; = Blank&#060;F2&#062; because F2 is in B
- BlankIfDup&#060;F2, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; = F2
- BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; = Blank&#060;F3&#062; because F3 is in C
- BlankIfDup&#060;F1, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; = F1
- BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; = F3

6) thus X inherits from one copy each of F1, F2, and F3, via 3 InheritUniques, via 1 InheritPacks. X also inherits from three dummy Blank&#060;...&#062; classes. See the comments in main() for a complete accounting.

I don&#039;t know if having many empty dummy bases will affect compilation speed in any significant way (and I&#039;d guess it&#039;d be cheaper than heaps of template recursion at any rate) but it shouldn&#039;t have any other costs because of empty base optimization.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my solution that avoids recursion: <a href="http://coliru.stacked-crooked.com/a/463db3673b139429" rel="nofollow ugc">http://coliru.stacked-crooked.com/a/463db3673b139429</a></p>
<p>The basic idea is to replace duplicate ExtraFeature base classes with empty dummy classes. This is because it&#8217;s easy to map over a parameter pack with just expansions but difficult to filter things out or otherwise change the pack&#8217;s size without recursion. Redundant comparisons between packs are avoid in a similar way.</p>
<p>There are several layers of indirection to deal with making index sequences and replacing things with dummy classes, so here&#8217;s the sketch of all the layers of a basic example, though certainly ignore this if it&#8217;s more confusing than the code itself:</p>
<p>The Pack struct wraps up parameter packs, and FeatureSets are just Packs of types (we instantiate ExtraFeature templates with Derived early for simplicity). Suppose we have extra feature classes F1,F2,F3, and feature sets A=Pack&#060;F1,F2&#062;; B=Pack&#060;F2,F3&#062;; C=Pack&#060;F1,F3&#062;</p>
<p>1) X inherits from UseFeatures, which just passes the buck to MergePacks: eg, UseFeatures&#060;X, A, B, C&#062; = MergePacks&#060;A&#060;X&#062;, B&#060;X&#062;, C&#060;X&#062;&#062;</p>
<p>2) which exists solely to add on an index sequence: MergePacks&#060;A,B,C&#062; = InheritPacks&#060;seq&#060;0,1,2&#062;, A, B, C&#062;</p>
<p>3) then InheritPacks has three base classes, to do the actual work of deduplicating:<br />
&#8211; InheritUnique&#060;0, A, seq&#060;0,1,2&#062;, A, B, C&#062;<br />
&#8211; InheritUnique&#060;1, B, seq&#060;0,1,2&#062;, A, B, C&#062;<br />
&#8211; InheritUnique&#060;2, C, seq&#060;0,1,2&#062;, A, B, C&#062;</p>
<p>4) and each InheritUnique inherits from multiple BlankIfDups, one for each type in its first Pack argument. It also uses the index and index sequence to replace Packs that would be redundant to test against with empty Packs. So,<br />
&#8211; InheritUnique&#060;0, A, &#8230;&#062; inherits from BlankIfDup&#060;F1, Pack&#060;&#062;, B, C&#062; and BlankIfDup&#060;F2, Pack&#060;&#062;, B, C&#062;<br />
&#8211; InheritUnique&#060;1, B, &#8230;&#062; inherits from BlankIfDup&#060;F2, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; and BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, C&#062;<br />
&#8211; InheritUnique&#060;2, C, &#8230;&#062; inherits from BlankIfDup&#060;F1, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; and BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062;</p>
<p>5) each BlankIfDup is either an alias for the type it is passed if the type in not present in any of the Packs it is passed, or else a Blank tagged with the type. So,<br />
&#8211; BlankIfDup&#060;F1, Pack&#060;&#062;, B, C&#062; = Blank&#060;F1&#062; because F1 is in C<br />
&#8211; BlankIfDup&#060;F2, Pack&#060;&#062;, B, C&#062; = Blank&#060;F2&#062; because F2 is in B<br />
&#8211; BlankIfDup&#060;F2, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; = F2<br />
&#8211; BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, C&#062; = Blank&#060;F3&#062; because F3 is in C<br />
&#8211; BlankIfDup&#060;F1, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; = F1<br />
&#8211; BlankIfDup&#060;F3, Pack&#060;&#062;, Pack&#060;&#062;, Pack&#060;&#062;&#062; = F3</p>
<p>6) thus X inherits from one copy each of F1, F2, and F3, via 3 InheritUniques, via 1 InheritPacks. X also inherits from three dummy Blank&#060;&#8230;&#062; classes. See the comments in main() for a complete accounting.</p>
<p>I don&#8217;t know if having many empty dummy bases will affect compilation speed in any significant way (and I&#8217;d guess it&#8217;d be cheaper than heaps of template recursion at any rate) but it shouldn&#8217;t have any other costs because of empty base optimization.</p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>
