Make FixedRingBuffer compatible with non-copyable structs.

This commit is contained in:
Sönke Ludwig 2019-01-14 22:15:38 +01:00
parent 82936041e4
commit dee54e505a

View file

@ -361,7 +361,7 @@ struct FixedRingBuffer(T, size_t N = 0, bool INITIALIZE = true) {
m_start = 0; m_start = 0;
} }
void put()(T itm) { assert(m_fill < m_buffer.length); m_buffer[mod(m_start + m_fill++)] = itm; } void put()(T itm) { assert(m_fill < m_buffer.length); move(itm, m_buffer[mod(m_start + m_fill++)]); }
void put(TC : T)(scope TC[] itms) void put(TC : T)(scope TC[] itms)
{ {
if( !itms.length ) return; if( !itms.length ) return;
@ -391,18 +391,18 @@ struct FixedRingBuffer(T, size_t N = 0, bool INITIALIZE = true) {
assert(r.m_start >= m_start && r.m_start < m_buffer.length || r.m_start < mod(m_start+m_fill)); assert(r.m_start >= m_start && r.m_start < m_buffer.length || r.m_start < mod(m_start+m_fill));
if( r.m_start > m_start ){ if( r.m_start > m_start ){
foreach(i; r.m_start .. m_buffer.length-1) foreach(i; r.m_start .. m_buffer.length-1)
m_buffer[i] = m_buffer[i+1]; move(m_buffer[i+1], m_buffer[i]);
m_buffer[$-1] = m_buffer[0]; move(m_buffer[0], m_buffer[$-1]);
foreach(i; 0 .. mod(m_start + m_fill - 1)) foreach(i; 0 .. mod(m_start + m_fill - 1))
m_buffer[i] = m_buffer[i+1]; move(m_buffer[i+1], m_buffer[i]);
} else { } else {
foreach(i; r.m_start .. mod(m_start + m_fill - 1)) foreach(i; r.m_start .. mod(m_start + m_fill - 1))
m_buffer[i] = m_buffer[i+1]; move(m_buffer[i+1], m_buffer[i]);
} }
} else { } else {
assert(r.m_start >= m_start && r.m_start < m_start+m_fill); assert(r.m_start >= m_start && r.m_start < m_start+m_fill);
foreach(i; r.m_start .. m_start+m_fill-1) foreach(i; r.m_start .. m_start+m_fill-1)
m_buffer[i] = m_buffer[i+1]; move(m_buffer[i+1], m_buffer[i]);
} }
m_fill--; m_fill--;
destroy(m_buffer[mod(m_start+m_fill)]); // TODO: only call destroy for non-POD T destroy(m_buffer[mod(m_start+m_fill)]); // TODO: only call destroy for non-POD T
@ -422,10 +422,20 @@ struct FixedRingBuffer(T, size_t N = 0, bool INITIALIZE = true) {
if( mod(m_start) >= mod(m_start+dst.length) ){ if( mod(m_start) >= mod(m_start+dst.length) ){
size_t chunk1 = m_buffer.length - m_start; size_t chunk1 = m_buffer.length - m_start;
size_t chunk2 = dst.length - chunk1; size_t chunk2 = dst.length - chunk1;
dst[0 .. chunk1] = m_buffer[m_start .. $]; static if (isCopyable!T) {
dst[chunk1 .. $] = m_buffer[0 .. chunk2]; dst[0 .. chunk1] = m_buffer[m_start .. $];
dst[chunk1 .. $] = m_buffer[0 .. chunk2];
} else {
foreach (i; 0 .. chunk1) move(m_buffer[m_start+i], dst[i]);
foreach (i; chunk1 .. this.length) move(m_buffer[i-chunk1], dst[i]);
}
} else { } else {
dst[] = m_buffer[m_start .. m_start+dst.length]; static if (isCopyable!T) {
dst[] = m_buffer[m_start .. m_start+dst.length];
} else {
foreach (i; 0 .. dst.length)
move(m_buffer[m_start + i], dst[i]);
}
} }
popFrontN(dst.length); popFrontN(dst.length);
} }
@ -507,7 +517,7 @@ struct FixedRingBuffer(T, size_t N = 0, bool INITIALIZE = true) {
@property bool empty() const { return m_length == 0; } @property bool empty() const { return m_length == 0; }
@property inout(T) front() inout { assert(!empty); return m_buffer[m_start]; } @property ref inout(T) front() inout { assert(!empty); return m_buffer[m_start]; }
void popFront() void popFront()
{ {