module containers.internal.node; template fatNodeCapacity(size_t bytesPerItem, size_t pointerCount, T, size_t cacheLineSize = 64) { enum size_t optimistic = (cacheLineSize - ((void*).sizeof * pointerCount) - T.sizeof) / bytesPerItem; static if (optimistic > 0) enum fatNodeCapacity = optimistic; else enum fatNodeCapacity = 1; } // Double linked fat node of int with bookkeeping in a uint should be able to // hold 11 ints per node. // 64 - 16 - 4 = 4 * 11 version (X86_64) static assert (fatNodeCapacity!(int.sizeof, 2, uint) == 11); template shouldNullSlot(T) { import std.traits; enum shouldNullSlot = isPointer!T || is (T == class); } template shouldAddGCRange(T) { import std.traits; enum shouldAddGCRange = isPointer!T || hasIndirections!T || is (T == class); } static assert (shouldAddGCRange!string); static assert (!shouldAddGCRange!int); template fullBits(size_t n, size_t c = 0) { static if (c >= (n - 1)) enum fullBits = (1 << c); else enum fullBits = (1 << c) | fullBits!(n, c + 1); } static assert (fullBits!1 == 1); static assert (fullBits!2 == 3); static assert (fullBits!3 == 7); static assert (fullBits!4 == 15);