Compare commits

3 Commits

Author SHA1 Message Date
61d42e0ac5 PIVector: map, reduce
rename arguments in uniform style
2021-09-07 18:29:09 +03:00
127935086c PIVector: any, every, indexWhere, lastIndexWhere
start arg in indexOf, entries, lastIndexOf
and some code brush
2021-09-07 17:29:24 +03:00
76ed60edf3 code brush 2021-09-07 15:39:44 +03:00
3 changed files with 291 additions and 136 deletions

View File

@@ -174,6 +174,7 @@ public:
inline size_t capacity() const {return pid_rsize;} inline size_t capacity() const {return pid_rsize;}
inline size_t _start() const {return pid_start;} inline size_t _start() const {return pid_start;}
inline bool isEmpty() const {return (pid_size == 0);} inline bool isEmpty() const {return (pid_size == 0);}
inline bool isNotEmpty() const {return (pid_size > 0);}
inline T & operator [](size_t index) {return pid_data[pid_start + index];} inline T & operator [](size_t index) {return pid_data[pid_start + index];}
inline const T & operator [](size_t index) const {return pid_data[pid_start + index];} inline const T & operator [](size_t index) const {return pid_data[pid_start + index];}
@@ -184,34 +185,41 @@ public:
inline const T & front() const {return pid_data[pid_start];} inline const T & front() const {return pid_data[pid_start];}
inline bool operator ==(const PIDeque<T> & t) const { inline bool operator ==(const PIDeque<T> & t) const {
if (pid_size != t.pid_size) return false; if (pid_size != t.pid_size) return false;
for (size_t i = 0; i < pid_size; ++i) for (size_t i = 0; i < pid_size; ++i) {
if (t[i] != (*this)[i]) if (t[i] != (*this)[i]) {
return false; return false;
}
}
return true; return true;
} }
inline bool operator !=(const PIDeque<T> & t) const {return !(*this == t);} inline bool operator !=(const PIDeque<T> & t) const {return !(*this == t);}
inline bool operator <(const PIDeque<T> & t) const { inline bool operator <(const PIDeque<T> & t) const {
if (pid_size != t.pid_size) return pid_size < t.pid_size; if (pid_size != t.pid_size) return pid_size < t.pid_size;
for (size_t i = 0; i < pid_size; ++i) for (size_t i = 0; i < pid_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] < t[i]; if ((*this)[i] != t[i]) return (*this)[i] < t[i];
}
return false; return false;
} }
inline bool operator >(const PIDeque<T> & t) const { inline bool operator >(const PIDeque<T> & t) const {
if (pid_size != t.pid_size) return pid_size > t.pid_size; if (pid_size != t.pid_size) return pid_size > t.pid_size;
for (size_t i = 0; i < pid_size; ++i) for (size_t i = 0; i < pid_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] > t[i]; if ((*this)[i] != t[i]) return (*this)[i] > t[i];
}
return false; return false;
} }
inline bool contains(const T & v) const { inline bool contains(const T & v) const {
for (size_t i = pid_start; i < pid_start + pid_size; ++i) for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
if (v == pid_data[i]) if (v == pid_data[i]) {
return true; return true;
}
}
return false; return false;
} }
inline int etries(const T & v) const { inline int etries(const T & v) const {
int ec = 0; int ec = 0;
for (size_t i = pid_start; i < pid_start + pid_size; ++i) for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
if (v == pid_data[i]) ++ec; if (v == pid_data[i]) ++ec;
}
return ec; return ec;
} }
inline ssize_t indexOf(const T & v) const { inline ssize_t indexOf(const T & v) const {
@@ -221,9 +229,11 @@ public:
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & v) const { inline ssize_t lastIndexOf(const T & v) const {
for (ssize_t i = pid_start + (ssize_t)pid_size - 1; i >= pid_start; --i) for (ssize_t i = pid_start + (ssize_t)pid_size - 1; i >= pid_start; --i) {
if (v == pid_data[i]) if (v == pid_data[i]) {
return i - pid_start; return i - pid_start;
}
}
return -1; return -1;
} }
@@ -250,15 +260,17 @@ public:
inline PIDeque<T> & fill(const T & f = T()) { inline PIDeque<T> & fill(const T & f = T()) {
deleteT(pid_data + pid_start, pid_size); deleteT(pid_data + pid_start, pid_size);
PIINTROSPECTION_CONTAINER_USED(T, pid_size) PIINTROSPECTION_CONTAINER_USED(T, pid_size)
for (size_t i = pid_start; i < pid_start + pid_size; ++i) for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
elementNew(pid_data + i, f); elementNew(pid_data + i, f);
}
return *this; return *this;
} }
inline PIDeque<T> & fill(std::function<T(size_t)> f) { inline PIDeque<T> & fill(std::function<T(size_t)> f) {
deleteT(pid_data + pid_start, pid_size); deleteT(pid_data + pid_start, pid_size);
PIINTROSPECTION_CONTAINER_USED(T, pid_size) PIINTROSPECTION_CONTAINER_USED(T, pid_size)
for (size_t i = pid_start; i < pid_start + pid_size; ++i) for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
elementNew(pid_data + i, f(i)); elementNew(pid_data + i, f(i));
}
return *this; return *this;
} }
inline PIDeque<T> & assign(const T & f = T()) {return fill(f);} inline PIDeque<T> & assign(const T & f = T()) {return fill(f);}
@@ -281,32 +293,36 @@ public:
if (new_size < pid_size) { if (new_size < pid_size) {
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size); deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
pid_size = new_size; pid_size = new_size;
if (new_size == 0) if (new_size == 0) {
pid_start = (pid_rsize - pid_size) / 2; pid_start = (pid_rsize - pid_size) / 2;
} }
}
if (new_size > pid_size) { if (new_size > pid_size) {
size_t os = pid_size; size_t os = pid_size;
alloc(new_size, true); alloc(new_size, true);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
elementNew(pid_data + i, f); elementNew(pid_data + i, f);
} }
}
return *this; return *this;
} }
inline PIDeque<T> & resize(size_t new_size, std::function<T(size_t)> f) { inline PIDeque<T> & resize(size_t new_size, std::function<T(size_t)> f) {
if (new_size < pid_size) { if (new_size < pid_size) {
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size); deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
pid_size = new_size; pid_size = new_size;
if (new_size == 0) if (new_size == 0) {
pid_start = (pid_rsize - pid_size) / 2; pid_start = (pid_rsize - pid_size) / 2;
} }
}
if (new_size > pid_size) { if (new_size > pid_size) {
size_t os = pid_size; size_t os = pid_size;
alloc(new_size, true); alloc(new_size, true);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
elementNew(pid_data + i, f(i)); elementNew(pid_data + i, f(i));
} }
}
return *this; return *this;
} }
@@ -344,9 +360,10 @@ public:
} }
} else { } else {
alloc(pid_size + 1, false, -1); alloc(pid_size + 1, false, -1);
if (index > 0) if (index > 0) {
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
} }
}
elementNew(pid_data + pid_start + index, v); elementNew(pid_data + pid_start + index, v);
return *this; return *this;
} }
@@ -362,9 +379,10 @@ public:
} }
} else { } else {
alloc(pid_size + 1, false, -1); alloc(pid_size + 1, false, -1);
if (index > 0) if (index > 0) {
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
} }
}
elementNew(pid_data + pid_start + index, std::move(v)); elementNew(pid_data + pid_start + index, std::move(v));
return *this; return *this;
} }
@@ -375,13 +393,15 @@ public:
if (dir) { if (dir) {
ssize_t os = pid_size - index; ssize_t os = pid_size - index;
alloc(pid_size + other.pid_size, true); alloc(pid_size + other.pid_size, true);
if (os > 0) if (os > 0) {
memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
}
} else { } else {
alloc(pid_size + other.pid_size, false, -other.pid_size); alloc(pid_size + other.pid_size, false, -other.pid_size);
if (index > 0) if (index > 0) {
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T)); memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T));
} }
}
newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size); newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size);
return *this; return *this;
} }
@@ -395,9 +415,13 @@ public:
size_t os = pid_size - index - count; size_t os = pid_size - index - count;
deleteT(&(pid_data[index + pid_start]), count); deleteT(&(pid_data[index + pid_start]), count);
if (os <= index) { if (os <= index) {
if (os > 0) memmove((void*)(&(pid_data[index + pid_start])), (const void*)(&(pid_data[index + pid_start + count])), os * sizeof(T)); if (os > 0) {
memmove((void*)(&(pid_data[index + pid_start])), (const void*)(&(pid_data[index + pid_start + count])), os * sizeof(T));
}
} else { } else {
if (index > 0) memmove((void*)(&(pid_data[pid_start + count])), (const void*)(&(pid_data[pid_start])), index * sizeof(T)); if (index > 0) {
memmove((void*)(&(pid_data[pid_start + count])), (const void*)(&(pid_data[pid_start])), index * sizeof(T));
}
pid_start += count; pid_start += count;
} }
pid_size -= count; pid_size -= count;
@@ -426,19 +450,21 @@ public:
} }
inline PIDeque<T> & removeOne(const T & v) { inline PIDeque<T> & removeOne(const T & v) {
for (size_t i = 0; i < pid_size; ++i) for (size_t i = 0; i < pid_size; ++i) {
if (pid_data[i + pid_start] == v) { if (pid_data[i + pid_start] == v) {
remove(i); remove(i);
return *this; return *this;
} }
}
return *this; return *this;
} }
inline PIDeque<T> & removeAll(const T & v) { inline PIDeque<T> & removeAll(const T & v) {
for (ssize_t i = 0; i < ssize_t(pid_size); ++i) for (ssize_t i = 0; i < ssize_t(pid_size); ++i) {
if (pid_data[i + pid_start] == v) { if (pid_data[i + pid_start] == v) {
remove(i); remove(i);
--i; --i;
} }
}
return *this; return *this;
} }
@@ -481,20 +507,23 @@ public:
template <typename ST> template <typename ST>
PIDeque<ST> toType() const { PIDeque<ST> toType() const {
PIDeque<ST> ret(pid_size); PIDeque<ST> ret(pid_size);
for (uint i = 0; i < pid_size; ++i) for (uint i = 0; i < pid_size; ++i) {
ret[i] = ST(pid_data[i + pid_start]); ret[i] = ST(pid_data[i + pid_start]);
}
return ret; return ret;
} }
const PIDeque<T> & forEach(std::function<void(const T &)> f) const { const PIDeque<T> & forEach(std::function<void(const T &)> f) const {
for (uint i = 0; i < pid_size; ++i) for (uint i = 0; i < pid_size; ++i) {
f(pid_data[i + pid_start]); f(pid_data[i + pid_start]);
}
return *this; return *this;
} }
PIDeque<T> copyForEach(std::function<T(const T &)> f) const { PIDeque<T> copyForEach(std::function<T(const T &)> f) const {
PIDeque<T> ret; ret.reserve(pid_size); PIDeque<T> ret; ret.reserve(pid_size);
for (uint i = 0; i < pid_size; ++i) for (uint i = 0; i < pid_size; ++i) {
ret << f(pid_data[i + pid_start]); ret << f(pid_data[i + pid_start]);
}
return ret; return ret;
} }
PIDeque<T> & forEachInplace(std::function<T(const T &)> f) { PIDeque<T> & forEachInplace(std::function<T(const T &)> f) {
@@ -505,8 +534,9 @@ public:
template <typename ST> template <typename ST>
PIDeque<ST> toType(std::function<ST(const T &)> f) const { PIDeque<ST> toType(std::function<ST(const T &)> f) const {
PIDeque<ST> ret; ret.reserve(pid_size); PIDeque<ST> ret; ret.reserve(pid_size);
for (uint i = 0; i < pid_size; ++i) for (uint i = 0; i < pid_size; ++i) {
ret << f(pid_data[i + pid_start]); ret << f(pid_data[i + pid_start]);
}
return ret; return ret;
} }
@@ -516,16 +546,18 @@ public:
assert(rows*cols == pid_size); assert(rows*cols == pid_size);
ret.resize(rows); ret.resize(rows);
if (order == byRow) { if (order == byRow) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols); ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols);
} }
}
if (order == byColumn) { if (order == byColumn) {
for (size_t r = 0; r < rows; r++) { for (size_t r = 0; r < rows; r++) {
ret[r].resize(cols); ret[r].resize(cols);
for (size_t c = 0; c < cols; c++) for (size_t c = 0; c < cols; c++) {
ret[r][c] = pid_data[c*rows + r]; ret[r][c] = pid_data[c*rows + r];
} }
} }
}
return ret; return ret;
} }
@@ -539,14 +571,17 @@ public:
size_t cols = at(0).size(); size_t cols = at(0).size();
ret.reserve(rows * cols); ret.reserve(rows * cols);
if (order == byRow) { if (order == byRow) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret.append(at(r)); ret.append(at(r));
} }
}
if (order == byColumn) { if (order == byColumn) {
for (size_t c = 0; c < cols; c++) for (size_t c = 0; c < cols; c++) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret << at(r)[c]; ret << at(r)[c];
} }
}
}
ret.resize(rows * cols); ret.resize(rows * cols);
return ret; return ret;
} }
@@ -555,11 +590,13 @@ private:
inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;} inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
inline size_t asize(ssize_t s) { inline size_t asize(ssize_t s) {
if (s <= 0) return 0; if (s <= 0) return 0;
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
return pid_rsize + pid_rsize; return pid_rsize + pid_rsize;
}
ssize_t t = 0, s_ = s - 1; ssize_t t = 0, s_ = s - 1;
while (s_ >> t) while (s_ >> t) {
++t; ++t;
}
return (1 << t); return (1 << t);
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
@@ -583,10 +620,11 @@ private:
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
if ((uchar*)d != 0) { if ((uchar*)d != 0) {
for (size_t i = 0; i < sz; ++i) for (size_t i = 0; i < sz; ++i) {
elementDelete(d[i]); elementDelete(d[i]);
} }
} }
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
@@ -658,10 +696,11 @@ private:
} }
} else { } else {
size_t as; size_t as;
if (pid_start + start_offset < 0) if (pid_start + start_offset < 0) {
as = asize(pid_rsize - start_offset); as = asize(pid_rsize - start_offset);
else as = pid_rsize; } else {
as = pid_rsize;
}
if (as > pid_rsize) { if (as > pid_rsize) {
T * td = (T*)(malloc(as * sizeof(T))); T * td = (T*)(malloc(as * sizeof(T)));
ssize_t ns = pid_start + as - pid_rsize; ssize_t ns = pid_start + as - pid_rsize;
@@ -688,7 +727,15 @@ private:
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
template<typename T> template<typename T>
inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;} inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {
s << "{";
for (size_t i = 0; i < v.size(); ++i) {
s << v[i];
if (i < v.size() - 1) s << ", ";
}
s << "}";
return s;
}
#endif #endif
template<typename T> template<typename T>
@@ -698,8 +745,7 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
s << "{"; s << "{";
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
s << v[i]; s << v[i];
if (i < v.size() - 1) if (i < v.size() - 1) s << ", ";
s << ", ";
} }
s << "}"; s << "}";
s.restoreControl(); s.restoreControl();

View File

@@ -39,10 +39,10 @@ public:
alloc(size); alloc(size);
newT(piv_data, data, piv_size); newT(piv_data, data, piv_size);
} }
inline PIVector(const PIVector<T> & other): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(other.piv_size); alloc(v.piv_size);
newT(piv_data, other.piv_data, piv_size); newT(piv_data, v.piv_data, piv_size);
} }
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
@@ -53,13 +53,13 @@ public:
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(piv_size, f); resize(piv_size, f);
} }
inline PIVector(size_t piv_size, std::function<T(size_t)> f): piv_data(0), piv_size(0), piv_rsize(0) { inline PIVector(size_t piv_size, std::function<T(size_t i)> f): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(piv_size, f); resize(piv_size, f);
} }
inline PIVector(PIVector<T> && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) { inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
other._reset(); v._reset();
} }
inline virtual ~PIVector() { inline virtual ~PIVector() {
PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_DELETE(T)
@@ -69,17 +69,17 @@ public:
_reset(); _reset();
} }
inline PIVector<T> & operator =(const PIVector<T> & other) { inline PIVector<T> & operator =(const PIVector<T> & v) {
if (this == &other) return *this; if (this == &v) return *this;
clear(); clear();
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
alloc(other.piv_size); alloc(v.piv_size);
newT(piv_data, other.piv_data, piv_size); newT(piv_data, v.piv_data, piv_size);
return *this; return *this;
} }
inline PIVector<T> & operator =(PIVector<T> && other) { inline PIVector<T> & operator =(PIVector<T> && v) {
swap(other); swap(v);
return *this; return *this;
} }
@@ -174,6 +174,19 @@ public:
inline size_t length() const {return piv_size;} inline size_t length() const {return piv_size;}
inline size_t capacity() const {return piv_rsize;} inline size_t capacity() const {return piv_rsize;}
inline bool isEmpty() const {return (piv_size == 0);} inline bool isEmpty() const {return (piv_size == 0);}
inline bool isNotEmpty() const {return (piv_size > 0);}
inline bool any(std::function<bool(const T &)> test) const {
for (uint i = 0; i < piv_size; ++i) {
if (test(piv_data[i])) return true;
}
return false;
}
inline bool every(std::function<bool(const T &)> test) const {
for (uint i = 0; i < piv_size; ++i) {
if (!test(piv_data[i])) return false;
}
return true;
}
inline T & operator [](size_t index) {return piv_data[index];} inline T & operator [](size_t index) {return piv_data[index];}
inline const T & operator [](size_t index) const {return piv_data[index];} inline const T & operator [](size_t index) const {return piv_data[index];}
@@ -183,48 +196,87 @@ public:
inline T & front() {return piv_data[0];} inline T & front() {return piv_data[0];}
inline const T & front() const {return piv_data[0];} inline const T & front() const {return piv_data[0];}
inline bool operator ==(const PIVector<T> & t) const { inline bool operator ==(const PIVector<T> & t) const {
if (piv_size != t.piv_size) if (piv_size != t.piv_size) {
return false; return false;
for (size_t i = 0; i < piv_size; ++i) }
if (t[i] != piv_data[i]) for (size_t i = 0; i < piv_size; ++i) {
if (t[i] != piv_data[i]) {
return false; return false;
}
}
return true; return true;
} }
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);} inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
inline bool operator <(const PIVector<T> & t) const { inline bool operator <(const PIVector<T> & t) const {
if (piv_size != t.piv_size) return piv_size < t.piv_size; if (piv_size != t.piv_size) return piv_size < t.piv_size;
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] < t[i]; if ((*this)[i] != t[i]) return (*this)[i] < t[i];
}
return false; return false;
} }
inline bool operator >(const PIVector<T> & t) const { inline bool operator >(const PIVector<T> & t) const {
if (piv_size != t.piv_size) return piv_size > t.piv_size; if (piv_size != t.piv_size) return piv_size > t.piv_size;
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
if ((*this)[i] != t[i]) return (*this)[i] > t[i]; if ((*this)[i] != t[i]) return (*this)[i] > t[i];
}
return false; return false;
} }
inline bool contains(const T & v) const { inline bool contains(const T & e) const {
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
if (v == piv_data[i]) if (e == piv_data[i]) {
return true; return true;
}
}
return false; return false;
} }
inline int etries(const T & v) const { inline int etries(const T & e, size_t start = 0) const {
int ec = 0; int ec = 0;
for (size_t i = 0; i < piv_size; ++i) for (size_t i = start; i < piv_size; ++i) {
if (v == piv_data[i]) ++ec; if (e == piv_data[i]) ++ec;
}
return ec; return ec;
} }
inline ssize_t indexOf(const T & v) const { inline int etries(std::function<bool(const T & e)> test, size_t start = 0) const {
for (size_t i = 0; i < piv_size; ++i) int ec = 0;
if (v == piv_data[i]) for (size_t i = start; i < piv_size; ++i) {
if (test(piv_data[i])) ++ec;
}
return ec;
}
inline ssize_t indexOf(const T & e, size_t start = 0) const {
for (size_t i = start; i < piv_size; ++i) {
if (e == piv_data[i]) {
return i; return i;
}
}
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & v) const { inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
for (ssize_t i = piv_size - 1; i >= 0; --i) for (size_t i = start; i < piv_size; ++i) {
if (v == piv_data[i]) if (test(piv_data[i])) {
return i; return i;
}
}
return -1;
}
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
if (start < 0) start = piv_size - 1;
else start = piMin<ssize_t>(piv_size - 1, start);
for (ssize_t i = start; i >= 0; --i) {
if (e == piv_data[i]) {
return i;
}
}
return -1;
}
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
if (start < 0) start = piv_size - 1;
else start = piMin<ssize_t>(piv_size - 1, start);
for (ssize_t i = start; i >= 0; --i) {
if (test(piv_data[i])) {
return i;
}
}
return -1; return -1;
} }
@@ -250,15 +302,17 @@ public:
inline PIVector<T> & fill(const T & f = T()) { inline PIVector<T> & fill(const T & f = T()) {
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
PIINTROSPECTION_CONTAINER_USED(T, piv_size) PIINTROSPECTION_CONTAINER_USED(T, piv_size)
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
elementNew(piv_data + i, f); elementNew(piv_data + i, f);
}
return *this; return *this;
} }
inline PIVector<T> & fill(std::function<T(size_t)> f) { inline PIVector<T> & fill(std::function<T(size_t i)> f) {
deleteT(piv_data, piv_size); deleteT(piv_data, piv_size);
PIINTROSPECTION_CONTAINER_USED(T, piv_size) PIINTROSPECTION_CONTAINER_USED(T, piv_size)
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
elementNew(piv_data + i, f(i)); elementNew(piv_data + i, f(i));
}
return *this; return *this;
} }
inline PIVector<T> & assign(const T & f = T()) {return fill(f);} inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
@@ -287,12 +341,13 @@ public:
size_t os = piv_size; size_t os = piv_size;
alloc(new_size); alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, f); elementNew(piv_data + i, f);
} }
}
return *this; return *this;
} }
inline PIVector<T> & resize(size_t new_size, std::function<T(size_t)> f) { inline PIVector<T> & resize(size_t new_size, std::function<T(size_t i)> f) {
if (new_size < piv_size) { if (new_size < piv_size) {
T * de = &(piv_data[new_size]); T * de = &(piv_data[new_size]);
deleteT(de, piv_size - new_size); deleteT(de, piv_size - new_size);
@@ -302,9 +357,10 @@ public:
size_t os = piv_size; size_t os = piv_size;
alloc(new_size); alloc(new_size);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os)) PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os; i < new_size; ++i) for (size_t i = os; i < new_size; ++i) {
elementNew(piv_data + i, f(i)); elementNew(piv_data + i, f(i));
} }
}
return *this; return *this;
} }
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
@@ -332,34 +388,35 @@ public:
return *this; return *this;
} }
inline PIVector<T> & insert(size_t index, const T & v = T()) { inline PIVector<T> & insert(size_t index, const T & e = T()) {
alloc(piv_size + 1); alloc(piv_size + 1);
if (index < piv_size - 1) { if (index < piv_size - 1) {
size_t os = piv_size - index - 1; size_t os = piv_size - index - 1;
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
} }
PIINTROSPECTION_CONTAINER_USED(T, 1) PIINTROSPECTION_CONTAINER_USED(T, 1)
elementNew(piv_data + index, v); elementNew(piv_data + index, e);
return *this; return *this;
} }
inline PIVector<T> & insert(size_t index, T && v) { inline PIVector<T> & insert(size_t index, T && e) {
alloc(piv_size + 1); alloc(piv_size + 1);
if (index < piv_size - 1) { if (index < piv_size - 1) {
size_t os = piv_size - index - 1; size_t os = piv_size - index - 1;
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
} }
PIINTROSPECTION_CONTAINER_USED(T, 1) PIINTROSPECTION_CONTAINER_USED(T, 1)
elementNew(piv_data + index, std::move(v)); elementNew(piv_data + index, std::move(e));
return *this; return *this;
} }
inline PIVector<T> & insert(size_t index, const PIVector<T> & other) { inline PIVector<T> & insert(size_t index, const PIVector<T> & v) {
if (other.isEmpty()) return *this; if (v.isEmpty()) return *this;
assert(&other != this); assert(&v != this);
ssize_t os = piv_size - index; ssize_t os = piv_size - index;
alloc(piv_size + other.piv_size); alloc(piv_size + v.piv_size);
if (os > 0) if (os > 0) {
memmove((void*)(&(piv_data[index + other.piv_size])), (const void*)(&(piv_data[index])), os * sizeof(T)); memmove((void*)(&(piv_data[index + v.piv_size])), (const void*)(&(piv_data[index])), os * sizeof(T));
newT(piv_data + index, other.piv_data, other.piv_size); }
newT(piv_data + index, v.piv_data, v.piv_size);
return *this; return *this;
} }
@@ -376,10 +433,10 @@ public:
return *this; return *this;
} }
inline void swap(PIVector<T> & other) { inline void swap(PIVector<T> & v) {
piSwap<T*>(piv_data, other.piv_data); piSwap<T*>(piv_data, v.piv_data);
piSwap<size_t>(piv_size, other.piv_size); piSwap<size_t>(piv_size, v.piv_size);
piSwap<size_t>(piv_rsize, other.piv_rsize); piSwap<size_t>(piv_rsize, v.piv_rsize);
} }
typedef int (*CompareFunc)(const T * , const T * ); typedef int (*CompareFunc)(const T * , const T * );
@@ -396,62 +453,65 @@ public:
return *this; return *this;
} }
inline PIVector<T> & removeOne(const T & v) { inline PIVector<T> & removeOne(const T & e) {
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i) {
if (piv_data[i] == v) { if (piv_data[i] == e) {
remove(i); remove(i);
return *this; return *this;
} }
}
return *this; return *this;
} }
inline PIVector<T> & removeAll(const T & v) {
for (ssize_t i = 0; i < ssize_t(piv_size); ++i) inline PIVector<T> & removeAll(const T & e) {
if (piv_data[i] == v) { for (ssize_t i = 0; i < ssize_t(piv_size); ++i) {
if (piv_data[i] == e) {
remove(i); remove(i);
--i; --i;
} }
}
return *this; return *this;
} }
inline PIVector<T> & push_back(const T & v) { inline PIVector<T> & push_back(const T & e) {
alloc(piv_size + 1); alloc(piv_size + 1);
PIINTROSPECTION_CONTAINER_USED(T, 1); PIINTROSPECTION_CONTAINER_USED(T, 1);
elementNew(piv_data + piv_size - 1, v); elementNew(piv_data + piv_size - 1, e);
return *this; return *this;
} }
inline PIVector<T> & push_back(T && v) {
inline PIVector<T> & push_back(T && e) {
alloc(piv_size + 1); alloc(piv_size + 1);
PIINTROSPECTION_CONTAINER_USED(T, 1); PIINTROSPECTION_CONTAINER_USED(T, 1);
elementNew(piv_data + piv_size - 1, std::move(v)); elementNew(piv_data + piv_size - 1, std::move(e));
return *this; return *this;
} }
inline PIVector<T> & append(const T & v) {return push_back(v);}
inline PIVector<T> & append(T && v) {return push_back(std::move(v));} inline PIVector<T> & append(const T & e) {return push_back(e);}
inline PIVector<T> & append(const PIVector<T> & other) { inline PIVector<T> & append(T && e) {return push_back(std::move(e));}
assert(&other != this); inline PIVector<T> & append(const PIVector<T> & v) {
assert(&v != this);
size_t ps = piv_size; size_t ps = piv_size;
alloc(piv_size + other.piv_size); alloc(piv_size + v.piv_size);
newT(piv_data + ps, other.piv_data, other.piv_size); newT(piv_data + ps, v.piv_data, v.piv_size);
return *this; return *this;
} }
inline PIVector<T> & operator <<(const T & v) {return push_back(v);} inline PIVector<T> & operator <<(const T & e) {return push_back(e);}
inline PIVector<T> & operator <<(T && v) {return push_back(std::move(v));} inline PIVector<T> & operator <<(T && e) {return push_back(std::move(e));}
inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);} inline PIVector<T> & operator <<(const PIVector<T> & v) {return append(v);}
inline PIVector<T> & push_front(const T & v) {insert(0, v); return *this;} inline PIVector<T> & push_front(const T & e) {insert(0, e); return *this;}
inline PIVector<T> & push_front(T && v) {insert(0, std::move(v)); return *this;} inline PIVector<T> & push_front(T && e) {insert(0, std::move(e)); return *this;}
inline PIVector<T> & prepend(const T & v) {return push_front(v);} inline PIVector<T> & prepend(const T & e) {return push_front(e);}
inline PIVector<T> & prepend(T && v) {return push_front(std::move(v));} inline PIVector<T> & prepend(T && e) {return push_front(std::move(e));}
inline PIVector<T> & pop_back() { inline PIVector<T> & pop_back() {
if (piv_size == 0) if (piv_size == 0) return *this;
return *this;
resize(piv_size - 1); resize(piv_size - 1);
return *this; return *this;
} }
inline PIVector<T> & pop_front() { inline PIVector<T> & pop_front() {
if (piv_size == 0) if (piv_size == 0) return *this;
return *this;
remove(0); remove(0);
return *this; return *this;
} }
@@ -462,32 +522,49 @@ public:
template <typename ST> template <typename ST>
PIVector<ST> toType() const { PIVector<ST> toType() const {
PIVector<ST> ret(piv_size); PIVector<ST> ret(piv_size);
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i) {
ret[i] = ST(piv_data[i]); ret[i] = ST(piv_data[i]);
}
return ret; return ret;
} }
const PIVector<T> & forEach(std::function<void(const T &)> f) const { const PIVector<T> & forEach(std::function<void(const T & e)> f) const {
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i) {
f(piv_data[i]); f(piv_data[i]);
}
return *this; return *this;
} }
PIVector<T> copyForEach(std::function<T(const T &)> f) const { PIVector<T> copyForEach(std::function<T(const T & e)> f) const {
PIVector<T> ret; ret.reserve(piv_size); PIVector<T> ret; ret.reserve(piv_size);
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i) {
ret << f(piv_data[i]); ret << f(piv_data[i]);
}
return ret; return ret;
} }
PIVector<T> & forEachInplace(std::function<T(const T &)> f) { PIVector<T> & forEachInplace(std::function<T(const T & e)> f) {
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i) {
piv_data[i] = f(piv_data[i]); piv_data[i] = f(piv_data[i]);
}
return *this; return *this;
} }
template <typename ST> template <typename ST>
PIVector<ST> toType(std::function<ST(const T &)> f) const { PIVector<ST> map(std::function<ST(const T & e)> f) const {
PIVector<ST> ret; ret.reserve(piv_size); PIVector<ST> ret; ret.reserve(piv_size);
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i) {
ret << f(piv_data[i]); ret << f(piv_data[i]);
}
return ret;
}
template <typename ST>
PIVector<ST> toType(std::function<ST(const T & e)> f) const {return map(f);}
template <typename ST>
ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
ST ret(initial);
for (uint i = 0; i < piv_size; ++i) {
ret = f(piv_data[i], ret);
}
return ret; return ret;
} }
@@ -497,16 +574,18 @@ public:
assert(rows*cols == piv_size); assert(rows*cols == piv_size);
ret.resize(rows); ret.resize(rows);
if (order == byRow) { if (order == byRow) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret[r] = PIVector<T>(&(piv_data[r*cols]), cols); ret[r] = PIVector<T>(&(piv_data[r*cols]), cols);
} }
}
if (order == byColumn) { if (order == byColumn) {
for (size_t r = 0; r < rows; r++) { for (size_t r = 0; r < rows; r++) {
ret[r].resize(cols); ret[r].resize(cols);
for (size_t c = 0; c < cols; c++) for (size_t c = 0; c < cols; c++) {
ret[r][c] = piv_data[c*rows + r]; ret[r][c] = piv_data[c*rows + r];
} }
} }
}
return ret; return ret;
} }
@@ -520,14 +599,17 @@ public:
size_t cols = at(0).size(); size_t cols = at(0).size();
ret.reserve(rows * cols); ret.reserve(rows * cols);
if (order == byRow) { if (order == byRow) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret.append(at(r)); ret.append(at(r));
} }
}
if (order == byColumn) { if (order == byColumn) {
for (size_t c = 0; c < cols; c++) for (size_t c = 0; c < cols; c++) {
for (size_t r = 0; r < rows; r++) for (size_t r = 0; r < rows; r++) {
ret << at(r)[c]; ret << at(r)[c];
} }
}
}
ret.resize(rows * cols); ret.resize(rows * cols);
return ret; return ret;
} }
@@ -536,8 +618,9 @@ private:
inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;} inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;}
inline size_t asize(size_t s) { inline size_t asize(size_t s) {
if (s == 0) return 0; if (s == 0) return 0;
if (piv_rsize + piv_rsize >= s && piv_rsize < s) if (piv_rsize + piv_rsize >= s && piv_rsize < s) {
return piv_rsize + piv_rsize; return piv_rsize + piv_rsize;
}
ssize_t t = 0, s_ = s - 1; ssize_t t = 0, s_ = s - 1;
while (s_ >> t) ++t; while (s_ >> t) ++t;
return (1 << t); return (1 << t);
@@ -563,10 +646,11 @@ private:
inline void deleteT(T * d, size_t sz) { inline void deleteT(T * d, size_t sz) {
PIINTROSPECTION_CONTAINER_UNUSED(T, sz) PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
if ((uchar*)d != 0) { if ((uchar*)d != 0) {
for (size_t i = 0; i < sz; ++i) for (size_t i = 0; i < sz; ++i) {
elementDelete(d[i]); elementDelete(d[i]);
} }
} }
}
template<typename T1 = T, typename std::enable_if< template<typename T1 = T, typename std::enable_if<
std::is_trivially_copyable<T1>::value std::is_trivially_copyable<T1>::value
, int>::type = 0> , int>::type = 0>
@@ -624,7 +708,15 @@ private:
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
template<typename T> template<typename T>
inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;} inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {
s << "{";
for (size_t i = 0; i < v.size(); ++i) {
s << v[i];
if (i < v.size() - 1) s << ", ";
}
s << "}";
return s;
}
#endif #endif
template<typename T> template<typename T>
@@ -634,9 +726,10 @@ inline PICout operator <<(PICout s, const PIVector<T> & v) {
s << "{"; s << "{";
for (size_t i = 0; i < v.size(); ++i) { for (size_t i = 0; i < v.size(); ++i) {
s << v[i]; s << v[i];
if (i < v.size() - 1) if (i < v.size() - 1) {
s << ", "; s << ", ";
} }
}
s << "}"; s << "}";
s.restoreControl(); s.restoreControl();
return s; return s;

View File

@@ -2,6 +2,22 @@
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
PIVector<int> x(20, [](int i) {return i;});
piCout << x;
piCout << x.any([](int v) {return v == 10;});
piCout << x.every([](int v) {return v > 0;});
piCout << x.etries([](int v) {return v % 5 == 0;});
piCout << x.indexWhere([](int v) {return v % 8 == 0;});
piCout << x.indexOf(4, -1);
piCout << x.lastIndexOf(1, 0);
piCout << x.lastIndexWhere([](int v) {return v % 8 == 0;});
PIVector<double> x2 = x.map<double>([](int v) {return v / 10;});
piCout << x2;
piCout << x.reduce<PIString>([](int v, PIString s){return s + PIString::fromNumber(v);});
return 0; // TODO:
PIByteArray rnd; PIByteArray rnd;
rnd.resize(1024*1024, 'x'); rnd.resize(1024*1024, 'x');
PICLI cli(argc, argv); PICLI cli(argc, argv);