digitalmars.D.learn - setIntersection of struct range
- Jesse Phillips (40/40) Aug 11 2009 I am trying to obtain a rang that is the intersection of two other range...
- Steven Schveighoffer (23/71) Aug 12 2009 You did not define a way to compare two S structs. Try redefining S lik...
- Steven Schveighoffer (6/8) Aug 12 2009 BTW, this probably should not be true, I would guess that static arrays ...
- Jesse Phillips (2/15) Aug 12 2009 You know, I didn't think about this because struct arrays are sorted by ...
- Jesse Phillips (2/19) Aug 12 2009 Got around to trying this, but it didn't fix the problem.
- Sergey Gromov (17/44) Aug 12 2009 Looks like a compiler bug/feature to me. The following is a reduced
I am trying to obtain a rang that is the intersection of two other ranges. To
do this I am using the _setIntersection()_ function.
import std.algorithm;
import std.stdio;
struct S {
string label;
}
void main() {
auto s1 = new S[2];
auto s2 = new S[2];
s1[0].label = "fish";
s1[1].label = "bar";
s2[0].label = "foo";
s2[1].label = "fish";
foreach(str; setIntersection(s1,s2))
writeln(str);
}
The code above generates this error:
C:\opt\dmd\windows\bin\..\..\src\phobos\std\functional.d(191):
Error: static assert "Bad binary function q{a < b}.
You need to use a valid D expression using symbols a of type S and
b of type S."
So I attempted an intersection of string arrays, and received a different
error. I'm not sure if I am at fault or the compiler. Shouldn't these work?
import std.algorithm;
import std.stdio;
import std.array;
struct S {
string label;
}
void main() {
auto s1 = ["fish", "bar"];
auto s2 = ["foo", "fish"];
foreach(str; setIntersection(s1,s2))
writeln(str);
}
Which ended up with:
test.d(13): Error: template std.algorithm.setIntersection(alias less = "a <
b",Rs...)
if (allSatisfy!(isInputRange,Rs)) does not match any function template
declaration
test.d(13): Error: template std.algorithm.setIntersection(alias less = "a <
b",Rs...)
if (allSatisfy!(isInputRange,Rs)) cannot deduce template function from
argument types !()(immutable(char)[][2u],immutable(char)[][2u])
test.d(13): Error: foreach: int is not an aggregate type
Aug 11 2009
On Tue, 11 Aug 2009 19:35:40 -0400, Jesse Phillips <jessekphillips+d gmail.com> wrote:I am trying to obtain a rang that is the intersection of two other ranges. To do this I am using the _setIntersection()_ function. import std.algorithm; import std.stdio; struct S { string label; } void main() { auto s1 = new S[2]; auto s2 = new S[2]; s1[0].label = "fish"; s1[1].label = "bar"; s2[0].label = "foo"; s2[1].label = "fish"; foreach(str; setIntersection(s1,s2)) writeln(str); } The code above generates this error: C:\opt\dmd\windows\bin\..\..\src\phobos\std\functional.d(191): Error: static assert "Bad binary function q{a < b}. You need to use a valid D expression using symbols a of type S and b of type S."You did not define a way to compare two S structs. Try redefining S like this: struct S { string label; int opCmp(ref const S s2) const { if(label < s2.label) return -1; if(label > s2.label) return 1; return 0; } }So I attempted an intersection of string arrays, and received a different error. I'm not sure if I am at fault or the compiler. Shouldn't these work? import std.algorithm; import std.stdio; import std.array; struct S { string label; } void main() { auto s1 = ["fish", "bar"]; auto s2 = ["foo", "fish"]; foreach(str; setIntersection(s1,s2)) writeln(str); } Which ended up with: test.d(13): Error: template std.algorithm.setIntersection(alias less = "a < b",Rs...) if (allSatisfy!(isInputRange,Rs)) does not match any function template declaration test.d(13): Error: template std.algorithm.setIntersection(alias less = "a < b",Rs...) if (allSatisfy!(isInputRange,Rs)) cannot deduce template function from argument types !()(immutable(char)[][2u],immutable(char)[][2u])I think it's expecting dynamc arrays, not static ones. Auto is making them static. Try explicitly defining s1 and s2 as string[] or slice the literal, typing them as dynamic arrays like this: auto s1 = ["fish", "bar"][]; auto s2 = ["foo", "fish"][];test.d(13): Error: foreach: int is not an aggregate typeThis is a dummy error because it couldn't figure out the type of setIntersection, so it just assumes int (a quirk of dmd). -Steve
Aug 12 2009
On Wed, 12 Aug 2009 11:25:10 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:I think it's expecting dynamc arrays, not static ones. Auto is making them static.BTW, this probably should not be true, I would guess that static arrays should be intersectable, of course the return type would have to be a dynamic array. When will static arrays be first class? *sigh* -Steve
Aug 12 2009
Steven Schveighoffer Wrote:
You did not define a way to compare two S structs. Try redefining S like
this:
struct S {
string label;
int opCmp(ref const S s2) const {
if(label < s2.label)
return -1;
if(label > s2.label)
return 1;
return 0;
}
}
You know, I didn't think about this because struct arrays are sorted by the
first element if you do array.sort. But this does make the error a little more
clear.
Aug 12 2009
Jesse Phillips Wrote:Steven Schveighoffer Wrote:Got around to trying this, but it didn't fix the problem.You did not define a way to compare two S structs. Try redefining S like this: struct S { string label; int opCmp(ref const S s2) const { if(label < s2.label) return -1; if(label > s2.label) return 1; return 0; } }You know, I didn't think about this because struct arrays are sorted by the first element if you do array.sort. But this does make the error a little more clear.
Aug 12 2009
Tue, 11 Aug 2009 19:35:40 -0400, Jesse Phillips wrote:
I am trying to obtain a rang that is the intersection of two other ranges. To
do this I am using the _setIntersection()_ function.
import std.algorithm;
import std.stdio;
struct S {
string label;
}
void main() {
auto s1 = new S[2];
auto s2 = new S[2];
s1[0].label = "fish";
s1[1].label = "bar";
s2[0].label = "foo";
s2[1].label = "fish";
foreach(str; setIntersection(s1,s2))
writeln(str);
}
The code above generates this error:
C:\opt\dmd\windows\bin\..\..\src\phobos\std\functional.d(191):
Error: static assert "Bad binary function q{a < b}.
You need to use a valid D expression using symbols a of type S
and b of type S."
Looks like a compiler bug/feature to me. The following is a reduced
test case:
import std.functional;
struct S {
string label;
}
void main() {
auto f1 = &binaryFunImpl!("a < b", "a", "b").result!(int, int);
auto f2 = &binaryFunImpl!("a.label < b.label", "a", "b").result!(S, S);
}
Compiled with dmd2 test.d:
C:\opt\dmd.2.031\windows\bin\..\..\src\phobos\std\functional.d(191):
Error: static assert "Bad binary function q{a.label < b.label}. You
need to use a valid D expression using symbols a of ty
pe S and b of type S."
Note that int,int passes while S,S fails.
Aug 12 2009









"Steven Schveighoffer" <schveiguy yahoo.com> 