recursive template (first attempt)

akcom CppCoder at gmail.com
Thu Apr 20 19:06:59 PDT 2006


Don Clugston wrote:
> akcom wrote:
> 
>> Ryan Steen wrote:
>>
>>> In article <e26v01$2m8$1 at digitaldaemon.com>, akcom says...
>>>
>>>
>>>>         static if ( t.length == 0 )
>>>>         static if ( t.length & 1 )
>>>> main.d(49): expression ((t).length) == 0u does not evaluate to a
>>>> boolean
>>>> main.d(53): expression ((t).length) & 1u does not evaluate to a boolean
>>>
>>>
>>> "It is an error if AssignExpression ... cannot be evaluated at
>>> compile time."
>>>
>>>
>> why can't it be computed at compile time if I make "str" static/const?
> 
> 
> It's just because array literals are only supported at this time for
> strings. (Your code might work in DMD 2.0).
> 
> If you change the definitions to
> const char [] str = x"01 02 03";
> 
> template aphasht( char [] T)
> {
>     const uint aphasht = ...
> }
> (changing returns to const aphasht).
> 
> it would work with
> 
> writefln( "aphasht(str) = %X", aphasht!(str ) );

I finally got it working, but for some odd reason the templates gives
different results than the original function when the string being
processed has a length that is odd, any ideas?

uint aphash( char []buf )
{
	uint hash;
	
	hash = 0;
	for ( uint i = 0; i < buf.length; i++ )
	{
		hash ^= ((i & 1) == 0) ?	(  (hash <<  7) ^ (cast(ubyte)buf[i]) ^ (hash
>> 3)) :
									(~((hash << 11) ^ (cast(ubyte)buf[i]) ^ (hash >> 5)));
	}
	return hash;
}

template aphashT( char []s, uint lastHash = 0 )
{
	static if ( s.length == 0 )
	{
		const aphashT = lastHash;
	}
	else static if ( s.length & 1 )
	{
		const aphashT = aphashT!( s[1..$], lastHash ^ ~( (lastHash << 11) ^
cast(ubyte)(s[0]) ^ (lastHash >> 5) ) );
	}
	else
	{
		const aphashT = aphashT!( s[1..$], lastHash ^ ( (lastHash << 7) ^
cast(ubyte)(s[0]) ^ (lastHash >>3) ) );
	}
}

unittest
{
	assert( aphashT!( "aaa" ) == aphash( "aaa" ) ); //fails
	assert( aphashT!( "abcdefg12345" ) == aphash( "abcdefg12345" ) );
	assert( aphashT!( "rofl haxor" ) == aphash( "rofl haxor" ) );
	assert( aphashT!( "abc" ) == aphash( "abc" ) );
	assert( aphashT!( "hello world" ) == aphash( "hello world" ) ); //fails
}



More information about the Digitalmars-d-learn mailing list