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 }