recursive equal, and firstDifference functions

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


On Tuesday, 19 March 2013 at 12:36:34 UTC, John Colvin wrote:
> On Tuesday, 19 March 2013 at 12:34:04 UTC, monarch_dodra wrote:
>> On Tuesday, 19 March 2013 at 12:11:50 UTC, bearophile wrote:
>>> Jonathan M Davis:
>>>
>>>> Going beyond a range of ranges is likely to be quite rare,
>>>
>>> I agree.
>>>
>>>
>>>> and when it does happen, you can simply nest equal as many 
>>>> times as you need.
>>>
>>> A similar function seems useful for Phobos because it's 
>>> automatic, you don't need to tell it how many levels there 
>>> are.
>>>
>>> Bye,
>>> bearophile
>>
>> But the compiler can't tell how many levels deep you want to 
>> go. There are legitimate cases of "Range of Stuff" where Stuff 
>> just so happens to be a range, but you don't want range 
>> comparison.
>>
>> For example:
>> class MyClassRange;
>>
>> MyClassRange a, b;
>>
>> SuperEqual(a, b); //?
>>
>> I think using equal!equal is not that much more verbose, but 
>> safer/explicit.
>
> I think if your calling a recursive version of equal, then you 
> assume it will go as deep as possible. If you want control as 
> to how deep, then you can either use equal manually, or there 
> could be a maximum depth parameter to the recursive equal.

i.e.

import std.array : replicate;
import std.algorithm : min;
import std.range : ElementType, equal;

bool rec_equal(size_t max_depth = size_t.max, R0, R1)(R0 r0, R1 
r1)
	if(NumDims!R0 == NumDims!R1)
{
	static if(NumDims!R0 == 0 || max_depth == 0)
		return r0 == r1;
	else {
		mixin("return " ~
			  replicate("equal!", min(max_depth-1, NumDims!(R0)-1)) ~
			  "equal(r0, r1);"
			 );
	}
}

template NumDims (T) {
	static if(is(ElementType!T == void))
		const NumDims = 0;
	else
		const NumDims = 1 + NumDims!(ElementType!T);
}


More information about the Digitalmars-d-learn mailing list