www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Check template parameter whether it has "length"

reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
I am "trying" to write a function that takes an array of items, 
and returns the length of longest item.

[code]
size_t maxLength(A)( const A[] listOfString ) if( __traits( 
hasMember, A, "length" ) )
{
	return 0; // not implemented yet
}
[/code]

I tried it with

if( __traits( compiles, A.length ) )

as well. But compiler doesn't match it.

writeln("Max Length: ", maxLength( ["foo", "123456789"] ));

Compilers says it cannot deduce function from argument types ...

I do not want to check whether the type "A" is string, char[], 
etc. As long as it has length (please do not put me into ranges, 
library functions etc as much as possible), I want the function 
to accept it.
Oct 08 2015
next sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 8 October 2015 at 09:29:30 UTC, tcak wrote:
 I am "trying" to write a function that takes an array of items, 
 and returns the length of longest item.

 [code]
 size_t maxLength(A)( const A[] listOfString ) if( __traits( 
 hasMember, A, "length" ) )
 {
 	return 0; // not implemented yet
 }
 [/code]

 I tried it with

 if( __traits( compiles, A.length ) )

 as well. But compiler doesn't match it.

 writeln("Max Length: ", maxLength( ["foo", "123456789"] ));

 Compilers says it cannot deduce function from argument types ...

 I do not want to check whether the type "A" is string, char[], 
 etc. As long as it has length (please do not put me into 
 ranges, library functions etc as much as possible), I want the 
 function to accept it.
I'm 99% sure something like __traits(hasMember, int[], "length" ) should evaluate to true. Please file a bug at issues.dlang.org I notice it also doesn't work for "ptr". The correct workaround: __traits(compiles, A.init.length )); or __traits(compiles, listOfStrings.length )); A.length doesn't work because length is not a static member, so it's only accessible from an instance. The __traits(compiles, ...) solution is actually more general because it will work if .length is implemented via UFCS and opDispatch. FYI: If you want to check whether a statement will compile, as opposed to an expression, make a function/delegate out of it, e.g.: __traits(compiles, { size_t n = A.init.length; }); to check that A has a member length that can be assigned to size_t. P.S. always check std.traits for solutions all your static reflection problems, there's a lot of good stuff in there.
Oct 08 2015
parent reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Thursday, 8 October 2015 at 09:50:12 UTC, John Colvin wrote:
 On Thursday, 8 October 2015 at 09:29:30 UTC, tcak wrote:
 [...]
I'm 99% sure something like __traits(hasMember, int[], "length" ) should evaluate to true. Please file a bug at issues.dlang.org I notice it also doesn't work for "ptr". The correct workaround: __traits(compiles, A.init.length )); or __traits(compiles, listOfStrings.length )); A.length doesn't work because length is not a static member, so it's only accessible from an instance. The __traits(compiles, ...) solution is actually more general because it will work if .length is implemented via UFCS and opDispatch. FYI: If you want to check whether a statement will compile, as opposed to an expression, make a function/delegate out of it, e.g.: __traits(compiles, { size_t n = A.init.length; }); to check that A has a member length that can be assigned to size_t. P.S. always check std.traits for solutions all your static reflection problems, there's a lot of good stuff in there.
__traits(compiles, { size_t n = A.init.length; }); did the trick. [code] size_t maxLength(A)( const A[] listOfString ) if( __traits( compiles, { size_t len = A.init.length; } ) ) { size_t len = 0; foreach(A str; listOfString) if( str.length > len ) len = str.length; return len; } [/code] BTW, there is nothing like std.traits.hasLength.
Oct 08 2015
next sibling parent John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 8 October 2015 at 15:22:02 UTC, tcak wrote:
 BTW, there is nothing like std.traits.hasLength.
yeah, that's because __traits(hasMember, ...) should be good enough, but obviously not in this case at the moment.
Oct 08 2015
prev sibling parent Meta <jared771 gmail.com> writes:
On Thursday, 8 October 2015 at 15:22:02 UTC, tcak wrote:
 BTW, there is nothing like std.traits.hasLength.
You're just looking in the wrong place =) http://dlang.org/phobos/std_range_primitives.html#hasLength
Oct 08 2015
prev sibling next sibling parent Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On 10/08/15 11:29, tcak via Digitalmars-d-learn wrote:
 I am "trying" to write a function that takes an array of items, and returns
the length of longest item.
 
 [code]
 size_t maxLength(A)( const A[] listOfString ) if( __traits( hasMember, A,
"length" ) )
 {
     return 0; // not implemented yet
 }
 [/code]
 
 I tried it with
 
 if( __traits( compiles, A.length ) )
 
 as well. But compiler doesn't match it.
Use `A.init.length` instead of `A.length`. You could also use something like if(is(typeof(A.init.length):size_t)) artur
Oct 08 2015
prev sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Thursday, 8 October 2015 at 09:29:30 UTC, tcak wrote:
 I am "trying" to write a function that takes an array of items, 
 and returns the length of longest item.

 [code]
 size_t maxLength(A)( const A[] listOfString ) if( __traits( 
 hasMember, A, "length" ) )
 {
 	return 0; // not implemented yet
 }
 [/code]

 I tried it with

 if( __traits( compiles, A.length ) )

 as well. But compiler doesn't match it.

 writeln("Max Length: ", maxLength( ["foo", "123456789"] ));

 Compilers says it cannot deduce function from argument types ...

 I do not want to check whether the type "A" is string, char[], 
 etc. As long as it has length (please do not put me into 
 ranges, library functions etc as much as possible), I want the 
 function to accept it.
iirc there's a hasLength trait in std.traits e.g. static assert(hasLength!int[])
Oct 08 2015