GCTrackingPolicy

A wrapper around common used policies for adding data allocated by the LinkedListQueue to the GC scan range.

Members

Static functions

always
bool always()

Enable addition of allocated items to the GC scan range regardless of the used type.

never
bool never()

Disable addition of allocated items to the GC scan range regardless of the used type.

refTypesOnly
bool refTypesOnly()

Checks T parameter and decides accordingly whether T items allocated by the LinkedListQueue will be added to the GC scan range.

Examples

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 }

Meta