www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CustomString and string constraints

reply SrMordred <patric.dexheimer gmail.com> writes:
Is possible to make a Custom Struct String work for D string 
constraints?

eg:

struct MyString
{
     char[] arr;
     alias arr this;
}

void getString( char[] str ){}

MyString().split(";"); //oops, type mismatch

getString( MyString() ); //fine, implicit conversion

isSomeString!(char[]).writeln; //true
isSomeString!(MyString).writeln; //false
Jun 26 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
n Tuesday, June 26, 2018 17:14:08 SrMordred via Digitalmars-d-learn wrote:
 Is possible to make a Custom Struct String work for D string
 constraints?

 eg:

 struct MyString
 {
      char[] arr;
      alias arr this;
 }

 void getString( char[] str ){}

 MyString().split(";"); //oops, type mismatch

 getString( MyString() ); //fine, implicit conversion

 isSomeString!(char[]).writeln; //true
 isSomeString!(MyString).writeln; //false
If what you're asking is whether it's possible for a template constraint that uses something like isSomeString will ever match a user-defined type, then the answer is no. isSomeString specifically requires that the type be a string. And it actually would be fairly error-prone if it accepted anything else. If a template is written with the assumption that it's going to be operating on arrays of characters, and it accepts anything that implicitly converts to an array of characters, then you easily get subtle bugs (e.g. some parts of the code could use the actual type and others would do the implicit conversion rather than the code consistently using the same type). Any template that accepts an implicit conversion really needs to force that conversion rather than trying to operate on a type that implicitly converts to a particular type as if it were that type. But in general, it's just far less error-prone to require that the caller do the conversion. And implicit conversions to dynamic arrays (strings included) are particularly dangerous to allow. For instance, if you have a function that does something like T[] foo(T[] arr) { ... return arr[i .. j]; } and you pass it a T[42], then the implicit conversion is done at the call site, and the slice that is returned is valid and will continue to be valid so long as the static array has not been destroyed. However, if you do something like T[] foo(U)(U arr) if(is(U : T[])) { ... return arr[i .. j]; } or T[] foo(U)(U arr) if(is(U : T[])) { T[] retval = arr; ... return retval[i .. j]; } then the implicit conversion is done inside the function. And because static arrays are value types, the slice that's returned is a slice of local memory and is therefore invalid, causing safety-related problems. So, while your particular type might be able to safely convert inside such a function and still be safe, that's not true in the general case. As such, templated code that wants to accept implicit conversions to dynamic arrays really needs to be templated on the element type and not the whole type. e.g. T[] foo(T)(T[] arr) { ... return arr[i .. j]; } can safely return a slice, because the implicit conversion was forced at the call site just like it was with the non-templated function. In general, Phobos only accepts implicit conversions with template constraints when the function was originally not a template but was later turned into a template, and the implicit conversion had to be kept in order to avoid breaking code. And to do that safely, the conversion to a template must be done very carefully, and there are actually some cases in Phobos which still need to be fixed, because it was done incorrectly. All in all, while it might be annoying sometimes, it's just safer to have templates require that all conversions be done before making the call rather than allowing implicit conversions. - Jonathan M Davis
Jun 26 2018
parent SrMordred <patric.dexheimer gmail.com> writes:
On Tuesday, 26 June 2018 at 22:16:28 UTC, Jonathan M Davis wrote:
 If what you're asking is whether it's possible for a template 
 constraint that uses something like isSomeString will ever 
 match a user-defined type, then the answer is no.
Thats exactly what I wanted xD. My idea was that if you can make custom array types that operate with phobos lib(via some implicit conversions) then there "should" have a way to do that with strings, but I understood the issues that you explained. Thanks!
Jun 26 2018