Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
April 20, 2006 recursive template (first attempt) | ||||
---|---|---|---|---|
| ||||
I apologize if this is an easily resolved problem, this is my first attempt at writing a template function. the objective of this function is to mimic the behavior of the AP hash function, but as a template function obviously. Here is what I have so far: uint aphash( ubyte []buf ) { uint hash; for ( uint i = 0; i < buf.length; i++ ) { hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (buf[i]) ^ (hash >> 3)) : (~((hash << 11) ^ (buf[i]) ^ (hash >> 5))); } return hash; } template aphasht( T : ubyte [] ) { uint aphasht( T t ) { uint result; static if ( t.length == 0 ) { return 0; } static if ( t.length & 1 ) { result = aphasht( t[1..$] ); return (result << 7) ^ t[0] ^ (result >> 3); } else { result = aphasht( t[1..$] ); return (result << 11) ^ t[0] ^ (result >> 5); } } } void test() { static ubyte []str = [ 0x01, 0x02, 0x03, 0x03 ]; writefln( "aphash(str) = %X", aphash( str ) ); writefln( "aphasht(str) = %X", aphasht!(ubyte [])( str ) ); } When I attempt to compile it, I get the following errors: dmd -w -c main.d 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 main.d(70): template instance main.aphasht!(ubyte[]) error instantiating Could someone please point out my mistake, and if there is a more elegant way of completing this task, I'd appreciate some input on that as well. Regards, Alex |
April 20, 2006 Re: recursive template (first attempt) | ||||
---|---|---|---|---|
| ||||
Posted in reply to akcom | In article <e26v01$2m8$1@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." |
April 20, 2006 Re: recursive template (first attempt) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ryan Steen | Ryan Steen wrote:
> In article <e26v01$2m8$1@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?
|
April 20, 2006 Re: recursive template (first attempt) | ||||
---|---|---|---|---|
| ||||
Posted in reply to akcom | akcom wrote:
> Ryan Steen wrote:
>> In article <e26v01$2m8$1@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 ) );
|
April 21, 2006 Re: recursive template (first attempt) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | Don Clugston wrote: > akcom wrote: > >> Ryan Steen wrote: >> >>> In article <e26v01$2m8$1@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 } |
Copyright © 1999-2021 by the D Language Foundation