1 /**
2 Copyright: Copyright (c) 2016 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 std.experimental.allocator.gc_allocator;
9 alias allocator = GCAllocator.instance;
10 
11 T nextPOT(T)(T x) {
12 	--x;
13 	x |= x >> 1;
14 	x |= x >> 2;
15 	x |= x >> 4;
16 	static if (T.sizeof >= 16) x |= x >>  8;
17 	static if (T.sizeof >= 32) x |= x >> 16;
18 	static if (T.sizeof >= 64) x |= x >> 32;
19 	++x;
20 
21 	return x;
22 }
23 
24 struct Buffer(T)
25 {
26 	T[] buf;
27 	size_t length;
28 
29 	void put(T[] items ...)
30 	{
31 		reserve(items.length);
32 		buf[length..length+items.length] = items;
33 		length += items.length;
34 	}
35 
36 	void put(T[] items)
37 	{
38 		reserve(items.length);
39 		buf[length..length+items.length] = items;
40 		length += items.length;
41 	}
42 
43 	T[] data() {
44 		return buf[0..length];
45 	}
46 
47 	void clear() {
48 		length = 0;
49 	}
50 
51 	void reserve(size_t items)
52 	{
53 		if (buf.length - length < items)
54 		{
55 			size_t newCapacity = nextPOT(buf.length + items);
56 			void[] tmp = buf;
57 			allocator.reallocate(tmp, newCapacity*T.sizeof);
58 			buf = cast(T[])tmp;
59 		}
60 	}
61 }