PIVector2D - add funcs, optimize, tests, fixes, doxygen #194

Merged
andrey merged 29 commits from vibecoding_pivector2d into master 2026-02-27 23:58:45 +03:00
2 changed files with 489 additions and 4 deletions
Showing only changes of commit 97c14870c0 - Show all commits

View File

@@ -193,7 +193,6 @@ public:
//! \~russian Преобразует строку в \a PIVector. //! \~russian Преобразует строку в \a PIVector.
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); } inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
// --- Поиск в строке ---
inline ssize_t indexOf(const T & e, ssize_t start = 0) const { inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -201,6 +200,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const { inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -208,6 +208,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const { inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -215,6 +216,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const { inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -222,6 +224,74 @@ public:
} }
return -1; return -1;
} }
//! \~english Applies a function to each element of the row (modifiable).
//! \~russian Применяет функцию к каждому элементу строки (с возможностью изменения).
inline void forEach(std::function<void(T &)> func) {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[st_ + i]);
}
}
//! \~english Applies a function to each element of the row (read-only).
//! \~russian Применяет функцию к каждому элементу строки (только чтение).
inline void forEach(std::function<void(const T &)> func) const {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[st_ + i]);
}
}
//! \~english Fills the row with copies of `value`.
//! \~russian Заполняет строку копиями `value`.
inline void fill(const T & value) {
for (size_t i = 0; i < sz_; ++i) {
(*p_)[st_ + i] = value;
}
}
//! \~english Checks if the row contains the element `e`.
//! \~russian Проверяет, содержит ли строка элемент `e`.
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the row.
//! \~russian Подсчитывает количество вхождений `e` в строке.
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if ((*p_)[st_ + i] == e) ++count;
}
return count;
}
//! \~english Counts elements in the row that pass the `test`.
//! \~russian Подсчитывает элементы в строке, проходящие `test`.
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if (test((*p_)[st_ + i])) ++count;
}
return count;
}
//! \~english Tests if any element in the row passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`.
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (test((*p_)[st_ + i])) return true;
}
return false;
}
//! \~english Tests if all elements in the row pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в строке `test`.
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (!test((*p_)[st_ + i])) return false;
}
return true;
}
}; };
//! \class Col //! \class Col
@@ -290,7 +360,6 @@ public:
return ret; return ret;
} }
// --- Поиск в столбце ---
inline ssize_t indexOf(const T & e, ssize_t start = 0) const { inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -298,6 +367,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const { inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -305,6 +375,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const { inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -312,6 +383,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const { inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -319,6 +391,74 @@ public:
} }
return -1; return -1;
} }
//! \~english Applies a function to each element of the column (modifiable).
//! \~russian Применяет функцию к каждому элементу столбца (с возможностью изменения).
inline void forEach(std::function<void(T &)> func) {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[i * step_ + col_]);
}
}
//! \~english Applies a function to each element of the column (read-only).
//! \~russian Применяет функцию к каждому элементу столбца (только чтение).
inline void forEach(std::function<void(const T &)> func) const {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[i * step_ + col_]);
}
}
//! \~english Fills the column with copies of `value`.
//! \~russian Заполняет столбец копиями `value`.
inline void fill(const T & value) {
for (size_t i = 0; i < sz_; ++i) {
(*p_)[i * step_ + col_] = value;
}
}
//! \~english Checks if the column contains the element `e`.
//! \~russian Проверяет, содержит ли столбец элемент `e`.
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the column.
//! \~russian Подсчитывает количество вхождений `e` в столбце.
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if ((*p_)[i * step_ + col_] == e) ++count;
}
return count;
}
//! \~english Counts elements in the column that pass the `test`.
//! \~russian Подсчитывает элементы в столбце, проходящие `test`.
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if (test((*p_)[i * step_ + col_])) ++count;
}
return count;
}
//! \~english Tests if any element in the column passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`.
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (test((*p_)[i * step_ + col_])) return true;
}
return false;
}
//! \~english Tests if all elements in the column pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в столбце `test`.
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (!test((*p_)[i * step_ + col_])) return false;
}
return true;
}
}; };
//! \class RowConst //! \class RowConst
@@ -353,7 +493,6 @@ public:
//! \~russian Преобразует строку в \a PIVector. //! \~russian Преобразует строку в \a PIVector.
inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); } inline PIVector<T> toVector() const { return PIVector<T>(p_->data(st_), sz_); }
// --- Поиск в строке (только чтение) ---
inline ssize_t indexOf(const T & e, ssize_t start = 0) const { inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -361,6 +500,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const { inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -368,6 +508,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const { inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -375,6 +516,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const { inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -382,6 +524,58 @@ public:
} }
return -1; return -1;
} }
//! \~english Applies a function to each element of the row (read-only).
//! \~russian Применяет функцию к каждому элементу строки (только чтение).
inline void forEach(std::function<void(const T &)> func) const {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[st_ + i]);
}
}
//! \~english Checks if the row contains the element `e`.
//! \~russian Проверяет, содержит ли строка элемент `e`.
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the row.
//! \~russian Подсчитывает количество вхождений `e` в строке.
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if ((*p_)[st_ + i] == e) ++count;
}
return count;
}
//! \~english Counts elements in the row that pass the `test`.
//! \~russian Подсчитывает элементы в строке, проходящие `test`.
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if (test((*p_)[st_ + i])) ++count;
}
return count;
}
//! \~english Tests if any element in the row passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в строке `test`.
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (test((*p_)[st_ + i])) return true;
}
return false;
}
//! \~english Tests if all elements in the row pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в строке `test`.
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (!test((*p_)[st_ + i])) return false;
}
return true;
}
}; };
//! \class ColConst //! \class ColConst
@@ -423,7 +617,6 @@ public:
return ret; return ret;
} }
// --- Поиск в столбце (только чтение) ---
inline ssize_t indexOf(const T & e, ssize_t start = 0) const { inline ssize_t indexOf(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -431,6 +624,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const { inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -438,6 +632,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const { inline ssize_t indexWhere(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0; if (start < 0) start = 0;
for (size_t i = (size_t)start; i < sz_; ++i) { for (size_t i = (size_t)start; i < sz_; ++i) {
@@ -445,6 +640,7 @@ public:
} }
return -1; return -1;
} }
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const { inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start; ssize_t from = (start < 0 || (size_t)start >= sz_) ? (ssize_t)sz_ - 1 : start;
for (ssize_t i = from; i >= 0; --i) { for (ssize_t i = from; i >= 0; --i) {
@@ -452,6 +648,58 @@ public:
} }
return -1; return -1;
} }
//! \~english Applies a function to each element of the column (read-only).
//! \~russian Применяет функцию к каждому элементу столбца (только чтение).
inline void forEach(std::function<void(const T &)> func) const {
for (size_t i = 0; i < sz_; ++i) {
func((*p_)[i * step_ + col_]);
}
}
//! \~english Checks if the column contains the element `e`.
//! \~russian Проверяет, содержит ли столбец элемент `e`.
inline bool contains(const T & e, ssize_t start = 0) const { return indexOf(e, start) != -1; }
//! \~english Counts occurrences of `e` in the column.
//! \~russian Подсчитывает количество вхождений `e` в столбце.
inline int entries(const T & e, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if ((*p_)[i * step_ + col_] == e) ++count;
}
return count;
}
//! \~english Counts elements in the column that pass the `test`.
//! \~russian Подсчитывает элементы в столбце, проходящие `test`.
inline int entries(std::function<bool(const T & e)> test, ssize_t start = 0) const {
if (start < 0) start = 0;
int count = 0;
for (size_t i = (size_t)start; i < sz_; ++i) {
if (test((*p_)[i * step_ + col_])) ++count;
}
return count;
}
//! \~english Tests if any element in the column passes the `test`.
//! \~russian Проверяет, проходит ли какой-либо элемент в столбце `test`.
inline bool any(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (test((*p_)[i * step_ + col_])) return true;
}
return false;
}
//! \~english Tests if all elements in the column pass the `test`.
//! \~russian Проверяет, проходят ли все элементы в столбце `test`.
inline bool every(std::function<bool(const T & e)> test) const {
for (size_t i = 0; i < sz_; ++i) {
if (!test((*p_)[i * step_ + col_])) return false;
}
return true;
}
}; };
//! \~english Returns a reference to the element at the given row and column. //! \~english Returns a reference to the element at the given row and column.

View File

@@ -993,6 +993,243 @@ TEST(Vector2DEdgeTest, single_element_vector) {
EXPECT_EQ(single.element(0, 0), 42); EXPECT_EQ(single.element(0, 0), 42);
} }
// ==================== PROXY ADDITIONAL OPERATIONS TESTS ====================
TEST_F(Vector2DTest, row_proxy_forEach_modifies_elements) {
auto row = vec[5];
row.forEach([](int & e) { e += 100; });
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
EXPECT_EQ(vec.element(5, c), 5 * COLS_COUNT_INIT + c + 100);
}
}
TEST_F(Vector2DTest, row_proxy_forEach_const_iterates) {
const auto & constVec = vec;
auto row = constVec[5];
size_t count = 0;
row.forEach([&count](const int &) { ++count; });
EXPECT_EQ(count, COLS_COUNT_INIT);
}
TEST_F(Vector2DTest, row_proxy_fill_sets_all_elements) {
auto row = vec[12];
row.fill(999);
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
EXPECT_EQ(vec.element(12, c), 999);
}
}
TEST_F(Vector2DTest, row_proxy_contains_finds_element) {
auto row = vec[8];
EXPECT_TRUE(row.contains(vec.element(8, 10)));
EXPECT_FALSE(row.contains(-999));
}
TEST_F(Vector2DTest, row_proxy_entries_counts_occurrences) {
auto row = vec[15];
// Add a duplicate
int val = vec.element(15, 5);
vec.element(15, 20) = val;
EXPECT_EQ(row.entries(val), 2);
EXPECT_EQ(row.entries(-999), 0);
}
TEST_F(Vector2DTest, row_proxy_entries_with_predicate_counts_matches) {
auto row = vec[20];
auto isEven = [](const int & e) { return e % 2 == 0; };
int expected = 0;
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
if (row[c] % 2 == 0) ++expected;
}
EXPECT_EQ(row.entries(isEven), expected);
}
TEST_F(Vector2DTest, row_proxy_any_returns_true_if_any_match) {
auto row = vec[25];
auto isNegative = [](const int & e) { return e < 0; };
EXPECT_FALSE(row.any(isNegative));
auto isPositive = [](const int & e) { return e >= 0; };
EXPECT_TRUE(row.any(isPositive));
}
TEST_F(Vector2DTest, row_proxy_every_returns_true_if_all_match) {
auto row = vec[30];
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
EXPECT_TRUE(row.every(isLessThanMax));
auto isEven = [](const int & e) { return e % 2 == 0; };
EXPECT_FALSE(row.every(isEven));
}
// ----------------------------------------------------------------------------
TEST_F(Vector2DTest, col_proxy_forEach_modifies_elements) {
auto col = vec.col(7);
col.forEach([](int & e) { e += 50; });
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
EXPECT_EQ(vec.element(r, 7), r * COLS_COUNT_INIT + 7 + 50);
}
}
TEST_F(Vector2DTest, col_proxy_forEach_const_iterates) {
const auto & constVec = vec;
auto col = constVec.col(9);
size_t count = 0;
col.forEach([&count](const int &) { ++count; });
EXPECT_EQ(count, ROWS_COUNT_INIT);
}
TEST_F(Vector2DTest, col_proxy_fill_sets_all_elements) {
auto col = vec.col(11);
col.fill(777);
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
EXPECT_EQ(vec.element(r, 11), 777);
}
}
TEST_F(Vector2DTest, col_proxy_contains_finds_element) {
auto col = vec.col(13);
EXPECT_TRUE(col.contains(vec.element(5, 13)));
EXPECT_FALSE(col.contains(-999));
}
TEST_F(Vector2DTest, col_proxy_entries_counts_occurrences) {
auto col = vec.col(17);
int val = vec.element(3, 17);
vec.element(22, 17) = val; // duplicate
EXPECT_EQ(col.entries(val), 2);
EXPECT_EQ(col.entries(-999), 0);
}
TEST_F(Vector2DTest, col_proxy_entries_with_predicate_counts_matches) {
auto col = vec.col(19);
auto isOdd = [](const int & e) { return e % 2 != 0; };
int expected = 0;
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
if (col[r] % 2 != 0) ++expected;
}
EXPECT_EQ(col.entries(isOdd), expected);
}
TEST_F(Vector2DTest, col_proxy_any_returns_true_if_any_match) {
auto col = vec.col(21);
auto isNegative = [](const int & e) { return e < 0; };
EXPECT_FALSE(col.any(isNegative));
auto isPositive = [](const int & e) { return e >= 0; };
EXPECT_TRUE(col.any(isPositive));
}
TEST_F(Vector2DTest, col_proxy_every_returns_true_if_all_match) {
auto col = vec.col(23);
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
EXPECT_TRUE(col.every(isLessThanMax));
auto isEven = [](const int & e) { return e % 2 == 0; };
EXPECT_FALSE(col.every(isEven));
}
// ----------------------------------------------------------------------------
TEST_F(Vector2DTest, rowconst_proxy_forEach_iterates) {
const auto & constVec = vec;
auto row = constVec[5];
size_t count = 0;
row.forEach([&count](const int &) { ++count; });
EXPECT_EQ(count, COLS_COUNT_INIT);
}
TEST_F(Vector2DTest, rowconst_proxy_contains_finds_element) {
const auto & constVec = vec;
auto row = constVec[6];
EXPECT_TRUE(row.contains(vec.element(6, 10)));
EXPECT_FALSE(row.contains(-999));
}
TEST_F(Vector2DTest, rowconst_proxy_entries_counts_occurrences) {
const auto & constVec = vec;
auto row = constVec[7];
int val = vec.element(7, 5);
// We can't modify through const proxy, but duplicates already exist from previous tests
EXPECT_GE(row.entries(val), 1); // at least one
}
TEST_F(Vector2DTest, rowconst_proxy_entries_with_predicate_counts_matches) {
const auto & constVec = vec;
auto row = constVec[9];
auto isEven = [](const int & e) { return e % 2 == 0; };
int expected = 0;
for (size_t c = 0; c < COLS_COUNT_INIT; ++c) {
if (vec.element(9, c) % 2 == 0) ++expected;
}
EXPECT_EQ(row.entries(isEven), expected);
}
TEST_F(Vector2DTest, rowconst_proxy_any_returns_true_if_any_match) {
const auto & constVec = vec;
auto row = constVec[10];
auto isNegative = [](const int & e) { return e < 0; };
EXPECT_FALSE(row.any(isNegative));
auto isPositive = [](const int & e) { return e >= 0; };
EXPECT_TRUE(row.any(isPositive));
}
TEST_F(Vector2DTest, rowconst_proxy_every_returns_true_if_all_match) {
const auto & constVec = vec;
auto row = constVec[11];
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
EXPECT_TRUE(row.every(isLessThanMax));
auto isEven = [](const int & e) { return e % 2 == 0; };
EXPECT_FALSE(row.every(isEven));
}
// ----------------------------------------------------------------------------
TEST_F(Vector2DTest, colconst_proxy_forEach_iterates) {
const auto & constVec = vec;
auto col = constVec.col(25);
size_t count = 0;
col.forEach([&count](const int &) { ++count; });
EXPECT_EQ(count, ROWS_COUNT_INIT);
}
TEST_F(Vector2DTest, colconst_proxy_contains_finds_element) {
const auto & constVec = vec;
auto col = constVec.col(27);
EXPECT_TRUE(col.contains(vec.element(4, 27)));
EXPECT_FALSE(col.contains(-999));
}
TEST_F(Vector2DTest, colconst_proxy_entries_counts_occurrences) {
const auto & constVec = vec;
auto col = constVec.col(29);
int val = vec.element(8, 29);
EXPECT_GE(col.entries(val), 1);
}
TEST_F(Vector2DTest, colconst_proxy_entries_with_predicate_counts_matches) {
const auto & constVec = vec;
auto col = constVec.col(31);
auto isOdd = [](const int & e) { return e % 2 != 0; };
int expected = 0;
for (size_t r = 0; r < ROWS_COUNT_INIT; ++r) {
if (vec.element(r, 31) % 2 != 0) ++expected;
}
EXPECT_EQ(col.entries(isOdd), expected);
}
TEST_F(Vector2DTest, colconst_proxy_any_returns_true_if_any_match) {
const auto & constVec = vec;
auto col = constVec.col(33);
auto isNegative = [](const int & e) { return e < 0; };
EXPECT_FALSE(col.any(isNegative));
auto isPositive = [](const int & e) { return e >= 0; };
EXPECT_TRUE(col.any(isPositive));
}
TEST_F(Vector2DTest, colconst_proxy_every_returns_true_if_all_match) {
const auto & constVec = vec;
auto col = constVec.col(0);
auto isLessThanMax = [&](const int & e) { return e < static_cast<int>(vec.size()); };
EXPECT_TRUE(col.every(isLessThanMax));
auto isNotEven = [](const int & e) { return e % 2 != 0; };
col.forEach([](const int & v) { piCout << v; });
EXPECT_FALSE(col.every(isNotEven));
}
// ==================== OUTPUT TESTS ==================== // ==================== OUTPUT TESTS ====================
TEST_F(Vector2DTest, picout_operator_works) { TEST_F(Vector2DTest, picout_operator_works) {
// Just test that it compiles and doesn't crash // Just test that it compiles and doesn't crash