FilteredListUpdaterOnReflectedVector.h
// FilteredListUpdaterOnReflectedVector.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2021
@import "ReflectedVectorBC.h"
@import "ConstructDestructCopyAssignReflectedVariable.h"
#include "Ceda/cxUtils/CedaAssert.h"
namespace ceda
{
/*
Provides an efficient mechanism to erase some subset of the elements of a reflected vector,
using calls to drop/keep in a single pass over the vector.
During the single pass, elements to be kept are moved and elements to be dropped are
destructed. The vector is only resized at the end.
*/
class FilteredListUpdaterOnReflectedVector
{
public:
FilteredListUpdaterOnReflectedVector(const ReflectedVectorBC& rv, VectorOfByte& vf) :
rv(rv),
vf(vf)
{
keepPos = dropPos = vf.data();
}
~FilteredListUpdaterOnReflectedVector()
{
cxAssert(dropPos == vf.data() + vf.size());
vf.resize(keepPos - vf.data());
}
// Drop the next n elements
void Drop(ssize_t n)
{
cxAssert(n >= 0);
cxAssert(dropPos + n*rv.elementSize <= vf.data() + vf.size());
if (!rv.isPOD)
{
DestructReflectedArrayVariable(rv.rbcElement, n, dropPos);
}
dropPos += n*rv.elementSize;
}
// Keep the next n elements
void Keep(ssize_t n)
{
cxAssert(n >= 0);
cxAssert(dropPos + n*rv.elementSize <= vf.data() + vf.size());
ssize_t numBytes = n*rv.elementSize;
std::memmove(keepPos, dropPos, numBytes);
keepPos += numBytes;
dropPos += numBytes;
}
private:
const ReflectedVectorBC& rv;
VectorOfByte& vf;
octet_t* keepPos;
octet_t* dropPos;
};
class FilteredListUpdaterOnReflectedVector2
{
public:
FilteredListUpdaterOnReflectedVector2(const ReflectedVector& rv, VectorOfByte& vf) :
elementOps(*rv.element.ops),
vf(vf)
{
keepPos = dropPos = vf.data();
}
~FilteredListUpdaterOnReflectedVector2()
{
cxAssert(dropPos == vf.data() + vf.size());
vf.resize(keepPos - vf.data());
}
// Drop the next n elements
void Drop(ssize_t n)
{
cxAssert(n >= 0);
cxAssert(dropPos + n * elementOps.GetSize() <= vf.data() + vf.size());
elementOps.DestructArray(dropPos,n);
dropPos += n * elementOps.GetSize();
}
// Keep the next n elements
void Keep(ssize_t n)
{
cxAssert(n >= 0);
cxAssert(dropPos + n * elementOps.GetSize() <= vf.data() + vf.size());
ssize_t numBytes = n * elementOps.GetSize();
std::memmove(keepPos, dropPos, numBytes);
keepPos += numBytes;
dropPos += numBytes;
}
private:
const TypeOps& elementOps;
VectorOfByte& vf;
octet_t* keepPos;
octet_t* dropPos;
};
} // namespace ceda