ReshapeOrder for reshape() methods

Last PIVector features ported to PIDeque
This commit is contained in:
2021-07-16 17:19:06 +03:00
parent de0e9f91ce
commit 511bedf425
4 changed files with 118 additions and 17 deletions

View File

@@ -53,6 +53,10 @@ public:
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(pid_size, f);
}
inline PIDeque(size_t piv_size, std::function<T(size_t)> f): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(piv_size, f);
}
inline PIDeque(PIDeque<T> && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
other._reset();
@@ -80,6 +84,11 @@ public:
typedef T value_type;
enum ReshapeOrder {
byRow,
byColumn
};
class iterator {
friend class PIDeque<T>;
private:
@@ -239,6 +248,13 @@ public:
elementNew(pid_data + i, f);
return *this;
}
inline PIDeque<T> & fill(std::function<T(size_t)> f) {
deleteT(pid_data + pid_start, pid_size);
PIINTROSPECTION_CONTAINER_USED(T, pid_size)
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
elementNew(pid_data + i, f(i));
return *this;
}
inline PIDeque<T> & assign(const T & f = T()) {return fill(f);}
template<typename T1 = T, typename std::enable_if<
!std::is_trivially_copyable<T1>::value
@@ -266,7 +282,24 @@ public:
size_t os = pid_size;
alloc(new_size, true);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) elementNew(pid_data + i, f);
for (size_t i = os + pid_start; i < new_size + pid_start; ++i)
elementNew(pid_data + i, f);
}
return *this;
}
inline PIDeque<T> & resize(size_t new_size, std::function<T(size_t)> f) {
if (new_size < pid_size) {
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
pid_size = new_size;
if (new_size == 0)
pid_start = (pid_rsize - pid_size) / 2;
}
if (new_size > pid_size) {
size_t os = pid_size;
alloc(new_size, true);
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
for (size_t i = os + pid_start; i < new_size + pid_start; ++i)
elementNew(pid_data + i, f(i));
}
return *this;
}
@@ -471,6 +504,47 @@ public:
return ret;
}
inline PIDeque<PIDeque<T>> reshape(size_t rows, size_t cols, int order = byRow) const {
PIDeque<PIDeque<T>> ret;
if (isEmpty()) return ret;
assert(rows*cols == pid_size);
ret.resize(rows);
if (order == byRow) {
for (size_t r = 0; r < rows; r++)
ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols);
}
if (order == byColumn) {
for (size_t r = 0; r < rows; r++) {
ret[r].resize(cols);
for (size_t c = 0; c < cols; c++)
ret[r][c] = pid_data[c*rows + r];
}
}
return ret;
}
template<typename C, typename std::enable_if<
std::is_same<T, PIDeque<C>>::value
, int>::type = 0>
inline PIDeque<C> reshape(int order = byRow) const {
PIDeque<C> ret;
if (isEmpty()) return ret;
size_t rows = size();
size_t cols = at(0).size();
ret.reserve(rows * cols);
if (order == byRow) {
for (size_t r = 0; r < rows; r++)
ret.append(at(r));
}
if (order == byColumn) {
for (size_t c = 0; c < cols; c++)
for (size_t r = 0; r < rows; r++)
ret << at(r)[c];
}
ret.resize(rows * cols);
return ret;
}
private:
inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
inline size_t asize(ssize_t s) {