1 module gfm.core.alignedbuffer; 2 3 import std.c.string; 4 import gfm.core.memory; 5 6 /// Growable array, points to a memory aligned location. 7 /// Bugs: make this class disappear when std.allocator is out. 8 final class AlignedBuffer(T) 9 { 10 public 11 { 12 /// Creates an empty aligned buffer. 13 this() nothrow 14 { 15 _size = 0; 16 _allocated = 0; 17 _data = null; 18 _alignment = 64; 19 } 20 21 /// Creates an aligned buffer with given size. 22 this(size_t initialSize) nothrow 23 { 24 this(); 25 resize(initialSize); 26 } 27 28 /// Creates an aligned buffer by copy. 29 this(AlignedBuffer other) 30 { 31 this(); 32 resize(other.length()); 33 memcpy(_data, other._data, _size * T.sizeof); 34 } 35 36 ~this() 37 { 38 close(); 39 } 40 41 void close() 42 { 43 if (_data !is null) 44 { 45 alignedFree(_data); 46 _data = null; 47 _allocated = 0; 48 } 49 } 50 51 size_t length() pure const nothrow 52 { 53 return _size; 54 } 55 56 void resize(size_t askedSize) nothrow 57 { 58 // grow only 59 if (_allocated < askedSize) 60 { 61 size_t numBytes = askedSize * T.sizeof; 62 _data = cast(T*)(alignedRealloc(_data, numBytes, _alignment)); 63 _allocated = askedSize; 64 } 65 _size = askedSize; 66 } 67 68 void pushBack(T x) nothrow 69 { 70 size_t i = _size; 71 resize(_size + 1); 72 _data[i] = x; 73 } 74 75 // push back another buffer 76 void pushBack(AlignedBuffer other) nothrow 77 { 78 size_t oldSize = _size; 79 resize(_size + other._size); 80 memcpy(_data + oldSize, other._data, T.sizeof * other._size); 81 } 82 83 @property T* ptr() nothrow 84 { 85 return _data; 86 } 87 88 T opIndex(size_t i) pure nothrow 89 { 90 return _data[i]; 91 } 92 93 T opIndexAssign(T x, size_t i) nothrow 94 { 95 return _data[i] = x; 96 } 97 98 void clear() nothrow 99 { 100 _size = 0; 101 } 102 103 void fill(T x) 104 { 105 for (size_t i = 0; i < _size; ++i) 106 { 107 _data[i] = x; 108 } 109 } 110 } 111 112 private 113 { 114 size_t _size; 115 T* _data; 116 size_t _allocated; 117 size_t _alignment; 118 } 119 } 120 121 unittest 122 { 123 auto buf = new AlignedBuffer!int; 124 enum N = 10; 125 buf.resize(N); 126 foreach(i ; 0..N) 127 buf[i] = i; 128 129 foreach(i ; 0..N) 130 assert(buf[i] == i); 131 }