1 /**
2 Copyright: Copyright (c) 2016-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.container.buffer;
7 
8 import voxelman.math : nextPOT;
9 
10 struct Buffer(T)
11 {
12 	T[] buf;
13 	// Must be kept private since it can be used to check for avaliable space
14 	// when used as output range
15 	private size_t length;
16 
17 	bool empty() { return length == 0; }
18 
19 	void put(T[] items ...)
20 	{
21 		reserve(items.length);
22 		buf[length..length+items.length] = items;
23 		length += items.length;
24 	}
25 
26 	void put(R)(R itemRange)
27 	{
28 		foreach(item; itemRange)
29 			put(item);
30 	}
31 
32 	void stealthPut(T item)
33 	{
34 		reserve(1);
35 		buf[length] = item;
36 	}
37 
38 	/// Increases length and returns void-initialized slice to be filled by user
39 	T[] voidPut(size_t howMany)
40 	{
41 		reserve(howMany);
42 		length += howMany;
43 		return buf[length-howMany..length];
44 	}
45 
46 	ref T opIndex(size_t at)
47 	{
48 		return buf[at];
49 	}
50 
51 	ref T back() { return buf[length-1]; }
52 
53 	inout(T[]) data() inout {
54 		return buf[0..length];
55 	}
56 
57 	void clear() nothrow {
58 		length = 0;
59 	}
60 
61 	size_t capacity() const @property {
62 		return buf.length;
63 	}
64 
65 	void reserve(size_t items)
66 	{
67 		if (buf.length - length < items)
68 		{
69 			size_t newCapacity = nextPOT(buf.length + items);
70 			buf.length = newCapacity;
71 		}
72 	}
73 
74 	void unput(size_t numItems)
75 	{
76 		length -= numItems;
77 	}
78 }