On Sunday, 27 May 2018 at 20:38:25 UTC, Daniel Kozak wrote:
I would rewrite it to something like this:

template BTree(ValueT, KeyT = ValueT,alias KeyF = unaryFun!"cast(const)a")
{
    class BTree
    {

This is roughly what I originally had, but it creates a number of problems that I wanted to get around. Changing KeyF back to an alias means that any function that uses it can no longer be const, pure, @nogc, or nothrow. Essentially the parameter is just anything the user provides.

If I use a template value-parameter, then it forces any lambda the user passes in to either match the type I enter in (with const, pure, etc.) or the program to fail to compile. That is, I don't want the user to pass in any function, but only functions with the desired attributes. I.e., I wouldn't want them to pass in for KeyF something like "a.data--".

Listing out the full type does indeed work correctly with various examples, and letting the user pass in something like `a => a._id` does compile, but the only problem is that when there are two such template instances in the same program.

Logically `BTree!(MyStruct, int, a => a.id)`, `BTree!(AnotherStruct, char, a => a.name[0])`, `BTree!int` and `BTree!char` should all be totally independent. But for reasons unknown, the individual parameters seems to be swapped and and confused during compilation.

In the error above I listed. The function parameter from `BTree!char` is being used to create a compile error against `BTree!int`, which is very odd. Each of these classes compile and run just fine individually, the compilation only breaks when both exist.


Reply via email to