1 /** 2 Copyright: Copyright (c) 2016-2017 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 private 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(R)(R itemRange) 37 { 38 foreach(item; itemRange) 39 put(item); 40 } 41 42 void stealthPut(T item) 43 { 44 reserve(1); 45 buf[length] = item; 46 } 47 48 T[] data() { 49 return buf[0..length]; 50 } 51 52 void clear() nothrow { 53 length = 0; 54 } 55 56 size_t capacity() @property { 57 return buf.length - length; 58 } 59 60 void reserve(size_t items) 61 { 62 if (buf.length - length < items) 63 { 64 size_t newCapacity = nextPOT(buf.length + items); 65 void[] tmp = buf; 66 allocator.reallocate(tmp, newCapacity*T.sizeof); 67 buf = cast(T[])tmp; 68 } 69 } 70 }