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 }