#ifndef zero_elimination_host
#define zero_elimination_host
template <typename T, bool check = false>
static inline bool h_ZEencode(const T* const in, const int insize, T* const dataout, int& datasize, T* const bmout) {
const int bits = sizeof(T) * 8; const int num = (insize + bits - 1) / bits; int pos = 0;
int cnt = 0;
for (int i = 0; i < num - 1; i++) {
T bm = 0;
for (int j = 0; j < bits; j++) {
const T val = in[cnt++];
if (val != 0) {
if constexpr (check) {
if (pos >= datasize) return false;
}
bm |= (T)1 << j;
dataout[pos++] = val;
}
}
bmout[i] = bm;
}
const int i = num - 1;
{
T bm = 0;
for (int j = 0; j < bits; j++) {
if (cnt >= insize) break;
const T val = in[cnt++];
if (val != 0) {
if constexpr (check) {
if (pos >= datasize) return false;
}
bm |= (T)1 << j;
dataout[pos++] = val;
}
}
bmout[i] = bm;
}
datasize = pos;
return true;
}
template <typename T>
static inline void h_ZEdecode(const int decsize, const T* const datain, const T* const bmin, T* const out) {
const int bits = sizeof(T) * 8; const int num = (decsize + bits - 1) / bits; int pos = 0;
int cnt = 0;
for (int i = 0; i < num - 1; i++) {
const T bm = bmin[i];
for (int j = 0; j < bits; j++) {
T val = 0;
if (((bm >> j) & 1) != 0) {
val = datain[pos++];
}
out[cnt++] = val;
}
}
const int i = num - 1;
{
const T bm = bmin[i];
for (int j = 0; j < bits; j++) {
T val = 0;
if (((bm >> j) & 1) != 0) {
val = datain[pos++];
}
out[cnt++] = val;
if (cnt >= decsize) break;
}
}
}
#endif