Am Mon, 16 Dec 2013 15:04:09 -0800 schrieb Andrei Alexandrescu <[email protected]>:
> On 12/16/13 2:55 PM, "Ola Fosheim Grøstad" > <[email protected]>" wrote: > > On Monday, 16 December 2013 at 21:45:40 UTC, Walter Bright wrote: > >>> 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. > > > > I would expect one table-lookup for this if vals contains strings, not N > > ifs. If you look at the example, most of them could be done with perfect > > hashing on a single character. > > > > Is it possible for the compiler/template system to turn this into a > > switch/dictionary? Or is there something in the language/compiler that > > makes that impossible? > > It's a good idea, but unfortunately we don't have partial evaluation. > We'd need to move whatever compile-time work is to be done in the > template arguments area, i.e. > > value.among!("foo", "bar", "baz") > > as opposed to > > value.among("foo", "bar", "baz") > > Now that I think of it we can easily support both forms. > > > > Andrei This works well in general. I did the same for writing bits to a stream: writeBits()(uint bits, uint value) writeBits(uint bits)(uint value) (Now with 2.064 the empty template parenthesis can be omitted.) Knowing that the bit count is 9 or less, you can optimize for a case that only writes to two bytes. The one bit case doesn't even need branching at all. -- Marco
