diff --git a/libs/main/containers/pideque.h b/libs/main/containers/pideque.h index b6ae8777..169e8614 100644 --- a/libs/main/containers/pideque.h +++ b/libs/main/containers/pideque.h @@ -53,7 +53,7 @@ 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) { + 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); } @@ -175,6 +175,19 @@ public: inline size_t _start() const {return pid_start;} inline bool isEmpty() const {return (pid_size == 0);} inline bool isNotEmpty() const {return (pid_size > 0);} + inline bool any(std::function test) const { + for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) { + if (test(pid_data[i])) return true; + } + return false; + } + inline bool every(std::function test) const { + for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) { + if (!test(pid_data[i])) return false; + } + return true; + } + 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];} @@ -183,54 +196,87 @@ public: inline const T & back() const {return pid_data[pid_start + pid_size - 1];} inline T & front() {return pid_data[pid_start];} inline const T & front() const {return pid_data[pid_start];} - inline bool operator ==(const PIDeque & t) const { - if (pid_size != t.pid_size) return false; + inline bool operator ==(const PIDeque & v) const { + if (pid_size != v.pid_size) return false; for (size_t i = 0; i < pid_size; ++i) { - if (t[i] != (*this)[i]) { + if (v[i] != (*this)[i]) { return false; } } return true; } - inline bool operator !=(const PIDeque & t) const {return !(*this == t);} - inline bool operator <(const PIDeque & t) const { - if (pid_size != t.pid_size) return pid_size < t.pid_size; + inline bool operator !=(const PIDeque & v) const {return !(*this == v);} + inline bool operator <(const PIDeque & v) const { + if (pid_size != v.pid_size) return pid_size < v.pid_size; for (size_t i = 0; i < pid_size; ++i) { - if ((*this)[i] != t[i]) return (*this)[i] < t[i]; + if ((*this)[i] != v[i]) return (*this)[i] < v[i]; } return false; } - inline bool operator >(const PIDeque & t) const { - if (pid_size != t.pid_size) return pid_size > t.pid_size; + inline bool operator >(const PIDeque & v) const { + if (pid_size != v.pid_size) return pid_size > v.pid_size; for (size_t i = 0; i < pid_size; ++i) { - if ((*this)[i] != t[i]) return (*this)[i] > t[i]; + if ((*this)[i] != v[i]) return (*this)[i] > v[i]; } return false; } - inline bool contains(const T & v) const { - for (size_t i = pid_start; i < pid_start + pid_size; ++i) { - if (v == pid_data[i]) { + inline bool contains(const T & e) const { + for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) { + if (e == pid_data[i]) { return true; } } return false; } - inline int etries(const T & v) const { + inline int etries(const T & e, size_t start = 0) const { int ec = 0; - for (size_t i = pid_start; i < pid_start + pid_size; ++i) { - if (v == pid_data[i]) ++ec; + if (start >= pid_size) return ec; + for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) { + if (e == pid_data[i]) ++ec; } return ec; } - inline ssize_t indexOf(const T & v) const { - for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) - if (v == pid_data[i]) + inline int etries(std::function test, size_t start = 0) const { + int ec = 0; + if (start >= pid_size) return ec; + for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) { + if (test(pid_data[i])) ++ec; + } + return ec; + } + inline ssize_t indexOf(const T & e, size_t start = 0) const { + if (start >= pid_size) return -1; + for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) { + if (e == pid_data[i]) { return i - pid_start; + } + } return -1; } - inline ssize_t lastIndexOf(const T & v) const { - for (ssize_t i = pid_start + (ssize_t)pid_size - 1; i >= pid_start; --i) { - if (v == pid_data[i]) { + inline ssize_t indexWhere(std::function test, size_t start = 0) const { + if (start >= pid_size) return -1; + for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) { + if (test(pid_data[i])) { + return i - pid_start; + } + } + return -1; + } + inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const { + if (start < 0) start = pid_size - 1; + else start = piMin(pid_size - 1, start); + for (ssize_t i = pid_start + start; i >= pid_start; --i) { + if (e == pid_data[i]) { + return i - pid_start; + } + } + return -1; + } + inline ssize_t lastIndexWhere(std::function test, ssize_t start = -1) const { + if (start < 0) start = pid_size - 1; + else start = piMin(pid_size - 1, start); + for (ssize_t i = pid_start + start; i >= pid_start; --i) { + if (test(pid_data[i])) { return i - pid_start; } } @@ -240,6 +286,12 @@ public: inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);} inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);} + PIDeque getRange(size_t index, size_t count) const { + if (index >= pid_size || count == 0) return PIDeque(); + if (index + count > pid_size) count = pid_size - index; + return PIDeque(&(pid_data[pid_start + index]), count); + } + template::value , int>::type = 0> @@ -265,7 +317,7 @@ public: } return *this; } - inline PIDeque & fill(std::function f) { + 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) { @@ -307,7 +359,7 @@ public: } return *this; } - inline PIDeque & resize(size_t new_size, std::function f) { + 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; @@ -348,8 +400,8 @@ public: return *this; } - inline PIDeque & insert(size_t index, const T & v = T()) { - if (index == pid_size) return push_back(v); + inline PIDeque & insert(size_t index, const T & e = T()) { + if (index == pid_size) return push_back(e); PIINTROSPECTION_CONTAINER_USED(T, 1) bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false); if (dir) { @@ -364,11 +416,11 @@ public: 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, e); return *this; } - inline PIDeque & insert(size_t index, T && v) { - if (index == pid_size) return push_back(v); + inline PIDeque & insert(size_t index, T && e) { + if (index == pid_size) return push_back(e); PIINTROSPECTION_CONTAINER_USED(T, 1) bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false); if (dir) { @@ -383,7 +435,7 @@ public: 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(e)); return *this; } inline PIDeque & insert(size_t index, const PIDeque & other) { @@ -449,18 +501,27 @@ public: return *this; } - inline PIDeque & removeOne(const T & v) { + inline PIDeque & removeOne(const T & e) { for (size_t i = 0; i < pid_size; ++i) { - if (pid_data[i + pid_start] == v) { + if (pid_data[i + pid_start] == e) { remove(i); return *this; } } return *this; } - inline PIDeque & removeAll(const T & v) { + inline PIDeque & removeAll(const T & e) { for (ssize_t i = 0; i < ssize_t(pid_size); ++i) { - if (pid_data[i + pid_start] == v) { + if (pid_data[i + pid_start] == e) { + remove(i); + --i; + } + } + return *this; + } + inline PIDeque & removeWhere(std::function test) { + for (ssize_t i = 0; i < ssize_t(pid_size); ++i) { + if (test(pid_data[i + pid_start])) { remove(i); --i; } @@ -468,77 +529,88 @@ public: return *this; } - inline PIDeque & push_back(const T & v) { + inline PIDeque & push_back(const T & e) { alloc(pid_size + 1, true); PIINTROSPECTION_CONTAINER_USED(T, 1); - elementNew(pid_data + pid_start + pid_size - 1, v); + elementNew(pid_data + pid_start + pid_size - 1, e); return *this; } - inline PIDeque & push_back(T && v) { + inline PIDeque & push_back(T && e) { alloc(pid_size + 1, true); PIINTROSPECTION_CONTAINER_USED(T, 1); - elementNew(pid_data + pid_start + pid_size - 1, std::move(v)); + elementNew(pid_data + pid_start + pid_size - 1, std::move(e)); return *this; } - inline PIDeque & append(const T & v) {return push_back(v);} - inline PIDeque & append(T && v) {return push_back(std::move(v));} - inline PIDeque & append(const PIDeque & t) { - assert(&t != this); + inline PIDeque & append(const T & e) {return push_back(e);} + inline PIDeque & append(T && e) {return push_back(std::move(e));} + inline PIDeque & append(const PIDeque & v) { + assert(&v != this); size_t ps = pid_size; - alloc(pid_size + t.pid_size, true); - newT(pid_data + ps + pid_start, t.pid_data + t.pid_start, t.pid_size); + alloc(pid_size + v.pid_size, true); + newT(pid_data + ps + pid_start, v.pid_data + v.pid_start, v.pid_size); return *this; } - inline PIDeque & operator <<(const T & v) {return push_back(v);} - inline PIDeque & operator <<(T && v) {return push_back(std::move(v));} - inline PIDeque & operator <<(const PIDeque & t) {return append(t);} + inline PIDeque & operator <<(const T & e) {return push_back(e);} + inline PIDeque & operator <<(T && e) {return push_back(std::move(e));} + inline PIDeque & operator <<(const PIDeque & v) {return append(v);} - inline PIDeque & push_front(const T & v) {insert(0, v); return *this;} - inline PIDeque & push_front(T && v) {insert(0, std::move(v)); return *this;} - inline PIDeque & prepend(const T & v) {return push_front(v);} - inline PIDeque & prepend(T && v) {return push_front(std::move(v));} + inline PIDeque & push_front(const T & e) {insert(0, e); return *this;} + inline PIDeque & push_front(T && e) {insert(0, std::move(e)); return *this;} + inline PIDeque & prepend(const T & e) {return push_front(e);} + inline PIDeque & prepend(T && e) {return push_front(std::move(e));} inline PIDeque & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;} inline PIDeque & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;} - inline T take_back() {T t(back()); pop_back(); return t;} - inline T take_front() {T t(front()); pop_front(); return t;} + inline T take_back() {T e(back()); pop_back(); return e;} + inline T take_front() {T e(front()); pop_front(); return e;} template PIDeque toType() const { PIDeque ret(pid_size); - for (uint i = 0; i < pid_size; ++i) { + for (size_t i = 0; i < pid_size; ++i) { ret[i] = ST(pid_data[i + pid_start]); } return ret; } - const PIDeque & forEach(std::function f) const { - for (uint i = 0; i < pid_size; ++i) { + const PIDeque & forEach(std::function f) const { + for (size_t i = 0; i < pid_size; ++i) { f(pid_data[i + pid_start]); } return *this; } - PIDeque copyForEach(std::function f) const { + PIDeque copyForEach(std::function f) const { PIDeque ret; ret.reserve(pid_size); - for (uint i = 0; i < pid_size; ++i) { + for (size_t i = 0; i < pid_size; ++i) { ret << f(pid_data[i + pid_start]); } return ret; } - PIDeque & forEachInplace(std::function f) { - for (uint i = 0; i < pid_size; ++i) + PIDeque & forEachInplace(std::function f) { + for (size_t i = 0; i < pid_size; ++i) pid_data[i + pid_start] = f(pid_data[i + pid_start]); return *this; } template - PIDeque toType(std::function f) const { + PIDeque map(std::function f) const { PIDeque ret; ret.reserve(pid_size); - for (uint i = 0; i < pid_size; ++i) { + for (size_t i = 0; i < pid_size; ++i) { ret << f(pid_data[i + pid_start]); } return ret; } + template + PIDeque toType(std::function f) const {return map(f);} + + template + ST reduce(std::function f, const ST & initial = ST()) const { + ST ret(initial); + for (size_t i = 0; i < pid_size; ++i) { + ret = f(pid_data[i + pid_start], ret); + } + return ret; + } inline PIDeque> reshape(size_t rows, size_t cols, int order = byRow) const { PIDeque> ret; diff --git a/libs/main/containers/pivector.h b/libs/main/containers/pivector.h index d62989a0..6d9a664a 100644 --- a/libs/main/containers/pivector.h +++ b/libs/main/containers/pivector.h @@ -175,14 +175,14 @@ public: inline size_t capacity() const {return piv_rsize;} inline bool isEmpty() const {return (piv_size == 0);} inline bool isNotEmpty() const {return (piv_size > 0);} - inline bool any(std::function test) const { - for (uint i = 0; i < piv_size; ++i) { + inline bool any(std::function test) const { + for (size_t i = 0; i < piv_size; ++i) { if (test(piv_data[i])) return true; } return false; } - inline bool every(std::function test) const { - for (uint i = 0; i < piv_size; ++i) { + inline bool every(std::function test) const { + for (size_t i = 0; i < piv_size; ++i) { if (!test(piv_data[i])) return false; } return true; @@ -231,6 +231,7 @@ public: } inline int etries(const T & e, size_t start = 0) const { int ec = 0; + if (start >= piv_size) return ec; for (size_t i = start; i < piv_size; ++i) { if (e == piv_data[i]) ++ec; } @@ -238,12 +239,14 @@ public: } inline int etries(std::function test, size_t start = 0) const { int ec = 0; + if (start >= piv_size) return ec; 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 { + if (start >= piv_size) return -1; for (size_t i = start; i < piv_size; ++i) { if (e == piv_data[i]) { return i; @@ -252,6 +255,7 @@ public: return -1; } inline ssize_t indexWhere(std::function test, size_t start = 0) const { + if (start >= piv_size) return -1; for (size_t i = start; i < piv_size; ++i) { if (test(piv_data[i])) { return i; @@ -530,33 +534,33 @@ public: return *this; } - inline T take_back() {T t(back()); pop_back(); return t;} - inline T take_front() {T t(front()); pop_front(); return t;} + inline T take_back() {T e(back()); pop_back(); return e;} + inline T take_front() {T e(front()); pop_front(); return e;} template PIVector toType() const { PIVector ret(piv_size); - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { ret[i] = ST(piv_data[i]); } return ret; } const PIVector & forEach(std::function f) const { - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { f(piv_data[i]); } return *this; } PIVector copyForEach(std::function f) const { PIVector ret; ret.reserve(piv_size); - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { ret << f(piv_data[i]); } return ret; } PIVector & forEachInplace(std::function f) { - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { piv_data[i] = f(piv_data[i]); } return *this; @@ -565,7 +569,7 @@ public: template PIVector map(std::function f) const { PIVector ret; ret.reserve(piv_size); - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { ret << f(piv_data[i]); } return ret; @@ -576,7 +580,7 @@ public: template ST reduce(std::function f, const ST & initial = ST()) const { ST ret(initial); - for (uint i = 0; i < piv_size; ++i) { + for (size_t i = 0; i < piv_size; ++i) { ret = f(piv_data[i], ret); } return ret; diff --git a/main.cpp b/main.cpp index 8cf6599e..1ed2e829 100644 --- a/main.cpp +++ b/main.cpp @@ -12,10 +12,30 @@ int main(int argc, char * argv[]) { piCout << x.indexOf(4, -1); piCout << x.lastIndexOf(1, 0); piCout << x.lastIndexWhere([](int v) {return v % 8 == 0;}); - PIVector x2 = x.map([](int v) {return v / 10;}); + PIVector x2 = x.map([](int v) {return v / 10.0;}); piCout << x2; piCout << x.reduce([](int v, PIString s){return s + PIString::fromNumber(v);}); + piCout << x.removeWhere([](int v){return v % 2 == 0;}); + piCout << x.getRange(8, 1); + piCout << x.getRange(8, 100); + piCout << "====================="; + + PIDeque y(20, [](int i) {return i;}); + piCout << y; + piCout << y.any([](int v) {return v == 10;}); + piCout << y.every([](int v) {return v > 0;}); + piCout << y.etries([](int v) {return v % 5 == 0;}); + piCout << y.indexWhere([](int v) {return v % 8 == 0;}); + piCout << y.indexOf(4, -1); + piCout << y.lastIndexOf(1, 0); + piCout << y.lastIndexWhere([](int v) {return v % 8 == 0;}); + PIDeque y2 = y.map([](int v) {return v / 10.0;}); + piCout << y2; + piCout << y.reduce([](int v, PIString s){return s + PIString::fromNumber(v);}); + piCout << y.removeWhere([](int v){return v % 2 == 0;}); + piCout << y.getRange(8, 1); + piCout << y.getRange(8, 100); return 0; // TODO: PIByteArray rnd;