1 /**
2 An implemention of a Queue.
3 
4 This Queue is thread safe (and block-free) to have separate threads reading and writing asynchronously.  The Queue is NOT safe to have multiple threads reading or writing at the same time.  i.e. A single thread can read while another single thread is writing.
5 If you want to have mutiple threads reading or writing data from queue the threads will need to be sure to block themself.
6 
7 To Create a queue
8 ---
9 Queue!string queue; // Replace string with data type that values should be.
10 ---
11 
12 To add to queue
13 ---
14 queue.put("This is a value that is added to queue!"); // Argument should be of oppropriate type.
15 ---
16 
17 To read data
18 ---
19 foreach (string value; queue) {
20 // Deal with value here!
21 }
22 ---
23 
24 To read data safe to have multiple threads reading
25 ---
26 synchronized {
27 foreach (string value; queue) {
28 // Deal with value here!
29 }
30 }
31 ---
32 or
33 ---
34 while (true) {
35 string value;
36 synchronized {
37 if (queue.empty) {
38 break;
39 }
40 value = queue.front;
41 queue.popFront;
42 }
43 // Deal with value here!
44 }
45 ---
46 
47 Examples:
48 ---
49 Queue!string queue; 
50 
51 queue.add("A!");
52 queue.add("BBB!");
53 queue.add("CC!");
54 
55 foreach (string value; queue) {
56 writeln(value);
57 }
58 
59 queue.add("DDDDD!");
60 queue.add("EEEE!");
61 
62 foreach (string value; queue) {
63 writeln(value);
64 }
65 ---
66 */
67 
68 module queue;
69 
70 import core.atomic : atomicOp;
71 ////import core.sync.semaphore : Semaphore;
72 
73 class Queue(T) {
74 
75 	//private struct HeadNode {
76 	//    Node* _first;
77 	//}
78 	private struct Node {
79 		T     payload;
80 		Node* next;
81 	}
82 
83 	private Node* _first;
84 	private Node* _last = new Node;
85 	shared private int   count = 0;
86 
87 	this() {
88 		this._first = this._last;
89 	}
90 
91 	/**	Add to the Queue (to the end).
92 	*/
93 	void put(T value) {
94 		Node* newLast = new Node;
95 		this._last.payload = value;
96 		this._last.next = newLast;
97 		this._last = newLast;
98 		
99 		count.atomicOp!("+=")(1);
100 	}
101 
102 
103 	/**	To be iterable with `foreach` loop.
104 	*/
105 	bool empty() {
106 		return this.count == 0;
107 		////return _head._first == null;
108 	}
109 
110 	/// ditto
111 	void popFront() {
112 		assert (!this.empty);
113 		this._first = this._first.next;
114 		count.atomicOp!("-=")(1);
115 	}
116 
117 	///ditto
118 	T front() {
119 		assert (!this.empty);
120 		return this._first.payload;
121 		////}
122 		////else {
123 		////    return null;
124 		////}
125 	}
126 
127 }
128 
129 
130 
131 ////void main(){
132 ////    import core.thread;
133 ////    import std.stdio;
134 ////    class ThreadInput : Thread {
135 ////        private Queue!string queue;
136 ////
137 ////        this(Queue!string queue) {
138 ////            super(&run);
139 ////            this.queue = queue;
140 ////        }
141 ////
142 ////        private void run() {
143 ////            while (true) {
144 ////                queue.put(readln);
145 ////            }
146 ////        }
147 ////    }
148 ////    Queue!string inputQueue = new Queue!string;
149 ////    ThreadInput threadInput = new ThreadInput(inputQueue);
150 ////    threadInput.start;
151 ////
152 ////    while (true) {
153 ////        foreach (string value; inputQueue) {
154 ////            writeln(value);
155 ////        }
156 ////    }
157 ////    
158 ////
159 ////
160 ////}