Commit dddffacd authored by KLOCZKO Thibaud's avatar KLOCZKO Thibaud
Browse files

Finalize ZUC.

parent 71264481
......@@ -60,6 +60,8 @@ set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "${CMAKE_INSTA
qt5_use_modules(${PROJECT_NAME} Core)
target_link_libraries(${PROJECT_NAME} dtkMeta)
## ###################################################################
## Install rules - files
## ###################################################################
......
......@@ -121,6 +121,7 @@ template <typename T, qlonglong PreallocSize = 8> class dtkArray : private dtkAr
{
typedef dtkTypedArrayData<T> Data;
Data *d;
bool isRawData;
public:
typedef typename Data::iterator iterator;
......@@ -135,12 +136,6 @@ public:
typedef qptrdiff difference_type;
typedef qlonglong size_type;
public:
enum RawDataType {
ReadOnly = 0x001,
Writable = 0x002
};
public:
dtkArray(void);
explicit dtkArray(qlonglong size);
......@@ -148,7 +143,7 @@ public:
dtkArray(const T *values, qlonglong size);
dtkArray(const dtkArray& other);
#ifdef Q_COMPILER_RVALUE_REFS
//dtkArray(dtkArray&& other);
dtkArray(dtkArray&& other);
#endif
public:
......@@ -157,7 +152,7 @@ public:
public:
dtkArray& operator = (const dtkArray& other);
#ifdef Q_COMPILER_RVALUE_REFS
//dtkArray operator = (dtkArray&& other);
dtkArray& operator = (dtkArray&& other);
#endif
bool operator == (const dtkArray& other) const;
......@@ -227,6 +222,13 @@ public:
dtkArray& fill(const T &t, qlonglong size = -1);
void setRawData(const T *raw_data, qlonglong size);
void setWritableRawData(T *raw_data, qlonglong size);
public:
static dtkArray fromRawData(const T *data, qlonglong size);
static dtkArray fromWritableRawData(T *data, qlonglong size);
public:
iterator erase(iterator begin, iterator end);
iterator erase(iterator pos);
......@@ -279,9 +281,9 @@ public:
qlonglong lastIndexOf(const T &t, qlonglong from = -1) const;
qlonglong count(const T &t) const;
dtkArray<T, PreallocSize> mid(qlonglong pos, qlonglong length = -1) const;
dtkArray<T, PreallocSize> left(qlonglong length) const;
dtkArray<T, PreallocSize> right(qlonglong length) const;
dtkArray mid(qlonglong pos, qlonglong length = -1) const;
dtkArray left(qlonglong length) const;
dtkArray right(qlonglong length) const;
public:
void push_back(const T &t) { append(t); }
......@@ -312,6 +314,8 @@ public:
private:
template <typename, qlonglong> friend class dtkArray;
void copyData(Data *other_d);
void reallocData(const qlonglong size, const qlonglong alloc, dtkArrayData::AllocationOptions options = dtkArrayData::Default);
void reallocData(const qlonglong size);
void freeData(Data *d);
......
......@@ -15,11 +15,37 @@
#pragma once
#include <QtCore>
#include <dtkMeta/dtkMeta>
// ///////////////////////////////////////////////////////////////////
// Private practices
// ///////////////////////////////////////////////////////////////////
template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSize>::copyData(Data *other_d)
{
if (other_d->ref.ref()) {
d = other_d;
} else {
if (other_d->capacityReserved) {
if (other_d->alloc > PreallocSize) {
d = Data::allocate(other_d->alloc);
d->capacityReserved = true;
} else {
d = Data::fromRawData(this->preallocData(), other_d->size, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
}
} else {
d = Data::allocate(other_d->size);
}
if (d->alloc) {
copyConstruct(other_d->begin(), other_d->end(), d->begin());
d->size = other_d->size;
}
}
}
template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSize>::reallocData(const qlonglong asize, const qlonglong aalloc, dtkArrayData::AllocationOptions options)
{
Q_ASSERT(asize >= 0 && asize <= aalloc);
......@@ -127,7 +153,8 @@ template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSi
template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSize>::freeData(Data *x)
{
destruct(x->begin(), x->end());
if(!isRawData)
destruct(x->begin(), x->end());
Data::deallocate(x);
}
......@@ -170,15 +197,20 @@ template <typename T, qlonglong PreallocSize> inline bool dtkArray<T, PreallocSi
// Public API
// ///////////////////////////////////////////////////////////////////
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(void)
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(void) : isRawData(false)
{
Q_STATIC_ASSERT_X(PreallocSize >= 0, "dtkArray PreallocSize must be greater than 0.");
d = Data::fromRawData(this->preallocData(), 0, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
if (PreallocSize) {
d = Data::fromRawData(this->preallocData(), 0, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
} else {
d = Data::fromRawData(this->preallocData(), 0);
}
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(qlonglong size)
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(qlonglong size) : isRawData(false)
{
Q_STATIC_ASSERT_X(PreallocSize >= 0, "dtkArray PreallocSize must be greater or equal than 0.");
Q_ASSERT_X(size >= 0, "dtkArray::dtkArray", "Size must be greater than or equal to 0.");
......@@ -193,7 +225,7 @@ template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::
defaultConstruct(d->begin(), d->end());
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(qlonglong size, const T& value)
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(qlonglong size, const T& value) : isRawData(false)
{
Q_STATIC_ASSERT_X(PreallocSize >= 0, "dtkArray PreallocSize must be greater than 0.");
Q_ASSERT_X(size >= 0, "dtkArray::dtkArray", "Size must be greater than or equal to 0.");
......@@ -210,7 +242,7 @@ template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::
new (--i) T(value);
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(const T *values, qlonglong size)
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(const T *values, qlonglong size) : isRawData(false)
{
Q_STATIC_ASSERT_X(PreallocSize > 0, "dtkArray PreallocSize must be greater than 0.");
Q_ASSERT_X(size >= 0, "dtkArray::dtkArray", "Size must be greater than or equal to 0.");
......@@ -228,40 +260,18 @@ template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::
new (--i) T(*(--value));
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(const dtkArray& other)
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(const dtkArray& other) : isRawData(false)
{
if (other.d->ref.ref()) {
d = other.d;
} else {
if (other.d->capacityReserved) {
if (other.d->alloc > PreallocSize) {
d = Data::allocate(other.d->alloc);
d->capacityReserved = true;
} else {
d = Data::fromRawData(this->preallocData(), other.d->size, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
}
} else {
d = Data::allocate(other.d->size);
}
if (d->alloc) {
copyConstruct(other.d->begin(), other.d->end(), d->begin());
d->size = other.d->size;
}
}
this->copyData(other.d);
}
// #ifdef Q_COMPILER_RVALUE_REFS
// template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(dtkArray&& other) : d(other.d)
// {
// if(other.usePreallocation()) {
// copyConstruct(other.d->begin(), other.d->end(), preallocData());
// }
// other.clear();
// }
// #endif
#ifdef Q_COMPILER_RVALUE_REFS
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::dtkArray(dtkArray&& other) : isRawData(false)
{
this->copyData(other.d);
other.d = Data::sharedNull();
}
#endif
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>::~dtkArray(void)
{
......@@ -276,23 +286,19 @@ template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>&
if (!d->ref.deref())
freeData(d);
if (other.d->ref.ref()) {
d = other.d;
} else {
d = Data::fromRawData(this->preallocData(), other.d->size, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
if (d->alloc) {
copyConstruct(other.d->begin(), other.d->end(), d->begin());
d->size = other.d->size;
}
}
this->copyData(other.d);
}
return *this;
}
#ifdef Q_COMPILER_RVALUE_REFS
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>& dtkArray<T, PreallocSize>::operator = (dtkArray&& other)
{
this->swap(other);
return *this;
}
#endif
template <typename T, qlonglong PreallocSize> inline bool dtkArray<T, PreallocSize>::operator == (const dtkArray<T, PreallocSize>& other) const
{
if (d->size != other.d->size)
......@@ -315,34 +321,17 @@ template <typename T, qlonglong PreallocSize> inline bool dtkArray<T, PreallocSi
template <typename T, qlonglong PreallocSize> template <qlonglong PreallocSizeOther> inline dtkArray<T, PreallocSize>::dtkArray(const dtkArray<T, PreallocSizeOther>& other)
{
if (other.d->ref.ref()) {
d = other.d;
} else {
if (other.d->capacityReserved) {
if (other.d->alloc > PreallocSize) {
d = Data::allocate(other.d->alloc);
d->capacityReserved = true;
} else {
d = Data::fromRawData(this->preallocData(), other.d->size, dtkArrayData::Unsharable);
d->capacityReserved = bool(PreallocSize);
d->alloc = PreallocSize;
}
} else {
d = Data::allocate(other.d->size);
}
if (d->alloc) {
copyConstruct(other.d->begin(), other.d->end(), d->begin());
d->size = other.d->size;
}
}
this->copyData(other.d);
}
template <typename T, qlonglong PreallocSize> template <qlonglong PreallocSizeOther> inline dtkArray<T, PreallocSize>& dtkArray<T, PreallocSize>::operator = (const dtkArray<T, PreallocSizeOther>& other)
{
if (other.d != d) {
dtkArray<T, PreallocSize> tmp(other);
tmp.swap(*this);
if (!d->ref.deref())
freeData(d);
this->copyData(other.d);
}
return *this;
}
......@@ -378,45 +367,9 @@ template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSi
qSwap(d, other.d);
} else {
qSwap(d, other.d);
copyConstruct(other.preallocData(), other.preallocData() + d->size, d->begin());
// if(!usePreallocation()) {
// Data *tmp = Data::fromRawData(dtkArrayPrealloc<T, PreallocSize>::preallocData(), other.size());
// tmp->capacityReserved = bool(PreallocSize);
// tmp->alloc = PreallocSize;
// qSwap(tmp, d);
// copyConstruct(other.d->begin(), other.d->end(), d->begin());
// qSwap(tmp, other.d);
// if (!tmp->ref.deref()) {
// if (QTypeInfo<T>::isStatic || !aalloc || (isShared && QTypeInfo<T>::isComplex)) {
// // data was copy constructed, we need to call destructors
// // or if !alloc we did nothing to the old 'd'.
// freeData(tmp);
// } else {
// Data::deallocate(tmp);
// }
// }
// } else if (!other.usePreallocation()) {
// Data *tmp = Data::fromRawData(other.preallocData(), size());
// tmp->capacityReserved = bool(PreallocSize);
// tmp->alloc = PreallocSize;
// qSwap(tmp, other.d);
// copyConstruct(d->begin(), d->end(), other.d->begin());
// qSwap(tmp, d);
// Data::deallocate(tmp);
// } else {
// T *tmp = new [d->size];
// copyConstruct(d->begin(), d->end(), tmp);
// copyConstruct(other.d->begin(), other.d->end(), d->begin());
// copyConstruct(tmp, tmp + d->size, other.d->begin());
// qSwap(d->ref, other.d->ref);
// qSwap(d->size, other.d->size);
// delete
// }
dtkArray<T, PreallocSize> tmp(other);
other = *this;
*this = tmp;
}
}
......@@ -806,6 +759,58 @@ template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize>&
return *this;
}
template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSize>::setRawData(const T *raw_data, qlonglong size)
{
if (!d->ref.deref())
freeData(d);
if (!raw_data || ! size) {
d = Data::fromRawData(this->preallocData(), 0);
} else {
d = Data::fromRawData(raw_data, size);
d->ref.atomic.store(2);
d->alloc = size;
isRawData = true;
}
}
template <typename T, qlonglong PreallocSize> inline void dtkArray<T, PreallocSize>::setWritableRawData(T *raw_data, qlonglong size)
{
if (!d->ref.deref())
freeData(d);
if (!raw_data || ! size) {
d = Data::fromRawData(this->preallocData(), 0);
} else {
d = Data::fromRawData(raw_data, size);
d->alloc = size;
isRawData = true;
}
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize> dtkArray<T, PreallocSize>::fromRawData(const T *raw_data, qlonglong size)
{
dtkArray result;
result.d = Data::fromRawData(raw_data, size);
result.d->ref.atomic.store(2);
result.d->alloc = size;
result.isRawData = true;
return result;
}
template <typename T, qlonglong PreallocSize> inline dtkArray<T, PreallocSize> dtkArray<T, PreallocSize>::fromWritableRawData(T *raw_data, qlonglong size)
{
dtkArray result;
result.d = Data::fromRawData(raw_data, size);
result.d->alloc = size;
result.isRawData = true;
return result;
}
template <typename T, qlonglong PreallocSize> inline typename dtkArray<T, PreallocSize>::iterator dtkArray<T, PreallocSize>::erase(iterator abegin, iterator aend)
{
Q_ASSERT_X(isValidIterator(abegin), "dtkArray<T, PreallocSize>::erase", "The specified iterator argument 'begin' is invalid");
......@@ -1147,25 +1152,27 @@ template<typename T, qlonglong PreallocSize> inline QDataStream& operator>>(QDat
return s;
}
// template<typename T, qlonglong PreallocSize> inline QDataStream& operator<<(QDataStream& s, const dtkArray<T *, PreallocSize>& a)
// {
// s << quint64(a.size());
// for (typename dtkArray<T *, PreallocSize>::const_iterator it = a.begin(); it != a.end(); ++it)
// s << dtkMetaType::variantFromValue(*it);
// return s;
// }
// template<typename T, qlonglong PreallocSize> inline QDataStream& operator>>(QDataStream& s, dtkArray<T *, PreallocSize>& a)
// {
// a.clear();
// quint64 c; s >> c;
// a.resize(c);
// for(quint64 i = 0; i < c; ++i) {
// s >> var;
// a[i] = var.value<T *>();
// }
// return s;
// }
template<typename T, qlonglong PreallocSize> inline QDataStream& operator<<(QDataStream& s, const dtkArray<T *, PreallocSize>& a)
{
s << quint64(a.size());
for (typename dtkArray<T *, PreallocSize>::const_iterator it = a.begin(); it != a.end(); ++it)
s << dtkMetaType::variantFromValue(*it);
return s;
}
template<typename T, qlonglong PreallocSize> inline QDataStream& operator>>(QDataStream& s, dtkArray<T *, PreallocSize>& a)
{
a.clear();
quint64 c; s >> c;
a.reserve(c);
for(quint64 i = 0; i < c; ++i) {
QVariant var;
s >> var;
a.append(var.value<T *>());
}
return s;
}
//
// dtkArray.tpp ends here
......@@ -42,7 +42,7 @@ void dtkRoundUpNextPowerOfTwo(quint64& nalloc)
qintptr dtkAllocMore(qintptr alloc, qintptr extra)
{
Q_ASSERT(alloc >= 0 && extra >= 0);
Q_ASSERT_X(alloc < (1ll << 62) - extra, "dtkAllocMore", "Requested size is too large!");
Q_ASSERT_X(alloc < (quint64(1) << 63) - (extra + 1), "dtkAllocMore", "Requested size is too large!");
quint64 nalloc = alloc + extra;
......
......@@ -1469,199 +1469,224 @@ void dtkArrayTestCase::testInsert(void)
QVERIFY(array3[16] == 10);
}
// void dtkArrayTestCase::testSetRawData(void)
// {
// dtkArray<double> array;
// double contents[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
// 7.0, 8.0, 9.0, 10.0, 11.0, 12.0};
// array.setRawData(contents, 0);
// QCOMPARE(array.size(), 0);
// QCOMPARE(array.capacity(), 0);
// QVERIFY(!array.isDetached());
// array.append(1.0);
// QCOMPARE(array.size(), 1);
// QVERIFY(array.capacity() > 0);
// QCOMPARE(array.at(0), 1.0);
// QVERIFY(array.isDetached());
// array.setRawData(contents, 6);
// QCOMPARE(array.size(), 6);
// QCOMPARE(array.capacity(), 6);
// for (int index = 0; index < 6; ++index)
// QCOMPARE(array.at(index), contents[index]);
// QVERIFY(array.constData() == contents);
// QVERIFY(!array.isDetached());
// // Force a copy-on-write.
// array[3] = 42.0;
// QVERIFY(array.isDetached());
// QCOMPARE(contents[3], 4.0);
// QCOMPARE(array.size(), 6);
// QVERIFY(array.capacity() > 6);
// for (int index = 0; index < 6; ++index) {
// if (index != 3)
// QCOMPARE(array.at(index), contents[index]);
// else
// QCOMPARE(array.at(index), 42.0);
// }
// QVERIFY(array.constData() != contents);
// array.setRawData(contents, 12);
// QCOMPARE(array.size(), 12);
// QCOMPARE(array.capacity(), 12);
// for (int index = 0; index < 12; ++index)
// QCOMPARE(array.at(index), contents[index]);
// QVERIFY(array.constData() == contents);
// QString strings[] = {QLatin1String("foo"), QLatin1String("bar")};
// dtkArray<QString> array2;
// array2.setRawData(strings, 2);
// QCOMPARE(array2.size(), 2);
// QCOMPARE(array2.capacity(), 2);
// QCOMPARE(array2.at(0), QLatin1String("foo"));
// QCOMPARE(array2.at(1), QLatin1String("bar"));
// QVERIFY(array2.constData() == strings);
// // Force a copy-on-write.
// array2[1] = QLatin1String("baz");
// QCOMPARE(array2.size(), 2);
// QVERIFY(array2.capacity() > 2);
// QCOMPARE(array2.at(0), QLatin1String("foo"));
// QCOMPARE(array2.at(1), QLatin1String("baz"));
// QVERIFY(array2.constData() != strings);
// QCOMPARE(strings[0], QLatin1String("foo"));
// QCOMPARE(strings[1], QLatin1String("bar"));
// }
// void dtkArrayTestCase::testFromRawData(void)
// {
// dtkArray<double> array;
// double contents[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
// 7.0, 8.0, 9.0, 10.0, 11.0, 12.0};
// array = dtkArray<double>::fromRawData(contents, 0);
// QCOMPARE(array.size(), 0);
// QCOMPARE(array.capacity(), 0);
// QVERIFY(!array.isDetached());
// array.append(1.0);
// QCOMPARE(array.size(), 1);
// QVERIFY(array.capacity() > 0);
// QCOMPARE(array.at(0), 1.0);
// QVERIFY(array.isDetached());
// array = dtkArray<double>::fromRawData(contents, 6);
// QCOMPARE(array.size(), 6);
// QCOMPARE(array.capacity(), 6);
// for (int index = 0; index < 6; ++index)
// QCOMPARE(array.at(index), contents[index]);
// QVERIFY(array.constData() == contents);
// QVERIFY(!array.isDetached());
// // Force a copy-on-write.
// array[3] = 42.0;
// QVERIFY(array.isDetached());
// QCOMPARE(contents[3], 4.0);
// QCOMPARE(array.size(), 6);
// QVERIFY(array.capacity() > 6);
// for (int index = 0; index < 6; ++index) {
// if (index != 3)
// QCOMPARE(array.at(index), contents[index]);
// else
// QCOMPARE(array.at(index), 42.0);
// }
// QVERIFY(array.constData() != contents);
// array = dtkArray<double>::fromRawData(contents, 12);
// QCOMPARE(array.size(), 12);
// QCOMPARE(array.capacity(), 12);
// for (int index = 0; index < 12; ++index)
// QCOMPARE(array.at(index), contents[index]);
// QVERIFY(array.constData() == contents);
// QString strings[] = {QLatin1String("foo"), QLatin1String("bar")};
// dtkArray<QString> array2;
// array2 = dtkArray<QString>::fromRawData(strings, 2);
// QCOMPARE(array2.size(), 2);
// QCOMPARE(array2.capacity(), 2);
// QCOMPARE(array2.at(0), QLatin1String("foo"));
// QCOMPARE(array2.at(1), QLatin1String("bar"));
// QVERIFY(array2.constData() == strings);
// // Force a copy-on-write.
// array2[1] = QLatin1String("baz");
// QCOMPARE(array2.size(), 2);
// QVERIFY(array2.capacity() > 2);
// QCOMPARE(array2.at(0), QLatin1String("foo"));
// QCOMPARE(array2.at(1), QLatin1String("baz"));
// QVERIFY(array2.constData() != strings);
// QCOMPARE(strings[0], QLatin1String("foo"));
// QCOMPARE(strings[1], QLatin1String("bar"));
// }
// void dtkArrayTestCase::testFromWritableRawData(void)
// {
// dtkArray<double> array;
// double contents[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
// double contentsModified[] =
// {1.0, 2.0, 3.0, 42.0, 5.0, 6.0, 53.0};
// array = dtkArray<double>::fromWritableRawData(contents, 0);
// QCOMPARE(array.size(), 0);
// QCOMPARE(array.capacity(), 0);
// array.append(0.0);
// QCOMPARE(array.size(), 1);
// QVERIFY(array.capacity() > 0);
// QCOMPARE(array.at(0), 0.0);
// array = dtkArray<double>::fromWritableRawData(contents, 6);
// QCOMPARE(array.size(), 6);
// QCOMPARE(array.capacity(), 6);
// for (int index = 0; index < 6; ++index)
// QCOMPARE(array.at(index), contents[index]);
// QVERIFY(array.constData() == contents);