1 module external_allocator_test;
2 
3 import containers.dynamicarray;
4 import containers.hashmap;
5 import containers.hashset;
6 import containers.immutablehashset;
7 import containers.openhashset;
8 import containers.simdset;
9 import containers.slist;
10 import containers.treemap;
11 import containers.ttree;
12 import containers.unrolledlist;
13 import std.experimental.allocator.building_blocks.free_list : FreeList;
14 import std.experimental.allocator.building_blocks.allocator_list : AllocatorList;
15 import std.experimental.allocator.building_blocks.region : Region;
16 import std.experimental.allocator.building_blocks.stats_collector : StatsCollector;
17 import std.stdio : stdout;
18 import std.algorithm.iteration : walkLength;
19 import std.meta : AliasSeq;
20 
21 // Chosen for a very important and completely undocumented reason
22 private enum VERY_SPECIFIC_NUMBER = 371;
23 
24 private void testSingle(alias Container, Allocator)(Allocator allocator)
25 {
26 	auto intMap = Container!(int, Allocator)(allocator);
27 	foreach (i; 0 .. VERY_SPECIFIC_NUMBER)
28 		intMap.insert(i);
29 	assert(intMap.length == VERY_SPECIFIC_NUMBER);
30 }
31 
32 private void testDouble(alias Container, Allocator)(Allocator allocator)
33 {
34 	auto intMap = Container!(int, int, Allocator)(allocator);
35 	foreach (i; 0 .. VERY_SPECIFIC_NUMBER)
36 		intMap[i] = VERY_SPECIFIC_NUMBER - i;
37 	assert(intMap.length == VERY_SPECIFIC_NUMBER);
38 }
39 
40 alias SingleContainers = AliasSeq!(DynamicArray,  HashSet,  /+ImmutableHashSet,+/
41 OpenHashSet, SimdSet, SList, TTree, UnrolledList);
42 
43 alias DoubleContainers = AliasSeq!(HashMap, TreeMap);
44 
45 alias AllocatorType = StatsCollector!(
46 	FreeList!(AllocatorList!(a => Region!(Mallocator)(1024 * 1024), Mallocator), 64));
47 
48 unittest
49 {
50 	foreach (C; SingleContainers)
51 	{
52 		AllocatorType allocator;
53 		testSingle!(C, AllocatorType*)(&allocator);
54 		assert(allocator.numAllocate > 0 || allocator.numReallocate > 0,
55 			"No allocations happened for " ~ C.stringof);
56 		assert(allocator.numAllocate == allocator.numDeallocate || allocator.numReallocate > 0);
57 		assert(allocator.bytesUsed == 0);
58 	}
59 	foreach (C; DoubleContainers)
60 	{
61 		AllocatorType allocator;
62 		testDouble!(C, AllocatorType*)(&allocator);
63 		assert(allocator.numAllocate > 0 || allocator.numReallocate > 0,
64 			"No allocations happened for " ~ C.stringof);
65 		assert(allocator.numAllocate == allocator.numDeallocate || allocator.numReallocate > 0);
66 		assert(allocator.bytesUsed == 0);
67 	}
68 }