1 /* Supporting different types and containers.
2  * Copyright (C) 2017  Marko Semet
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 module structuresd.containers.queue;
18 
19 /**
20  * A queue
21  */
22 public class Queue(TYPE, bool THREAD_SAFE = false)
23 {
24 	private static struct Entry
25 	{
26 		public Entry* next;
27 		TYPE data;
28 		bool used;
29 	}
30 
31 	private Entry* front;
32 	private Entry* back;
33 
34 	public this()
35 	{
36 		this.front = new Entry;
37 		this.front.used = true;
38 		this.front.next = null;
39 		this.back = this.front;
40 	}
41 
42 	private void _insert(TYPE data)
43 	{
44 		Entry* tmp = new Entry;
45 		tmp.data = data;
46 		tmp.used = false;
47 		tmp.next = null;
48 		this.back.next = tmp;
49 		this.back = tmp;
50 	}
51 	public void insert(TYPES...)(TYPES types)
52 	{
53 		static if(THREAD_SAFE)
54 		{
55 			synchronized(this)
56 			{
57 				static foreach(i; types)
58 				{
59 					this._insert(i);
60 				}
61 			}
62 		}
63 		else
64 		{
65 			static foreach(TYPE i; types)
66 			{
67 				this._insert(i);
68 			}
69 		}
70 	}
71 
72 	public bool _fetch(ref TYPE data)
73 	{
74 		while(true)
75 		{
76 			if(!this.front.used)
77 			{
78 				this.front.used = true;
79 				data = this.front.data;
80 				return true;
81 			}
82 			else if(this.front.next !is null)
83 			{
84 				this.front = this.front.next;
85 			}
86 			else
87 			{
88 				return false;
89 			}
90 		}
91 	}
92 	public bool fetch(ref TYPE data)
93 	{
94 		static if(THREAD_SAFE)
95 		{
96 			synchronized(this)
97 			{
98 				return this._fetch(data);
99 			}
100 		}
101 		else
102 		{
103 			return this._fetch(data);
104 		}
105 	}
106 }