On Apr 30, 11 03:12, Andrei Alexandrescu wrote:
On 4/29/11 8:50 AM, Denis Koroskin wrote:
On Thu, 28 Apr 2011 03:10:15 +0400, Andrej Mitrovic
<andrej.mitrov...@gmail.com> wrote:
I often see code written like this:
if (value == somevalue ||
value == someothervalue ||
value == yetanothervalue);
You could use the switch statement. But that introduces indentation,
and is rarely used for a couple of values.
I really like the "in" keyword, and I also like hashes since they can
potentially speed up look-ups compared to conventional arrays. So I
thought it would be cool to have a Hash template that constructs an
associative array which you can use especially in if statements when
you just want to know if a runtime value matches some predetermined
value.
Here's my attempt at writing it:
http://codepad.org/c4sYDSyR
Whaddya think?
Try this:
[snip]
Nice work. I think this code could earn a place in Phobos:
auto either(Keys...)(Keys keys)
{
static struct Result
{
bool opIn_r(Key)(Key key)
{
foreach (k; keys) {
if (k == key) {
return true;
}
}
return false;
}
private Keys keys;
}
return Result(keys);
}
Andrei
This is generally 2~3 times slower than a compile-time solution if the
keys are known in advance (and the former is 1~2 times slower than using
x == y || x == z || ... directly)
(Why do you still use opIn_r? ;) )
import std.datetime, std.algorithm, std.typecons, std.stdio;
auto either(Keys...)(Keys keys)
{
static struct Result
{
bool opIn_r(Key)(Key key)
{
foreach (k; keys) {
if (k == key) {
return true;
}
}
return false;
}
private Keys keys;
}
return Result(keys);
}
struct ctEither(keys...) {
@safe bool opBinaryRight(string op:"in", T)(in T x) const pure nothrow {
foreach (k; keys)
if (x == k)
return true;
return false;
}
}
struct ctEither2(keys...) {
@safe bool opBinaryRight(string op:"in", T)(in T x) const pure nothrow {
switch (x) {
default:
return false;
foreach (k; keys) {
case k:
return true;
}
}
return false;
}
}
__gshared int p = 1234567890;
void a() {
assert(p !in ctEither!(1, 12, 123, 1234, 12345, 123456, 1234567, 12345678,
123456789)() );
}
void b() {
assert(p !in either(1, 12, 123, 1234, 12345, 123456, 1234567, 12345678,
123456789));
}
void c() {
assert(![1, 12, 123, 1234, 12345, 123456, 1234567, 12345678,
123456789].canFind(p));
}
void d() {
assert(!(p == 1 || p == 12 || p == 123 || p == 1234 || p == 12345 || p ==
123456 || p == 1234567 || p == 12345678 || p == 123456789));
}
void e() {
assert(p !in ctEither2!(1, 12, 123, 1234, 12345, 123456, 1234567, 12345678,
123456789)() );
}
void main() {
writeln( benchmark!c(1_000_000)[0].to!("msecs", int) );
writeln( benchmark!a(1_000_000)[0].to!("msecs", int) );
writeln( benchmark!b(1_000_000)[0].to!("msecs", int) );
writeln( benchmark!d(1_000_000)[0].to!("msecs", int) );
writeln( benchmark!e(1_000_000)[0].to!("msecs", int) );
}