From 53288c653aec9906a5bd41c62ef7a14c799ece7b Mon Sep 17 00:00:00 2001 From: maozh Date: Mon, 23 Oct 2023 21:09:17 +0800 Subject: [PATCH 1/3] add @nogc when use nogc Allocator and do not addGCRange --- src/containers/cyclicbuffer.d | 8 ++++++-- src/containers/dynamicarray.d | 13 +++++++++---- src/containers/hashmap.d | 9 +++++---- src/containers/hashset.d | 3 +++ src/containers/immutablehashset.d | 3 +++ src/containers/internal/node.d | 10 +++++++++- src/containers/openhashset.d | 3 +++ src/containers/simdset.d | 4 ++++ src/containers/slist.d | 3 +++ src/containers/treemap.d | 3 +++ src/containers/ttree.d | 3 +++ src/containers/unrolledlist.d | 4 ++++ 12 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/containers/cyclicbuffer.d b/src/containers/cyclicbuffer.d index ee16790..a579b95 100644 --- a/src/containers/cyclicbuffer.d +++ b/src/containers/cyclicbuffer.d @@ -10,7 +10,7 @@ module containers.cyclicbuffer; private import core.exception : onRangeError; private import std.experimental.allocator.mallocator : Mallocator; private import std.range.primitives : empty, front, back, popFront, popBack; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; /** * Array that provides constant time (amortized) appending and popping @@ -23,11 +23,15 @@ private import containers.internal.node : shouldAddGCRange; */ struct CyclicBuffer(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange!T) { + + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } @disable this(this); private import std.conv : emplace; private import std.experimental.allocator.common : stateSize; - private import std.traits : isImplicitlyConvertible, hasElaborateDestructor; + private import std.traits : isImplicitlyConvertible, hasElaborateDestructor,hasFunctionAttributes; static if (stateSize!Allocator != 0) { diff --git a/src/containers/dynamicarray.d b/src/containers/dynamicarray.d index 90c16f4..8baa3df 100644 --- a/src/containers/dynamicarray.d +++ b/src/containers/dynamicarray.d @@ -8,8 +8,8 @@ module containers.dynamicarray; private import core.lifetime : move, moveEmplace, copyEmplace, emplace; -private import std.traits : isCopyable; -private import containers.internal.node : shouldAddGCRange; +private import std.traits : isCopyable,hasFunctionAttributes; +private import containers.internal.node : shouldAddGCRange, isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; /** @@ -24,10 +24,15 @@ private import std.experimental.allocator.mallocator : Mallocator; */ struct DynamicArray(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange!T) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } this(this) @disable; private import std.experimental.allocator.common : stateSize; + + static if (is(typeof((T[] a, const T[] b) => a[0 .. b.length] = b[0 .. $]))) { /// Either `const(T)` or `T`. @@ -346,8 +351,8 @@ struct DynamicArray(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange } else { - import core.exception : RangeError; - throw new RangeError("Out of range index used to remove element"); + import core.exception : onRangeError; + onRangeError("Out of range index used to remove element"); } } diff --git a/src/containers/hashmap.d b/src/containers/hashmap.d index eb9c684..6ade254 100644 --- a/src/containers/hashmap.d +++ b/src/containers/hashmap.d @@ -11,7 +11,7 @@ private import core.lifetime : move; private import containers.internal.hash; private import containers.internal.node : shouldAddGCRange; private import std.experimental.allocator.mallocator : Mallocator; -private import std.traits : isBasicType, Unqual; +private import std.traits : isBasicType, Unqual,hasFunctionAttributes; /** * Associative array / hash map. @@ -27,6 +27,9 @@ struct HashMap(K, V, Allocator = Mallocator, alias hashFunction = generateHash!K bool supportGC = shouldAddGCRange!K || shouldAddGCRange!V, bool storeHash = true) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } this(this) @disable; private import std.experimental.allocator.common : stateSize; @@ -71,9 +74,7 @@ struct HashMap(K, V, Allocator = Mallocator, alias hashFunction = generateHash!K static if (is(typeof(allocator is null))) assert(allocator !is null, "Allocator must not be null"); } - } - else - { + } else { /** * Constructs an HashMap with an initial bucket count of bucketCount. bucketCount * must be a power of two. diff --git a/src/containers/hashset.d b/src/containers/hashset.d index cf1c3e8..2668d23 100644 --- a/src/containers/hashset.d +++ b/src/containers/hashset.d @@ -25,6 +25,9 @@ struct HashSet(T, Allocator = Mallocator, alias hashFunction = generateHash!T, bool supportGC = shouldAddGCRange!T, bool storeHash = !isBasicType!T) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } this(this) @disable; private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/immutablehashset.d b/src/containers/immutablehashset.d index e6cf5ea..0131cca 100644 --- a/src/containers/immutablehashset.d +++ b/src/containers/immutablehashset.d @@ -17,6 +17,9 @@ module containers.immutablehashset; */ struct ImmutableHashSet(T, alias hashFunction) { + static if(isNoGCAllocator!(Allocator) && !supportGC){ + @nogc: + } /// @disable this(); /// diff --git a/src/containers/internal/node.d b/src/containers/internal/node.d index d18ec04..1941c8f 100644 --- a/src/containers/internal/node.d +++ b/src/containers/internal/node.d @@ -53,7 +53,7 @@ version (X86_64) template shouldNullSlot(T) { import std.traits; - enum shouldNullSlot = isPointer!T || is (T == class) || is (T == interface) || isDynamicArray!T + enum shouldNullSlot = isPointer!T || is (T == class) || is (T == interface) || isDynamicArray!T || is(T == delegate); // closures or class method shoulde be null for GC recycle } @@ -63,6 +63,14 @@ template shouldAddGCRange(T) enum shouldAddGCRange = hasIndirections!T; } + +template isNoGCAllocator(Allocator) +{ + import std.traits : hasFunctionAttributes; + enum isNoGCAllocator = hasFunctionAttributes!(Allocator.deallocate, "@nogc") + && hasFunctionAttributes!(Allocator.allocate, "@nogc"); +} + static assert (shouldAddGCRange!string); static assert (!shouldAddGCRange!int); diff --git a/src/containers/openhashset.d b/src/containers/openhashset.d index 8a74afa..9693b12 100644 --- a/src/containers/openhashset.d +++ b/src/containers/openhashset.d @@ -28,6 +28,9 @@ struct OpenHashSet(T, Allocator = Mallocator, /** * Disallow copy construction */ + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } this(this) @disable; static if (stateSize!Allocator != 0) diff --git a/src/containers/simdset.d b/src/containers/simdset.d index 8effa3a..eac0ed7 100644 --- a/src/containers/simdset.d +++ b/src/containers/simdset.d @@ -24,10 +24,14 @@ private import std.experimental.allocator.mallocator : Mallocator; version (D_InlineAsm_X86_64) struct SimdSet(T, Allocator = Mallocator) if (T.sizeof == 1 || T.sizeof == 2 || T.sizeof == 4 || T.sizeof == 8) { + static if(isNoGCAllocator!(Allocator)) { + @nogc: + } this(this) @disable; private import std.experimental.allocator.common : stateSize; + static if (stateSize!Allocator != 0) { /// No default construction if an allocator must be provided. diff --git a/src/containers/slist.d b/src/containers/slist.d index a0d1de8..0027657 100644 --- a/src/containers/slist.d +++ b/src/containers/slist.d @@ -20,6 +20,9 @@ private import std.experimental.allocator.mallocator : Mallocator; */ struct SList(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange!T) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } /// Disable copying. this(this) @disable; diff --git a/src/containers/treemap.d b/src/containers/treemap.d index b59ebc2..888c39e 100644 --- a/src/containers/treemap.d +++ b/src/containers/treemap.d @@ -23,6 +23,9 @@ private import std.experimental.allocator.mallocator : Mallocator; struct TreeMap(K, V, Allocator = Mallocator, alias less = "a < b", bool supportGC = shouldAddGCRange!K || shouldAddGCRange!V, size_t cacheLineSize = 64) { + static if(isNoGCAllocator!(Allocator) && !supportGC){ + @nogc: + } this(this) @disable; private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/ttree.d b/src/containers/ttree.d index 5e7e908..fd5d458 100644 --- a/src/containers/ttree.d +++ b/src/containers/ttree.d @@ -37,6 +37,9 @@ private import std.experimental.allocator.mallocator : Mallocator; struct TTree(T, Allocator = Mallocator, bool allowDuplicates = false, alias less = "a < b", bool supportGC = shouldAddGCRange!T, size_t cacheLineSize = 64) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } /** * T-Trees are not copyable due to the way they manage memory and interact * with allocators. diff --git a/src/containers/unrolledlist.d b/src/containers/unrolledlist.d index 15d963b..21356d8 100644 --- a/src/containers/unrolledlist.d +++ b/src/containers/unrolledlist.d @@ -32,6 +32,10 @@ version (X86_64) struct UnrolledList(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange!T, size_t cacheLineSize = 64) { + static if(isNoGCAllocator!(Allocator) && !supportGC) { + @nogc: + } + this(this) @disable; private import std.experimental.allocator.common : stateSize; From d2fcabbd36f456f27ea1e8a4931a66bdd226accf Mon Sep 17 00:00:00 2001 From: maozh Date: Mon, 23 Oct 2023 21:18:02 +0800 Subject: [PATCH 2/3] replace 'this(this)' to Copy Constructor syntax --- src/containers/cyclicbuffer.d | 6 +++++- src/containers/dynamicarray.d | 4 ++++ src/containers/hashmap.d | 4 ++++ src/containers/hashset.d | 4 ++++ src/containers/immutablehashset.d | 6 +++++- src/containers/openhashset.d | 10 +++++++--- src/containers/simdset.d | 4 ++++ src/containers/slist.d | 4 ++++ src/containers/treemap.d | 5 +++++ src/containers/ttree.d | 4 ++++ src/containers/unrolledlist.d | 4 ++++ 11 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/containers/cyclicbuffer.d b/src/containers/cyclicbuffer.d index a579b95..40538af 100644 --- a/src/containers/cyclicbuffer.d +++ b/src/containers/cyclicbuffer.d @@ -27,7 +27,11 @@ struct CyclicBuffer(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } - @disable this(this); +static if (__VERSION__ > 2086) { + @disable this(ref CyclicBuffer); +} else { + this(this) @disable; +} private import std.conv : emplace; private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/dynamicarray.d b/src/containers/dynamicarray.d index 8baa3df..e7a583c 100644 --- a/src/containers/dynamicarray.d +++ b/src/containers/dynamicarray.d @@ -27,7 +27,11 @@ struct DynamicArray(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } +static if (__VERSION__ > 2086) { + @disable this(ref DynamicArray); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/hashmap.d b/src/containers/hashmap.d index 6ade254..c5782a3 100644 --- a/src/containers/hashmap.d +++ b/src/containers/hashmap.d @@ -30,7 +30,11 @@ struct HashMap(K, V, Allocator = Mallocator, alias hashFunction = generateHash!K static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } +static if (__VERSION__ > 2086) { + @disable this(ref HashMap); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/hashset.d b/src/containers/hashset.d index 2668d23..ef801b1 100644 --- a/src/containers/hashset.d +++ b/src/containers/hashset.d @@ -28,7 +28,11 @@ struct HashSet(T, Allocator = Mallocator, alias hashFunction = generateHash!T, static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } +static if (__VERSION__ > 2086) { + @disable this(ref HashSet); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/immutablehashset.d b/src/containers/immutablehashset.d index 0131cca..46bf283 100644 --- a/src/containers/immutablehashset.d +++ b/src/containers/immutablehashset.d @@ -23,7 +23,11 @@ struct ImmutableHashSet(T, alias hashFunction) /// @disable this(); /// - @disable this(this); +static if (__VERSION__ > 2086) { + @disable this(ref ImmutableHashSet); +} else { + this(this) @disable; +} /** * Constructs an immutable hash set from the given values. The values must diff --git a/src/containers/openhashset.d b/src/containers/openhashset.d index 9693b12..9654483 100644 --- a/src/containers/openhashset.d +++ b/src/containers/openhashset.d @@ -25,13 +25,17 @@ private import std.experimental.allocator.mallocator : Mallocator; struct OpenHashSet(T, Allocator = Mallocator, alias hashFunction = generateHash!T, bool supportGC = shouldAddGCRange!T) { - /** - * Disallow copy construction - */ static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } + /** + * Disallow copy construction + */ +static if (__VERSION__ > 2086) { + @disable this(ref OpenHashSet); +} else { this(this) @disable; +} static if (stateSize!Allocator != 0) { diff --git a/src/containers/simdset.d b/src/containers/simdset.d index eac0ed7..5bbcd5d 100644 --- a/src/containers/simdset.d +++ b/src/containers/simdset.d @@ -27,7 +27,11 @@ version (D_InlineAsm_X86_64) struct SimdSet(T, Allocator = Mallocator) static if(isNoGCAllocator!(Allocator)) { @nogc: } +static if (__VERSION__ > 2086) { + @disable this(ref SimdSet); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/slist.d b/src/containers/slist.d index 0027657..63301a1 100644 --- a/src/containers/slist.d +++ b/src/containers/slist.d @@ -24,7 +24,11 @@ struct SList(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange!T) @nogc: } /// Disable copying. +static if (__VERSION__ > 2086) { + @disable this(ref SList); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/treemap.d b/src/containers/treemap.d index 888c39e..ff86251 100644 --- a/src/containers/treemap.d +++ b/src/containers/treemap.d @@ -26,7 +26,12 @@ struct TreeMap(K, V, Allocator = Mallocator, alias less = "a < b", static if(isNoGCAllocator!(Allocator) && !supportGC){ @nogc: } + +static if (__VERSION__ > 2086) { + @disable this(ref TreeMap); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; diff --git a/src/containers/ttree.d b/src/containers/ttree.d index fd5d458..0a161d5 100644 --- a/src/containers/ttree.d +++ b/src/containers/ttree.d @@ -44,7 +44,11 @@ struct TTree(T, Allocator = Mallocator, bool allowDuplicates = false, * T-Trees are not copyable due to the way they manage memory and interact * with allocators. */ +static if (__VERSION__ > 2086) { + @disable this(ref TTree); +} else { this(this) @disable; +} static if (stateSize!Allocator != 0) { diff --git a/src/containers/unrolledlist.d b/src/containers/unrolledlist.d index 21356d8..39d39f2 100644 --- a/src/containers/unrolledlist.d +++ b/src/containers/unrolledlist.d @@ -36,7 +36,11 @@ struct UnrolledList(T, Allocator = Mallocator, @nogc: } +static if (__VERSION__ > 2086) { + @disable this(ref UnrolledList); +} else { this(this) @disable; +} private import std.experimental.allocator.common : stateSize; From 2727b6fe8a2f17a8d1ddc1cdb87ddbebee576b79 Mon Sep 17 00:00:00 2001 From: maozh Date: Mon, 23 Oct 2023 22:48:20 +0800 Subject: [PATCH 3/3] fix the erro and deprecate --- src/containers/dynamicarray.d | 23 ++++++++++------------- src/containers/hashmap.d | 4 ++-- src/containers/hashset.d | 2 +- src/containers/immutablehashset.d | 7 +++---- src/containers/openhashset.d | 2 +- src/containers/simdset.d | 2 +- src/containers/slist.d | 2 +- src/containers/treemap.d | 2 +- src/containers/ttree.d | 7 ++++--- src/containers/unrolledlist.d | 2 +- 10 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/containers/dynamicarray.d b/src/containers/dynamicarray.d index e7a583c..0ba0e2a 100644 --- a/src/containers/dynamicarray.d +++ b/src/containers/dynamicarray.d @@ -27,11 +27,8 @@ struct DynamicArray(T, Allocator = Mallocator, bool supportGC = shouldAddGCRange static if(isNoGCAllocator!(Allocator) && !supportGC) { @nogc: } -static if (__VERSION__ > 2086) { - @disable this(ref DynamicArray); -} else { + this(this) @disable; -} private import std.experimental.allocator.common : stateSize; @@ -73,9 +70,6 @@ static if (__VERSION__ > 2086) { ~this() { - import std.experimental.allocator.mallocator : Mallocator; - import containers.internal.node : shouldAddGCRange; - if (arr is null) return; @@ -122,9 +116,6 @@ static if (__VERSION__ > 2086) { */ void insertBack(T value) { - import std.experimental.allocator.mallocator : Mallocator; - import containers.internal.node : shouldAddGCRange; - if (arr.length == 0) { arr = cast(typeof(arr)) allocator.allocate(T.sizeof * 4); @@ -284,8 +275,14 @@ static if (__VERSION__ > 2086) { foreach (ref target; toFill) emplace(&target); } - else - toFill[] = T.init; + else { + foreach (ref target; toFill){ + target = T.init; + } + //it not work in 2.102.2, see: https://issues.dlang.org/show_bug.cgi?id=24196 + // toFill[] = T.init; + } + } /** @@ -701,7 +698,7 @@ version(emsi_containers_unittest) @nogc unittest assert(Counter.count == 3); } -version(emsi_containers_unittest) @nogc unittest +version(emsi_containers_unittest) @nogc unittest { struct S { int i = 42; @disable this(this); } DynamicArray!S a; diff --git a/src/containers/hashmap.d b/src/containers/hashmap.d index c5782a3..e44134f 100644 --- a/src/containers/hashmap.d +++ b/src/containers/hashmap.d @@ -9,7 +9,7 @@ module containers.hashmap; private import core.lifetime : move; private import containers.internal.hash; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; private import std.traits : isBasicType, Unqual,hasFunctionAttributes; @@ -668,7 +668,7 @@ version(emsi_containers_unittest) unittest string name; } - void someFunc(const scope ref HashMap!(string,Foo) map) @safe + void someFunc(const ref HashMap!(string,Foo) map) @safe { foreach (kv; map.byKeyValue()) { diff --git a/src/containers/hashset.d b/src/containers/hashset.d index ef801b1..7779f78 100644 --- a/src/containers/hashset.d +++ b/src/containers/hashset.d @@ -8,7 +8,7 @@ module containers.hashset; private import containers.internal.hash : generateHash, hashToIndex; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; private import std.traits : isBasicType; diff --git a/src/containers/immutablehashset.d b/src/containers/immutablehashset.d index 46bf283..cbd6f81 100644 --- a/src/containers/immutablehashset.d +++ b/src/containers/immutablehashset.d @@ -7,6 +7,9 @@ module containers.immutablehashset; +private import containers.internal.node : shouldAddGCRange; + + /** * The immutable hash set is useful for constructing a read-only collection that * supports quickly determining if an element is present. @@ -17,9 +20,6 @@ module containers.immutablehashset; */ struct ImmutableHashSet(T, alias hashFunction) { - static if(isNoGCAllocator!(Allocator) && !supportGC){ - @nogc: - } /// @disable this(); /// @@ -162,7 +162,6 @@ private: import std.experimental.allocator.mallocator : Mallocator; import std.traits : isBasicType, hasMember; - import containers.internal.node : shouldAddGCRange; import core.memory : GC; static struct Node diff --git a/src/containers/openhashset.d b/src/containers/openhashset.d index 9654483..8ff746c 100644 --- a/src/containers/openhashset.d +++ b/src/containers/openhashset.d @@ -7,7 +7,7 @@ module containers.openhashset; private import containers.internal.hash; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.common : stateSize; private import std.experimental.allocator.mallocator : Mallocator; diff --git a/src/containers/simdset.d b/src/containers/simdset.d index 5bbcd5d..5270ac3 100644 --- a/src/containers/simdset.d +++ b/src/containers/simdset.d @@ -7,7 +7,7 @@ module containers.simdset; private import std.experimental.allocator.mallocator : Mallocator; - +private import containers.internal.node : isNoGCAllocator; /** * Set implementation that is well suited for small sets and simple items. * diff --git a/src/containers/slist.d b/src/containers/slist.d index 63301a1..bdcee73 100644 --- a/src/containers/slist.d +++ b/src/containers/slist.d @@ -7,7 +7,7 @@ module containers.slist; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; /** diff --git a/src/containers/treemap.d b/src/containers/treemap.d index ff86251..18c3179 100644 --- a/src/containers/treemap.d +++ b/src/containers/treemap.d @@ -7,7 +7,7 @@ module containers.treemap; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; /** diff --git a/src/containers/ttree.d b/src/containers/ttree.d index 0a161d5..ce7d0f7 100644 --- a/src/containers/ttree.d +++ b/src/containers/ttree.d @@ -7,7 +7,7 @@ module containers.ttree; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import containers.internal.mixins : AllocatorState; private import std.experimental.allocator.mallocator : Mallocator; @@ -906,7 +906,7 @@ private: return r; } - void rotateLeft(ref Node* root, AllocatorType allocator) @safe + void rotateLeft(ref Node* root, AllocatorType allocator) @trusted { Node* newRoot; if (right.left !is null && right.right is null) @@ -934,7 +934,7 @@ private: cleanup(newRoot, root, allocator); } - void rotateRight(ref Node* root, AllocatorType allocator) @safe + void rotateRight(ref Node* root, AllocatorType allocator) @trusted { Node* newRoot; if (left.right !is null && left.left is null) @@ -951,6 +951,7 @@ private: } else { + newRoot = left; newRoot.parent = this.parent; left = newRoot.right; diff --git a/src/containers/unrolledlist.d b/src/containers/unrolledlist.d index 39d39f2..abb68b1 100644 --- a/src/containers/unrolledlist.d +++ b/src/containers/unrolledlist.d @@ -8,7 +8,7 @@ module containers.unrolledlist; private import core.lifetime : move; -private import containers.internal.node : shouldAddGCRange; +private import containers.internal.node : shouldAddGCRange,isNoGCAllocator; private import std.experimental.allocator.mallocator : Mallocator; version (X86_64)