digitalmars.D.learn - Check template parameter whether it has "length"
- tcak (18/18) Oct 08 2015 I am "trying" to write a function that takes an array of items,
- John Colvin (21/39) Oct 08 2015 I'm 99% sure something like __traits(hasMember, int[], "length" )
- tcak (13/36) Oct 08 2015 __traits(compiles, { size_t n = A.init.length; }); did the trick.
- John Colvin (3/4) Oct 08 2015 yeah, that's because __traits(hasMember, ...) should be good
- Meta (3/4) Oct 08 2015 You're just looking in the wrong place =)
- Artur Skawina via Digitalmars-d-learn (5/19) Oct 08 2015 Use `A.init.length` instead of `A.length`.
- Nicholas Wilson (3/21) Oct 08 2015 iirc there's a hasLength trait in std.traits e.g. static
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
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
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:__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.[...]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
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
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
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
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