Enable addition of allocated items to the GC scan range regardless of the used type.
Disable addition of allocated items to the GC scan range regardless of the used type.
Checks T parameter and decides accordingly whether T items allocated by the LinkedListQueue will be added to the GC scan range.
Test walking over the linked list
auto list = new LinkedListQueue!(int); bool iterated = false; foreach (item; list) iterated = true; test!("==")(iterated, false); *list.push = 0; *list.push = 1; *list.push = 2; size_t count; size_t idx; foreach (item; list) { test!("==")(item, idx++); ++count; } test!("==")(count, 3);
Test root_values is determined correctly
struct emptyStruct { } struct someStruct { int[] array; } class someClass { } // int test((new LinkedListQueue!(int)).root_values == false, "'int' should not be added as GC root"); test((new LinkedListQueue!(int, GCTrackingPolicy.refTypesOnly)).root_values == false, "'int' should not be added as GC root (2)"); // empty struct test((new LinkedListQueue!(emptyStruct)).root_values == false, "An empty struct should not be added as GC root"); test((new LinkedListQueue!(emptyStruct, GCTrackingPolicy.refTypesOnly)).root_values == false, "An empty struct should not be added as GC root (2)"); // struct that points to GC memory test((new LinkedListQueue!(someStruct)).root_values, "A struct containing an array should be added as GC root!"); test((new LinkedListQueue!(someStruct, GCTrackingPolicy.refTypesOnly)).root_values, "A struct containing an array should be added as GC root (2)!"); // pointer to struct test((new LinkedListQueue!(emptyStruct*)).root_values, "A pointer to a struct should be added as GC root!"); test((new LinkedListQueue!(emptyStruct*, GCTrackingPolicy.refTypesOnly)).root_values, "A pointer to a struct should be added as GC root (2)!"); // class test((new LinkedListQueue!(someClass)).root_values, "A class should be added as GC root!"); test((new LinkedListQueue!(someClass, GCTrackingPolicy.refTypesOnly)).root_values, "A class should be added as GC root (2)!"); // Test forcing a GC policy test((new LinkedListQueue!(someClass, GCTrackingPolicy.never)).root_values == false, "GC scanning should be forcefully disabled for class!"); test((new LinkedListQueue!(int, GCTrackingPolicy.always)).root_values, "GC scanning should be forcefully enabled for ints!"); test((new LinkedListQueue!(emptyStruct, GCTrackingPolicy.always)).root_values, "GC scanning should be forcefully enabled for empty struct!");
Test ITypedQueue methods
class JustSomeClass { protected int just_some_int; public this ( int set_just_some_int ) { this.just_some_int = set_just_some_int; } override public equals_t opEquals ( Object _another ) { auto another = cast(JustSomeClass) _another; if (another is null) return false; return this.just_some_int == another.just_some_int; } } // T = int LinkedListQueue!(int) integersList = new LinkedListQueue!(int)(); // T = JustSomeClass LinkedListQueue!(JustSomeClass) classesList = new LinkedListQueue!(JustSomeClass)(); static immutable int size = 100; int[] int_array; JustSomeClass[] class_array; for(int i = 0; i < size; i++) { int_array ~= i; class_array ~= new JustSomeClass(i); } testInterfaceMethods(integersList, int_array); testInterfaceMethods(classesList, class_array);
Test LinkedListQueue methods
1 /************************************************************************** 2 3 A class to test LinkedListQueue. 4 5 The 'invariant' section validates the exact content of the 6 LinkedListQueue. And in case of validation failure the name of the 7 particular test is printed. 8 9 ***************************************************************************/ 10 11 class TestQueue 12 { 13 /********************************************************************** 14 15 The tested LinkedListQueue 16 17 ***********************************************************************/ 18 19 protected LinkedListQueue!(int) int_queue; 20 21 22 /********************************************************************** 23 24 The values expected to be in intQueue, and their expected order 25 26 ***********************************************************************/ 27 28 protected int[] expected_values; 29 30 31 /********************************************************************** 32 33 The name of the particular test, to be printed in case of test 34 failure 35 36 ***********************************************************************/ 37 38 protected istring name; 39 40 41 /********************************************************************** 42 43 Constructor 44 45 Params: 46 in_name = The name of the particular test 47 48 ***********************************************************************/ 49 50 public this (istring in_name) 51 { 52 this.int_queue = new LinkedListQueue!(int)(); 53 this.name = in_name; 54 } 55 56 57 /********************************************************************** 58 59 Invarinat to validate the contents in int_queue and expected_values 60 are the same. 61 62 ***********************************************************************/ 63 64 invariant ( ) 65 { 66 auto _this = cast(TestQueue) this; 67 68 test( 69 _this.int_queue.length() == _this.expected_values.length, 70 name ~ ": length should be the same" 71 ); 72 73 if ( _this.expected_values.length == 0 ) 74 { 75 test(_this.int_queue.empty(), name ~ ": queue should be mepty"); 76 test(_this.int_queue.top() == null, 77 name ~ ": queue is empty. Top should have returned null"); 78 test(_this.int_queue.bottom() == null, 79 name ~ ": queue is empty. Bottom should have returned null"); 80 } 81 82 LinkedListQueue!(int).QueueItem* iterator = _this.int_queue.head; 83 84 // compare all values 85 foreach( value; _this.expected_values) 86 { 87 test(iterator.value == value, 88 name ~ ": value incorrect"); 89 iterator = iterator.next; 90 } 91 } 92 93 94 /********************************************************************** 95 96 Push values into LinkedListQueue. 97 98 Params: 99 values = values to push 100 101 ***********************************************************************/ 102 103 public void push ( int[] values ) 104 { 105 foreach( value; values ) 106 { 107 .push(this.int_queue, value); 108 this.expected_values ~= value; 109 test!("==")(*this.int_queue.bottom, value); 110 } 111 } 112 113 114 /********************************************************************** 115 116 Removes a value from LinkedListQueue. 117 118 Params: 119 value = value to remove 120 expected_to_remove = number of items expected to be removed 121 all = should all instances of value be removed 122 123 ***********************************************************************/ 124 125 public void remove ( int value, int expected_to_remove = 1, bool all = true ) 126 { 127 bool continue_remove = true; 128 129 if ( expected_to_remove ) 130 test(this.int_queue.contains(value), 131 name ~ ": value should have been found in LinkedListQueue"); 132 133 test(this.int_queue.remove(value, all) == expected_to_remove, 134 name ~ ": Removed wrong number of items from LinkedListQueue"); 135 test(!this.int_queue.contains(value), 136 name ~ ": value should NOT have been found in LinkedListQueue"); 137 138 if ( all ) 139 { 140 int[] result, match; 141 match ~= value; 142 this.expected_values = ocean.core.array.Transformation.remove( 143 this.expected_values, match, result); 144 } 145 else 146 { 147 foreach ( i, item; this.expected_values ) 148 { 149 if ( item == value ) 150 { 151 removeShift(this.expected_values, i); 152 break; 153 } 154 } 155 } 156 } 157 } 158 159 160 { 161 // [1] 162 TestQueue testQueue = new TestQueue("Test 'remove' from LinkedListQueue with a single item"); 163 testQueue.push([1]); 164 testQueue.remove(1); 165 } 166 { 167 // [3] 4 168 TestQueue testQueue = new TestQueue("Test 'remove' first item from LinkedListQueue"); 169 testQueue.push([3, 4]); 170 testQueue.remove(3); 171 } 172 { 173 // 5 [6] 174 TestQueue testQueue = new TestQueue("Test 'remove' last item from LinkedListQueue"); 175 testQueue.push([5, 6]); 176 testQueue.remove(6); 177 } 178 { 179 // [7] [8] 180 TestQueue testQueue = new TestQueue("Test 'remove' all items from LinkedListQueue"); 181 testQueue.push([7, 8]); 182 testQueue.remove(7); 183 testQueue.remove(8); 184 } 185 { 186 // 9 [10] 11 187 TestQueue testQueue = new TestQueue("Test 'remove' middle item from LinkedListQueue"); 188 testQueue.push([9, 10, 11]); 189 testQueue.remove(10); 190 } 191 { 192 // 12 [13] [14] 15 193 TestQueue testQueue = new TestQueue("Test 'remove' several middle items from LinkedListQueue"); 194 testQueue.push([12, 13, 14, 15]); 195 testQueue.remove(13); 196 testQueue.remove(14); 197 } 198 { 199 // [16] 17 18 [19] 200 TestQueue testQueue = new TestQueue("Test 'remove' first and last items from LinkedListQueue"); 201 testQueue.push([16, 17, 18, 19]); 202 testQueue.remove(16); 203 testQueue.remove(19); 204 } 205 { 206 // [20] 21 21 [20] 207 TestQueue testQueue = new TestQueue("Test 'remove' repeating values from LinkedListQueue"); 208 testQueue.push([20, 21, 21, 20]); 209 testQueue.remove(20, 2); 210 testQueue.remove(20, 0); 211 } 212 { 213 // remove from an empty queue 214 TestQueue testQueue = new TestQueue("Test 'remove' on an empty LinkedListQueue"); 215 testQueue.remove(1, 0); 216 }
A wrapper around common used policies for adding data allocated by the LinkedListQueue to the GC scan range.