www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Comparing Multiple Values

reply okibi <spam ratedo.com> writes:
I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:

select *
from table
where value in (1,2,3)

And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:

if (value == 1 || value == 2 || value == 3)
    dosomething();

Just seems like this could be written better. Can anyone give me any pointers?

Thanks!
Mar 11 2008
next sibling parent oliver <oliver.ruebenkoenigREM web.de> writes:
okibi Wrote:

 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
 
 Thanks!
Probably not quite what you are looking for but you could use AAs. Something like: int foo[char[]]; ... if ("hello" in foo) Oliver
Mar 11 2008
prev sibling next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
okibi wrote:
 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
Mar 11 2008
parent reply downs <default_357-line yahoo.de> writes:
Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs! --downs
Mar 11 2008
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 11 Mar 2008 13:39:55 +0100, downs wrote:
 There's a better way actually.
But that is only good for ranges ;-) Not so good for ... if value in set(2,4,7,10,23,445) I'm pretty sure this will be simple to organize once AST macros are implemented. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Mar 11 2008
parent reply BCS <ao pathlink.com> writes:
Reply to Derek,

 On Tue, 11 Mar 2008 13:39:55 +0100, downs wrote:
 
 There's a better way actually.
 
But that is only good for ranges ;-) Not so good for ... if value in set(2,4,7,10,23,445) I'm pretty sure this will be simple to organize once AST macros are implemented.
struct _Set(T) { T[] set; bool opIn_r(U)(U u) { foreach(v; set) if(v==u) return true; return false; } } struct Set { static _Set!(T) opIndex(T, U)(T[] a...) { _Set!(T) ret; ret.set = a.dup; //need the dup??? return ret; } } I /think/ that will work. But I haven't tested it. if(1 in Set[1,2,3,5,9,23])
Mar 11 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Derek,
 
 On Tue, 11 Mar 2008 13:39:55 +0100, downs wrote:

 There's a better way actually.
But that is only good for ranges ;-) Not so good for ... if value in set(2,4,7,10,23,445) I'm pretty sure this will be simple to organize once AST macros are implemented.
struct _Set(T) { T[] set; bool opIn_r(U)(U u) { foreach(v; set) if(v==u) return true; return false; } } struct Set { static _Set!(T) opIndex(T, U)(T[] a...) { _Set!(T) ret; ret.set = a.dup; //need the dup??? return ret; } } I /think/ that will work. But I haven't tested it. if(1 in Set[1,2,3,5,9,23])
Hadn't noticed that you wrote basically the same thing I did already ... You left a U template parameter in the opIndex. The dup isn't necessary. And unfortunately it doesn't work because IFTI isn't smart enough to deduce the template argument. So you need to call it as Set[[1,2,3,4]]. --bb
Mar 11 2008
parent BCS <ao pathlink.com> writes:
Reply to Bill,


 Hadn't noticed that you wrote basically the same thing I did already
 ...
 
 You left a U template parameter in the opIndex.
Errr. Oops.
 The dup isn't necessary.
 And unfortunately it doesn't work because IFTI isn't smart enough to
 deduce the template argument.  So you need to call it as
 Set[[1,2,3,4]].
that's a cool syntax <<g>>
 --bb
 
Mar 11 2008
prev sibling next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
downs wrote:
 Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs!
What?! Dost mine eyes deceive me? Downs just gave up an opportunity to proselytize about his infix operators? This is sure a sign of the end times, my friends. --bb
Mar 11 2008
parent reply downs <default_357-line yahoo.de> writes:
Bill Baxter wrote:
 downs wrote:
 Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs!
What?! Dost mine eyes deceive me? Downs just gave up an opportunity to proselytize about his infix operators? This is sure a sign of the end times, my friends. --bb
Um. `in` already is an infix operator :) --downs
Mar 11 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
downs wrote:
 Bill Baxter wrote:
 downs wrote:
 Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs!
What?! Dost mine eyes deceive me? Downs just gave up an opportunity to proselytize about his infix operators? This is sure a sign of the end times, my friends. --bb
Um. `in` already is an infix operator :) --downs
Yes, but it doesn't work! --bb
Mar 11 2008
parent reply downs <default_357-line yahoo.de> writes:
Bill Baxter wrote:
 downs wrote:
 Bill Baxter wrote:
 downs wrote:
 Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports
 any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs!
What?! Dost mine eyes deceive me? Downs just gave up an opportunity to proselytize about his infix operators? This is sure a sign of the end times, my friends. --bb
Um. `in` already is an infix operator :) --downs
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
Mar 11 2008
parent reply BCS <ao pathlink.com> writes:
Reply to Downs,

 Bill Baxter wrote:
 
 downs wrote:
 
 
 `in` already is an infix operator :)
 
 --downs
 
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
I think he was saying the "in" operator dosn't work / works wrong. As in (a in [0:0, 1:2, 2:4, 3:6]) == (0<= a <=4) rather than (a==0 || a==2 || a==4 || a==6).
Mar 11 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Downs,
 
 Bill Baxter wrote:

 downs wrote:

 `in` already is an infix operator :)

 --downs
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
I think he was saying the "in" operator dosn't work / works wrong.
Right, as in "a in [1,2,3]" is an error, rather than doing what the poster who started this thread expected it to do.
 As in 
 (a in [0:0, 1:2, 2:4, 3:6]) == (0<= a <=4) rather than (a==0 || a==2 || 
 a==4 || a==6).
No that's fine. If I ask you "is 'ain't' in the the dictionary?" I'm clearly not asking if it appears as a definition. --bb
Mar 11 2008
parent reply downs <default_357-line yahoo.de> writes:
Bill Baxter wrote:
 BCS wrote:
 Reply to Downs,

 Bill Baxter wrote:

 downs wrote:

 `in` already is an infix operator :)

 --downs
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
I think he was saying the "in" operator dosn't work / works wrong.
Right, as in "a in [1,2,3]" is an error, rather than doing what the poster who started this thread expected it to do.
To give an example of W's stance .. Say you have a book with four pages. The first page contains the number 15, the second page 16 the third 23 and the fourth 42. Now, if I ask "3 in book", do I mean "is the page 3 in the book" (index) or "is the number 3 in the book" (value)? There's precedence in the D language for the first case, because `in` for AAs also checks against index (key) and not value. However, checking against value would arguably be more useful :) In the absence of a consensus, and because a case could be made for both possibilities, it was decided to leave it out for now. That should about sum it up. --downs
Mar 11 2008
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
downs wrote:
 Bill Baxter wrote:
 BCS wrote:
 Reply to Downs,

 Bill Baxter wrote:

 downs wrote:

 `in` already is an infix operator :)

 --downs
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
I think he was saying the "in" operator dosn't work / works wrong.
Right, as in "a in [1,2,3]" is an error, rather than doing what the poster who started this thread expected it to do.
To give an example of W's stance .. Say you have a book with four pages. The first page contains the number 15, the second page 16 the third 23 and the fourth 42. Now, if I ask "3 in book", do I mean "is the page 3 in the book" (index) or "is the number 3 in the book" (value)? There's precedence in the D language for the first case, because `in` for AAs also checks against index (key) and not value. However, checking against value would arguably be more useful :) In the absence of a consensus, and because a case could be made for both possibilities, it was decided to leave it out for now. That should about sum it up.
Yes, that sums it up quite nicely. --bb
Mar 11 2008
parent okibi <spam ratedo.com> writes:
Bill Baxter Wrote:

 downs wrote:
 Bill Baxter wrote:
 BCS wrote:
 Reply to Downs,

 Bill Baxter wrote:

 downs wrote:

 `in` already is an infix operator :)

 --downs
Yes, but it doesn't work! --bb
Curious. Works here, GDC 1.028 / 4.1.2 What are you using? --downs
I think he was saying the "in" operator dosn't work / works wrong.
Right, as in "a in [1,2,3]" is an error, rather than doing what the poster who started this thread expected it to do.
To give an example of W's stance .. Say you have a book with four pages. The first page contains the number 15, the second page 16 the third 23 and the fourth 42. Now, if I ask "3 in book", do I mean "is the page 3 in the book" (index) or "is the number 3 in the book" (value)? There's precedence in the D language for the first case, because `in` for AAs also checks against index (key) and not value. However, checking against value would arguably be more useful :) In the absence of a consensus, and because a case could be made for both possibilities, it was decided to leave it out for now. That should about sum it up.
Yes, that sums it up quite nicely. --bb
Thanks for clearing up why it's not in there. I was really expecting it to work as I thought, however it's no big deal. Thanks everyone!
Mar 12 2008
prev sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
downs wrote:
 Bill Baxter wrote:
 okibi wrote:
 I've looked all over the site but can't seem to find if D supports any
 kind of like IN statement for comparisons. For example, I can do the
 following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within
 D's if statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any
 pointers?
I can point you to a bunch of discussions where certain people argued tooth and nail that "if(value in [1,2,3])" should mean "if(value==0||value==1||value==2)", leading basically to a stalemate. So, no. Nothing like that is in the language. But you can write a little "contains" function that will do the trick. Or ask Downs how to make "if(x /In/ [1,2,3])" work. --bb
There's a better way actually. import std.stdio; // bottom-inclusive, top-exclusive, like slices. struct _Range(T) { T from, to; bool opIn_r(U)(U u) { return u < to && u !< from; } } struct Range { static _Range!(T) opSlice(T, U)(T from, U to) { return _Range!(T)(from, to); } } void main() { writefln(3 in Range[2..4], " -- ", 4 in Range[2..4]); } Have funs! --downs
Downs seems to have misunderstood the request, but his suggestion can be adapted to do what the OP wanted, and without the high cost of constructing an associative array on the fly: import std.stdio; struct _Set(T) { T[] _set; bool opIn_r(U)(U u) { foreach(v; _set) { if (v==u) return true; } return false; } } struct Set { static _Set!(T) opIndex(T)(T[] x ...) { return _Set!(T)(x); } // or this static _Set!(T) opCall(T)(T[] x ...) { return _Set!(T)(x); } } void main() { // doesn't work because of template deduction bug :-( //writefln(3 in Set[2,7,4], " -- ", 4 in Set[2,7,4]); // ok writefln(3 in Set([2,7,4]), " -- ", 4 in Set([2,7,4])); }
Mar 11 2008
prev sibling next sibling parent reply Frank Benoit <keinfarbton googlemail.com> writes:
okibi schrieb:
 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
 
 Thanks!
*untested* bool isOneOf(T)( T value, T[] compares ... ){ foreach( c; compares ){ if( value == c ) return true; } return false; } if ( isOneOf( value, 1, 2, 3 )) dosomething();
Mar 11 2008
parent reply okibi <spam ratedo.com> writes:
Frank Benoit Wrote:

 okibi schrieb:
 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
 
 Thanks!
*untested* bool isOneOf(T)( T value, T[] compares ... ){ foreach( c; compares ){ if( value == c ) return true; } return false; } if ( isOneOf( value, 1, 2, 3 )) dosomething();
This is what I was looking for, thanks! Is there any chance of the in [] method getting into D or is it a definite no?
Mar 11 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
okibi wrote:
 Frank Benoit Wrote:
 
 okibi schrieb:
 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:

 select *
 from table
 where value in (1,2,3)

 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:

 if (value == 1 || value == 2 || value == 3)
     dosomething();

 Just seems like this could be written better. Can anyone give me any pointers?

 Thanks!
*untested* bool isOneOf(T)( T value, T[] compares ... ){ foreach( c; compares ){ if( value == c ) return true; } return false; } if ( isOneOf( value, 1, 2, 3 )) dosomething();
This is what I was looking for, thanks! Is there any chance of the in [] method getting into D or is it a definite no?
Probably not much chance, since Walter is one of the ones who thinks A in [x,y,z] should return true if A is 0 1 or 2, regardless of the values of x,y, and z. See big long argument here: http://d.puremagic.com/issues/show_bug.cgi?id=1323 But Walter has been known to change his mind on occasion. --bb
Mar 11 2008
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Tue, 11 Mar 2008 06:45:14 -0400, okibi wrote:

 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
Without thinking too deeply about it, you could use this technique ... bool[int] goodvalues; static this() { goodvalues = [1:true, 2:true, 3:true]; } . . . if (value in goodvalues) dosomething(); -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Mar 11 2008
prev sibling next sibling parent Alexander Panek <alexander.panek brainsware.org> writes:
okibi wrote:
 I've looked all over the site but can't seem to find if D supports any kind of
like IN statement for comparisons. For example, I can do the following in SQL:
 
 select *
 from table
 where value in (1,2,3)
 
 And it will compare it to 1, 2, and 3. Is this possible to do within D's if
statement? I hate to go about it as such:
 
 if (value == 1 || value == 2 || value == 3)
     dosomething();
 
 Just seems like this could be written better. Can anyone give me any pointers?
 
 Thanks!
bool includes (T) (T[] array, item) { foreach (i; array) { if ( item == i) { return true; } } return false; } if (["a", "b", "c"].includes("a")) { doSomething(); } untested, and almost the same as Frank's, just a tad more Ruby-ish. ;)
Mar 11 2008
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
If the set values are known only a run time then you can use the isIn()
function from my d libs that works with arrays.
And soon you will be able to use the set() constructor too (it builds an AA
inside).

If the set values are known at compile time you may use something like this:


import std.stdio: putr = writefln;

const bool do_speed_tests = true; // Put this to true if you want to run the
speed tests


/***********************************************
Given one or more items, of different types too, it builds a struct at
compile time with the opIn_r() method, that allows to look (with a linear
scan) for an item inside.
*/
_Bunch!(Types) bunch(Types...)(Types items) {
    return _Bunch!(Types)(items);
}

struct _Bunch(Types...) {
    Types items; // tuple

    bool opIn_r(Tx)(Tx x) {
        // no compile-time hashing yet
        foreach (el; items) // this is a static foreach
            static if (is(typeof(el == x)))
                if (el == x)
                    return true;
        return false;
    }
    // toString too can be defined
}

/// To be sure to execute a function at compile time.
template StaticEval(A...) {
    const typeof(A[0]) StaticEval = A[0];
}


static if(do_speed_tests) {
    static import std.c.time; // *****

    /*********************************
    Return the seconds (a double) from the start of the program.
    */
    double clock() {
        auto t = std.c.time.clock();
        if (t == -1)
            return 0.0;
        else
            return t/cast(double)std.c.time.CLOCKS_PER_SEC;
    }

    struct _LSet(T) {
        T[] set;

        bool opIn_r(U)(U u) {
            foreach(v; set)
                if (v == u)
                    return true;
            return false;
        }
    }

    struct LSet {
        static _LSet!(T) opCall(T)(T[] x ...) {
            return _LSet!(T)(x);
        }
    }

    void bunch_benchmark() {
        const uint N = 20_000_000;

        auto t = clock;
        uint result;
        auto b1 = LSet([1U, 2U, 3U, 4U]);
        for (uint i; i < N; ++i)
            result += ((i % 5U) in b1);
        putr(clock - t, " s ", result);

        t = clock;
        result = 0;
        auto b2 = bunch(1U, 2U, 3U, 4U);
        for (uint i; i < N; ++i)
            result += ((i % 5U) in b2);
        putr(clock - t, " s ", result);

        t = clock;
        result = 0;
        for (uint i; i < N; ++i) {
            switch (i % 5U) {
                case 1U, 2U, 3U, 4U:
                    result++;
                    break;
                default:
                    break;
            }
        }

        t = clock;
        result = 0;
        for (uint i; i < N; ++i) {
            uint i5 = i % 5U;
            if (i5 == 1U || i5 == 2U || i5 == 3U || i5 == 4U)
                result++;
        }
        putr(clock - t, " s ", result);

        t = clock;
        result = 0;
        for (uint i; i < N; ++i) {
            switch (i % 5U) {
                case 1U, 2U, 3U, 4U:
                    result++;
                    break;
                default:
                    break;
            }
        }
        putr(clock - t, " s ", result);

        // Timings, N = 20_000_000, -O -release -inline:
        //   3.33 s 16000000 (LSet)
        //   2.23 s 16000000 (bunch)
        //   2.07 s 16000000 (if)
        //   1.82 s 16000000 (switch)
    }
}


void main() {
    // just to be sure it's created at compile time
    auto b = StaticEval!(bunch(2L, 7, 4U, "a"));
    assert(!(3 in b));
    assert(4 in b);
    assert("a" in b);

    static if (do_speed_tests)
        bunch_benchmark();
}

After more improvements, some unit testing, (and a better name) I may even
include this in my libs :-)

Bye,
bearophile
Mar 12 2008