diff --git a/libs/crypt/piauth.cpp b/libs/crypt/piauth.cpp index dcb91369..d3858355 100644 --- a/libs/crypt/piauth.cpp +++ b/libs/crypt/piauth.cpp @@ -128,7 +128,7 @@ PIAuth::State PIAuth::receive(PIByteArray & ba) { passwordRequest(&ps); if (ps.isEmpty()) return disconnect(ba, "Canceled by user"); ph = crypt.passwordHash(ps, PIString("PIAuth").toByteArray()); - ps.fill(0); + ps.fill(PIChar(0)); tba.clear(); tba << ph << auth_sign << sign_pk; tba = crypt.crypt(tba, box_pk, box_sk); diff --git a/libs/main/containers/pideque.h b/libs/main/containers/pideque.h index ebc8a990..4e38944d 100644 --- a/libs/main/containers/pideque.h +++ b/libs/main/containers/pideque.h @@ -53,6 +53,10 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(pid_size, f); } + inline PIDeque(size_t piv_size, std::function 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 && 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; private: @@ -239,6 +248,13 @@ public: elementNew(pid_data + i, f); return *this; } + inline PIDeque & fill(std::function 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 & assign(const T & f = T()) {return fill(f);} template::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 & resize(size_t new_size, std::function 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> reshape(size_t rows, size_t cols, int order = byRow) const { + PIDeque> 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(&(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>::value + , int>::type = 0> + inline PIDeque reshape(int order = byRow) const { + PIDeque 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) { diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index 75becdca..b7a194c5 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -53,6 +53,10 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } + inline PIVector(size_t piv_size, std::function f): piv_data(0), piv_size(0), piv_rsize(0) { + PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) + resize(piv_size, f); + } inline PIVector(PIVector && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) other._reset(); @@ -81,6 +85,11 @@ public: typedef T value_type; + enum ReshapeOrder { + byRow, + byColumn + }; + class iterator { friend class PIVector; private: @@ -470,12 +479,21 @@ public: return ret; } - inline PIVector> reshape(size_t rows, size_t cols) const { - assert(rows*cols == piv_size); + inline PIVector> reshape(size_t rows, size_t cols, int order = byRow) const { PIVector> ret; + if (isEmpty()) return ret; + assert(rows*cols == piv_size); ret.resize(rows); - for (size_t i = 0; i < rows; i++) { - ret[i] = PIVector(&(piv_data[i*cols]), cols); + if (order == byRow) { + for (size_t r = 0; r < rows; r++) + ret[r] = PIVector(&(piv_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] = piv_data[c*rows + r]; + } } return ret; } @@ -483,17 +501,22 @@ public: template>::value , int>::type = 0> - inline PIVector reshape() const { + inline PIVector reshape(int order = byRow) const { PIVector ret; + if (isEmpty()) return ret; size_t rows = size(); - if (rows) { - size_t cols = at(0).size(); - ret.reserve(rows * cols); - for (size_t i = 0; i < rows; i++) { - ret.append(at(i)); - } - ret.resize(rows * cols); + 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; } diff --git a/main.cpp b/main.cpp index 6afa8630..26301951 100644 --- a/main.cpp +++ b/main.cpp @@ -10,13 +10,17 @@ template x; + PIDeque x; x.resize(16, [](size_t i) {return i+1;}); piCout << x; - PIVector> m = x.reshape(4,4); + PIDeque> m = x.reshape(2,8); piCout << m; - PIVector y; + piCout << x.reshape(4,4,PIDeque::byColumn); + piCout << x.reshape(2,8); + piCout << x.reshape(2,8,PIDeque::byColumn); + PIDeque y; y = m.reshape(); piCout << y; + piCout << m.reshape(PIDeque::byColumn); return 0; }