between and among: worth Phobosization?
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Dec 16 14:10:52 PST 2013
On 12/16/13 1:45 PM, Walter Bright wrote:
> On 12/16/2013 12:38 PM, Andrei Alexandrescu wrote:
>> bool between(T, U1, U2)(T v, U1 lo, U2 hi)
>> {
>> return v >= lo && v <= hi;
>> }
>
> You'd need 4 such functions, < <, < <=, <= <, <= <=, and it just seems
> like trivia.
The behavior is taken from SQL where it's closed both ends.
>> uint among(T, Us...)(T v, Us vals)
>> {
>> foreach (i, U; Us)
>> {
>> if (v == vals[i]) return i + 1;
>> }
>> return 0;
>> }
>
> This has O(n) behavior, which might be unexpected for the user.
It's O(1) because the data size is in the source text. There's no
variable n.
There's quite a bit of evidence in support of among (not as much for
between) in the source code of Facebook's cpplint, soon to be open
sourced. Here are some relevant quotes:
bool atBuiltinType(R)(R it) {
return it.front.type_.among(tk!"double", tk!"float", tk!"int",
tk!"short",
tk!"unsigned", tk!"long", tk!"signed", tk!"void", tk!"bool",
tk!"wchar_t",
tk!"char") != 0;
}
...
string[] readQualifiedIdentifier(R)(ref R it) {
string[] result;
for (; it.front.type_.among(tk!"identifier", tk!"::"); it.popFront) {
if (it.front.type_ == tk!"identifier") {
result ~= it.front.value_;
}
}
return result;
}
...
if (it.front.type_.among(tk!"class", tk!"struct", tk!"union")) {
result += callback(it, v);
}
...
if (it.front.type_.among(tk!"namespace", tk!"class", tk!"struct",
tk!"union", tk!"{")) {
auto term = it.find!(x => x.type_ == tk!"{");
if (term.empty) {
break;
}
it = skipBlock(term);
continue;
}
...
if (v[i .. $].atSequence(tk!"#", tk!"if")
|| (v[i .. $].atSequence(tk!"#", tk!"identifier")
&& v[i + 1].value_.among("ifndef", "ifdef"))) {
++openIf;
} else if (v[i .. $].atSequence(tk!"#", tk!"identifier")
&& v[i + 1].value_ == "endif") {
++i; // hop over the else
--openIf;
}
...
auto term = it.find!((t) => t.type_.among(tk!":", tk!"{"));
...
static bool endsClass(CppLexer.TokenType2 tkt) {
return tkt.among(tk!"\0", tk!"{", tk!";") != 0;
}
...
static bool isAccessSpecifier(CppLexer.TokenType2 tkt) {
return tkt.among(tk!"private", tk!"public", tk!"protected") != 0;
}
...
while (i.front.type_.among(tk!"*", tk!"const", tk!"volatile")) {
i.popFront;
}
I invite you all to contemplate redoing all these and more from first
principles.
Andrei
More information about the Digitalmars-d
mailing list