logical operands on strings
I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings?
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:21:06 UTC, Erik van Velzen wrote: I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings? It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct.
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. Forgive me for making the comparison, but I believe in C++ i can simply implement this function and be done with it: string operator^(string lhs, string rhs);
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? Well something like this. struct MyString { string value; alias value this; auto opBinary(string op)(string rhs) if( op == ^ ) { string result; foreach(i; 0 .. min(value.length, rhs.length)) result ~= value[i] ^ rhs[i]; return MyString(result); } } auto mstr(string s) { return MyString(s); } auto s = Hello; auto s2 = World; auto res = s.mstr ^ s2; or string res = s.mstr ^ s2; //If you want the result to be a string. While this works it's not that much better then the simple: auto s = Hello; auto s2 = World; auto res = s.xor(s2); It seems I can't even inherit from string. In D a string is not a class its just an immutable array (slice) of char. alias string = immutable(char[]);
Re: logical operands on strings
On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. Forgive me for making the comparison, but I believe in C++ i can simply implement this function and be done with it: string operator^(string lhs, string rhs); global operator overloads aren't allowed in D. For your particular problem I would construct a wrapper around string using psuedo-inheritance via 'alias this': struct MyString { string nativeStr; alias nativeStr this; auto opBinary(string op)(string rhs) if(op == ^) { return xor(nativeStr, rhs); } void opOpBinary(string op)(string rhs) if(op == ^) { nativeStr = xor(nativeStr, rhs); } } All normal string operations on a MyString will be applied to nativeStr thanks to alias this, except the ^ and ^= whch are intercepted by the opBinary and opOpBinary methods in MyString. The ^= could be more efficient by working in-place. Also, you should pre-allocate the return string in xor as it's a lot quicker than doing repeated append operations.
Re: logical operands on strings
On 01/12/2014 10:21 AM, Erik van Velzen wrote: I would like to do this: string one = x315c4eeaa8b5f8aaf9174145bf43e1784b; string two = xc29398f5f3251a0d47e503c66e935de81230b59b7a; string three = one ^ two; The closests I've been able to get is: string three = xor(one, two); string xor(string one, string two) { int len = min(one.length, two.length); string result; for(int i=0; ilen; i++) { result ~= one[i] ^ two[i]; } return cast(string)result; } Question 1: is there a more elegant way to implement the function xor? (foreach-ish or std.algorithm) Then I tried to add operator overloading: string opBinary(string op)(string lhs, string rhs) { static if( op == ^ ) return xor(lhs, rhs); else static assert(false, operator not possible); } But it doesn't invoke this function. Question 2: how would I implement ^ for strings? XOR is not a valid operation on a UTF-8 code unit. ;) It makes more sense to work with ubyte arrays. However, I found two usability issues with it: 1) std.conv.to did not work from string to ubyte[]; so, I wrote a function. 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Otherwise, ^= works with slices: import std.stdio; ubyte[] toBytes(string s) { return cast(ubyte[])s.dup; } void main() { ubyte[] one = x55.toBytes; ubyte[] two = xaa.toBytes; ubyte[] three = one.dup; three[] ^= two[]; assert(one == x55); assert(two == xaa); assert(three == xff); } Ali
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:12:13 UTC, TheFlyingFiddle wrote: On Sunday, 12 January 2014 at 18:37:40 UTC, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? Well something like this. struct MyString { string value; alias value this; auto opBinary(string op)(string rhs) if( op == ^ ) { string result; foreach(i; 0 .. min(value.length, rhs.length)) result ~= value[i] ^ rhs[i]; return MyString(result); } } auto mstr(string s) { return MyString(s); } auto s = Hello; auto s2 = World; auto res = s.mstr ^ s2; or string res = s.mstr ^ s2; //If you want the result to be a string. While this works it's not that much better then the simple: auto s = Hello; auto s2 = World; auto res = s.xor(s2); It seems I can't even inherit from string. In D a string is not a class its just an immutable array (slice) of char. alias string = immutable(char[]); You can also use opBinaryRight for when your custom string class is on the right side of the operand, so string ^ MyString also works. This pretty much obviates the need for global operator overloading, at least in this case.
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:22:57 UTC, Ali Çehreli wrote: 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Is this a bug or intended?
Re: logical operands on strings
On Sunday, 12 January 2014 at 19:27:18 UTC, Meta wrote: On Sunday, 12 January 2014 at 19:22:57 UTC, Ali Çehreli wrote: 2) Array-wise operations does not support the following syntax auto three = one[] ^ two[]; Is this a bug or intended? intended. It would require an implicit allocation, which is incongruent with array operations being fast. It's been discussed at length.
Re: logical operands on strings
On 1/13/2014 3:37 AM, Erik van Velzen wrote: On Sunday, 12 January 2014 at 18:28:38 UTC, Meta wrote: It looks like your opBinary on strings is an attempt at globally overriding the XOR operator. I'm almost 100% sure this won't work in D. All operator overloads have to be part of a class or struct. How would I do that without rewriting an entire string class? It seems I can't even inherit from string. In D, string is not a class. It's an alias for an immutable array of char.