Consider the following program:
void main()
{
import std.stdio;
import std.container.rbtree;
import std.variant;
// alias Type = int; // Works with no problem.
alias Type = Variant; // Produces error.
auto rbTree = new RedBlackTree!(Type);
rbTree.stableInsert(Type(3));
rbTree.stableInsert(Type(2));
rbTree.stableInsert(Type(4));
foreach (v; rbTree.upperBound(Type(2))) {
writeln(v);
}
}
A RedBlackTree
constructs and runs perfectly fine using "int" as the data type, but it seems to blow up as soon as I use std.variant : Variant
.
Compilation output (1: )
/dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1116): Error: `@safe` function `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false).RedBlackTree.toHash` cannot call `@system` function `std.container.rbtree.RBRange!(RBNode!(VariantN!32LU)*).RBRange.front`
/dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(682): `std.container.rbtree.RBRange!(RBNode!(VariantN!32LU)*).RBRange.front` is declared here
/dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1116): Error: destructor `std.variant.VariantN!32LU.VariantN.~this` is not `nothrow`
/dlang/dmd/linux/bin64/../../src/phobos/std/container/rbtree.d(1113): Error: function `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false).RedBlackTree.toHash` may throw but is marked as `nothrow`
onlineapp.d(10): Error: template instance `std.container.rbtree.RedBlackTree!(VariantN!32LU, "a < b", false)` error instantiating
This may seem like a strange thing to do, but it is useful when trying to have set of indexes, each of which is used on a different data field. The set of indexes can share a common data-type using Variant, which allows one to do things like have associative arrays of indexes which you can look up by field name.
However, it looks like Variant
doesn't have the various attributes desired by RedBlackTree
. Is there a way to make them compatible? Do I need to avoid std.container.rbtree and make my own which doesn't require these attributes, or do I need to implement my own version of Variant using a union and try to make it safe/nothrow/etc.?