mirror of
https://github.com/Alcaro/Flips.git
synced 2026-09-07 01:56:07 -05:00
Update Arlib
This commit is contained in:
@@ -16,6 +16,17 @@ protected:
|
||||
// this->count=other.count;
|
||||
// this->items=other.items;
|
||||
//}
|
||||
|
||||
protected:
|
||||
static const bool trivial_cons = std::is_trivial<T>::value; // constructor is memset(0)
|
||||
#if __GNUC__ >= 5
|
||||
static const bool trivial_copy = std::is_trivially_copyable<T>::value;
|
||||
#else
|
||||
static const bool trivial_copy = trivial_cons; // copy constructor is memcpy
|
||||
#endif
|
||||
//static const bool trivial_comp = std::has_unique_object_representations<T>::value;
|
||||
static const bool trivial_comp = std::is_integral<T>::value;
|
||||
|
||||
public:
|
||||
const T& operator[](size_t n) const { return items[n]; }
|
||||
|
||||
@@ -82,6 +93,28 @@ public:
|
||||
// return *this;
|
||||
//}
|
||||
|
||||
bool operator==(arrayview<T> other)
|
||||
{
|
||||
if (size() != other.size()) return false;
|
||||
if (this->trivial_comp)
|
||||
{
|
||||
return memcmp(ptr(), other.ptr(), sizeof(T)*size())==0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i=0;i<size();i++)
|
||||
{
|
||||
if (!(items[i]==other[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(arrayview<T> other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const T* begin() { return this->items; }
|
||||
const T* end() { return this->items+this->count; }
|
||||
};
|
||||
@@ -148,24 +181,11 @@ template<typename T> class array : public arrayvieww<T> {
|
||||
//T * items;
|
||||
//size_t count;
|
||||
|
||||
//My requirements:
|
||||
//- all fields initialized by the default constructor are initialized to 0
|
||||
//- all copy/move constructors are equivalent to memcpy()
|
||||
//- there is no destructor
|
||||
//I believe that is equivalent to (possibly slightly looser than) std::is_trivial.
|
||||
//If true, constructor calls are replaced with memset. (Destructor is still called; it'll get optimized out anyways.)
|
||||
static const bool trivial_cons = std::is_trivial<T>::value;
|
||||
#if __GNUC__ >= 5
|
||||
static const bool trivial_copy = std::is_trivially_copyable<T>::value;
|
||||
#else
|
||||
static const bool trivial_copy = trivial_cons;
|
||||
#endif
|
||||
|
||||
void clone(const arrayview<T>& other)
|
||||
{
|
||||
this->count = other.size(); // I can't access non-this instances of my base class, so let's just use the public interface.
|
||||
this->items = malloc(sizeof(T)*bitround(this->count));
|
||||
if (trivial_copy)
|
||||
if (this->trivial_copy)
|
||||
{
|
||||
memcpy(this->items, other.ptr(), sizeof(T)*this->count);
|
||||
}
|
||||
@@ -211,7 +231,7 @@ template<typename T> class array : public arrayvieww<T> {
|
||||
if (this->count >= count) return;
|
||||
size_t prevcount = this->count;
|
||||
resize_grow_noinit(count);
|
||||
if (trivial_cons)
|
||||
if (this->trivial_cons)
|
||||
{
|
||||
memset(this->items+prevcount, 0, sizeof(T)*(count-prevcount));
|
||||
}
|
||||
@@ -247,12 +267,12 @@ public:
|
||||
T& operator[](size_t n) { resize_grow(n+1); return this->items[n]; }
|
||||
|
||||
void resize(size_t len) { resize_to(len); }
|
||||
void resize_noinit(size_t len)
|
||||
{
|
||||
if (trivial_cons && len > this->size()) resize_grow_noinit(len);
|
||||
else resize_to(len);
|
||||
}
|
||||
void reserve(size_t len) { resize_grow(len); }
|
||||
void reserve_noinit(size_t len)
|
||||
{
|
||||
if (this->trivial_cons) resize_grow_noinit(len);
|
||||
else resize_grow(len);
|
||||
}
|
||||
|
||||
void append(const T& item) { size_t pos = this->count; resize_grow(pos+1); this->items[pos] = item; }
|
||||
void reset() { resize_shrink(0); }
|
||||
@@ -343,7 +363,7 @@ public:
|
||||
|
||||
resize_grow_noinit(prevcount + othercount);
|
||||
|
||||
if (trivial_copy)
|
||||
if (this->trivial_copy)
|
||||
{
|
||||
memcpy(this->items+prevcount, other.ptr(), sizeof(T)*othercount);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,22 @@ uint32_t crc32_update(arrayview<uint8_t> data, uint32_t crc)
|
||||
const uint8_t* ptr = data.ptr();
|
||||
size_t len = data.size();
|
||||
crc = ~crc;
|
||||
for (size_t i=0;i<len;i++)
|
||||
for (size_t i=0;i<(len&7);i++)
|
||||
{
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i]] ^ (crc>>8);
|
||||
}
|
||||
for (size_t i=len&7;i<len;i+=8)
|
||||
{
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+0]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+1]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+2]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+3]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+4]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+5]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+6]] ^ (crc>>8);
|
||||
crc = crctable[(crc & 0xFF) ^ ptr[i+7]] ^ (crc>>8);
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ public:
|
||||
array<byte> read() const
|
||||
{
|
||||
array<byte> ret;
|
||||
ret.resize_noinit(this->size());
|
||||
ret.reserve_noinit(this->size());
|
||||
size_t actual = this->read(ret, 0);
|
||||
ret.resize_noinit(actual);
|
||||
ret.resize(actual);
|
||||
return ret;
|
||||
}
|
||||
static array<byte> read(cstring path)
|
||||
@@ -154,7 +154,7 @@ private:
|
||||
{
|
||||
if (!datawr) return false;
|
||||
size_t nbyte = newdata.size();
|
||||
datawr->reserve(start+nbyte);
|
||||
datawr->reserve_noinit(start+nbyte);
|
||||
memcpy(datawr->slice(start, nbyte).ptr(), newdata.ptr(), nbyte);
|
||||
datard=*datawr;
|
||||
return true;
|
||||
|
||||
@@ -11,38 +11,38 @@ template<typename T> class safeint {
|
||||
T data;
|
||||
|
||||
#define HANDLE_BASE(stype, utype) \
|
||||
static inline bool addov(utype a, utype b, utype* c) \
|
||||
static inline bool addov_i(utype a, utype b, utype* c) \
|
||||
{ \
|
||||
*c = a+b; /* rely on unsigned overflow wrapping */ \
|
||||
return *c < a; \
|
||||
} \
|
||||
static inline bool subov(utype a, utype b, utype* c) \
|
||||
static inline bool subov_i(utype a, utype b, utype* c) \
|
||||
{ \
|
||||
*c = a-b; \
|
||||
return (b > a); \
|
||||
} \
|
||||
static inline bool mulov(utype a, utype b, utype* c) \
|
||||
static inline bool mulov_i(utype a, utype b, utype* c) \
|
||||
{ \
|
||||
*c = a*b; \
|
||||
return a!=0 && *c/a!=b; \
|
||||
} \
|
||||
static inline bool lslov(utype a, utype b, utype* c) \
|
||||
static inline bool lslov_i(utype a, utype b, utype* c) \
|
||||
{ \
|
||||
if (b >= sizeof(utype)*8) return true; \
|
||||
*c = a<<b; \
|
||||
return (*c>>b != a); \
|
||||
} \
|
||||
static inline bool addov(stype a, stype b, stype* c) \
|
||||
static inline bool addov_i(stype a, stype b, stype* c) \
|
||||
{ \
|
||||
*c = (utype)a+(utype)b; \
|
||||
return (a>0 && b>0 && *c<0) || (a<0 && b<0 && *c>0); \
|
||||
} \
|
||||
static inline bool subov(stype a, stype b, stype* c) \
|
||||
static inline bool subov_i(stype a, stype b, stype* c) \
|
||||
{ \
|
||||
*c = (utype)a-(utype)b; \
|
||||
return (a>0 && b<0 && *c<0) || (a<0 && b>0 && *c>0); \
|
||||
} \
|
||||
static inline bool mulov(stype a, stype b, stype* c) \
|
||||
static inline bool mulov_i(stype a, stype b, stype* c) \
|
||||
{ \
|
||||
stype min = ((stype)-1)<<(sizeof(stype)*8-1); \
|
||||
stype max = -(min+1); \
|
||||
@@ -54,7 +54,7 @@ template<typename T> class safeint {
|
||||
*c = a*b; \
|
||||
return false; \
|
||||
} \
|
||||
static inline bool lslov(stype a, stype b, stype* c) \
|
||||
static inline bool lslov_i(stype a, stype b, stype* c) \
|
||||
{ \
|
||||
if (b<0 || b >= sizeof(stype)*8) return true; \
|
||||
*c = (a << b); \
|
||||
@@ -73,22 +73,22 @@ template<typename T> class safeint {
|
||||
*c = (ext)a op (ext)b; \
|
||||
return false; \
|
||||
}
|
||||
HANDLE_EXT(addov, +, signed short, signed int)
|
||||
HANDLE_EXT(addov, +, signed char, signed int)
|
||||
HANDLE_EXT(addov, +, unsigned short, unsigned int)
|
||||
HANDLE_EXT(addov, +, unsigned char, unsigned int)
|
||||
HANDLE_EXT(subov, -, signed short, signed int)
|
||||
HANDLE_EXT(subov, -, signed char, signed int)
|
||||
HANDLE_EXT(subov, -, unsigned short, unsigned int)
|
||||
HANDLE_EXT(subov, -, unsigned char, unsigned int)
|
||||
HANDLE_EXT(mulov, *, signed short, signed int)
|
||||
HANDLE_EXT(mulov, *, signed char, signed int)
|
||||
HANDLE_EXT(mulov, *, unsigned short, unsigned int)
|
||||
HANDLE_EXT(mulov, *, unsigned char, unsigned int)
|
||||
HANDLE_EXT(lslov,<<, signed short, signed int)
|
||||
HANDLE_EXT(lslov,<<, signed char, signed int)
|
||||
HANDLE_EXT(lslov,<<, unsigned short, unsigned int)
|
||||
HANDLE_EXT(lslov,<<, unsigned char, unsigned int)
|
||||
HANDLE_EXT(addov_i, +, signed short, signed int)
|
||||
HANDLE_EXT(addov_i, +, signed char, signed int)
|
||||
HANDLE_EXT(addov_i, +, unsigned short, unsigned int)
|
||||
HANDLE_EXT(addov_i, +, unsigned char, unsigned int)
|
||||
HANDLE_EXT(subov_i, -, signed short, signed int)
|
||||
HANDLE_EXT(subov_i, -, signed char, signed int)
|
||||
HANDLE_EXT(subov_i, -, unsigned short, unsigned int)
|
||||
HANDLE_EXT(subov_i, -, unsigned char, unsigned int)
|
||||
HANDLE_EXT(mulov_i, *, signed short, signed int)
|
||||
HANDLE_EXT(mulov_i, *, signed char, signed int)
|
||||
HANDLE_EXT(mulov_i, *, unsigned short, unsigned int)
|
||||
HANDLE_EXT(mulov_i, *, unsigned char, unsigned int)
|
||||
HANDLE_EXT(lslov_i,<<, signed short, signed int)
|
||||
HANDLE_EXT(lslov_i,<<, signed char, signed int)
|
||||
HANDLE_EXT(lslov_i,<<, unsigned short, unsigned int)
|
||||
HANDLE_EXT(lslov_i,<<, unsigned char, unsigned int)
|
||||
#undef HANDLE_EXT
|
||||
#else
|
||||
//allow forcing the non-casting algorithm, so an exhaustive search can be done over the full range of some types
|
||||
@@ -99,9 +99,9 @@ HANDLE_EXT(lslov,<<, unsigned char, unsigned int)
|
||||
#undef HANDLE_BASE
|
||||
|
||||
#if __GNUC__>=5
|
||||
#define addov __builtin_add_overflow
|
||||
#define subov __builtin_sub_overflow
|
||||
#define mulov __builtin_mul_overflow
|
||||
#define addov_i __builtin_add_overflow
|
||||
#define subov_i __builtin_sub_overflow
|
||||
#define mulov_i __builtin_mul_overflow
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -131,21 +131,21 @@ ALLOPER(OP)
|
||||
{
|
||||
if (!valid() || !b.valid()) return invalid;
|
||||
T ret;
|
||||
if (addov(val(), b.val(), &ret)) return invalid;
|
||||
if (addov_i(val(), b.val(), &ret)) return invalid;
|
||||
else return ret;
|
||||
}
|
||||
safeint<T> operator-(safeint<T> b)
|
||||
{
|
||||
if (!valid() || !b.valid()) return invalid;
|
||||
T ret;
|
||||
if (subov(val(), b.val(), &ret)) return invalid;
|
||||
if (subov_i(val(), b.val(), &ret)) return invalid;
|
||||
else return ret;
|
||||
}
|
||||
safeint<T> operator*(safeint<T> b)
|
||||
{
|
||||
if (!valid() || !b.valid()) return invalid;
|
||||
T ret;
|
||||
if (mulov(val(), b.val(), &ret)) return invalid;
|
||||
if (mulov_i(val(), b.val(), &ret)) return invalid;
|
||||
else return ret;
|
||||
}
|
||||
safeint<T> operator/(safeint<T> b)
|
||||
@@ -182,7 +182,7 @@ ALLOPER(OP)
|
||||
{
|
||||
if (!valid() || !b.valid()) return invalid;
|
||||
T ret;
|
||||
if (lslov(val(), b.val(), &ret)) return invalid;
|
||||
if (lslov_i(val(), b.val(), &ret)) return invalid;
|
||||
else return ret;
|
||||
}
|
||||
safeint<T> operator>>(safeint<T> b)
|
||||
@@ -222,6 +222,14 @@ ALLOPER(OP)
|
||||
if (!valid() || !b.valid()) return false;
|
||||
return val()>=b.val();
|
||||
}
|
||||
|
||||
static bool addov(T a, T b, T* c) { return addov_i(a, b, c); }
|
||||
static bool subov(T a, T b, T* c) { return subov_i(a, b, c); }
|
||||
static bool mulov(T a, T b, T* c) { return mulov_i(a, b, c); }
|
||||
static bool lslov(T a, T b, T* c) { return lslov_i(a, b, c); }
|
||||
#undef addov_i
|
||||
#undef subov_i
|
||||
#undef mulov_i
|
||||
};
|
||||
|
||||
#define OP(op, ope) \
|
||||
|
||||
Reference in New Issue
Block a user