recursive equal, and firstDifference functions

John Colvin john.loughran.colvin at gmail.com
Tue Mar 19 05:18:52 PDT 2013


On Tuesday, 19 March 2013 at 12:16:54 UTC, John Colvin wrote:
> On Tuesday, 19 March 2013 at 11:46:14 UTC, monarch_dodra wrote:
>> On Tuesday, 19 March 2013 at 10:08:43 UTC, Jonathan M Davis 
>> wrote:
>>> On Tuesday, March 19, 2013 09:25:43 timotheecour wrote:
>>>> we need a std.algorithm.equalRecurse(T1,T2)(T1 a, T2 b) that
>>>> compares recursively a and b;
>>>> 
>>>> its behavior should be:
>>>> 
>>>> if opEqual is defined, call it
>>>> else, if its a range, call std.algorithm.equal (ie compare nb
>>>> elements, then each element for equality)
>>>> else, if it's a class/struct, make sure types are same and 
>>>> call
>>>> it recursively on each field.
>>>> else if it's a numerical type, call "=="
>>>> else (is there an else?)
>>>> 
>>>> just as std.algorithm.equal, we should have
>>>> equalRecurse([1],[1.0]);
>>>
>>> If you want recursive equal, then do equal!equal. Granted, 
>>> that's only one
>>> level of recursion, but how many levels deep are you really 
>>> going to have your
>>> ranges? And you have to get to == eventually anyway in order 
>>> to compare the
>>> deepest elements. Going beyond a range of ranges is likely to 
>>> be quite rare,
>>> and when it does happen, you can simply nest equal as many 
>>> times as you need.
>>>
>>> - Jonathan M Davis
>>
>> "equal!equal(RoR1, RoR2)"
>>
>> That looks cute, but I think it says something about how 
>> powerful and expressive D can be, while being compile-time 
>> optimized. It's those little things that still amaze me about 
>> D.
>
> and then:
>
> template NumDimensions (T) {
> 	static if(is(ElementType!T == void))
> 		const NumDimensions = 0;
> 	else
> 		const NumDimensions = 1 + NumDimensions!(ElementType!T);
> }
>
> bool rec_equal(R0, R1)(R0 r0, R1 r1)
> 	if(NumDimensions!R0 == NumDimensions!R1)
> {
> 	mixin("return " ~ replicate("equal!", NumDimensions!(R0)-1) ~ 
> "equal(r0, r1);");
> }
>
> obviously it requires some more checks, but it works nicely 
> (except if you feed it two integer literals, in which case the 
> compiler throws an out of memory error!).

correction:

bool rec_equal(R0, R1)(R0 r0, R1 r1)
	if(NumDimensions!R0 == NumDimensions!R1)
{
	static if(NumDimensions!R0 == 0)
		return r0 == r1;
	else
		mixin("return " ~ replicate("equal!", NumDimensions!(R0)-1) ~ 
"equal(r0, r1);");
}


More information about the Digitalmars-d-learn mailing list