diff --git a/src/utils/Table.hpp b/src/utils/Table.hpp index 5f621ab2719e93ea63d3be610818aab1cb164665..cd380661b5b59d33f20812f969f9df7b93cd5a73 100644 --- a/src/utils/Table.hpp +++ b/src/utils/Table.hpp @@ -9,6 +9,8 @@ #include <Kokkos_CopyViews.hpp> +#include <iostream> + template <typename DataType> class [[nodiscard]] Table { @@ -126,6 +128,18 @@ class [[nodiscard]] Table #endif // NDEBUG } + friend std::ostream& operator<<(std::ostream& os, const Table& t) + { + for (size_t i = 0; i < t.numberOfRows(); ++i) { + os << i << '|'; + for (size_t j = 0; j < t.numberOfColumns(); ++j) { + os << ' ' << j << ':' << NaNHelper(t(i, j)); + } + os << '\n'; + } + return os; + } + PUGS_INLINE Table() = default; diff --git a/tests/test_Table.cpp b/tests/test_Table.cpp index 5372c697dc8d8bde1e2039141a8d8e226e7a68d3..a89344b75262a2eb3322589b613d6add8ae5764e 100644 --- a/tests/test_Table.cpp +++ b/tests/test_Table.cpp @@ -158,27 +158,62 @@ TEST_CASE("Table", "[utils]") SECTION("checking for Kokkos::View encaspulation") { - { - Kokkos::View<double**> kokkos_view("anonymous", 10, 3); - for (size_t i = 0; i < 10; ++i) { - for (size_t j = 0; j < 3; ++j) { - kokkos_view(i, j) = 3 * i + j; - } + Kokkos::View<double**> kokkos_view("anonymous", 10, 3); + for (size_t i = 0; i < 10; ++i) { + for (size_t j = 0; j < 3; ++j) { + kokkos_view(i, j) = 3 * i + j; } + } - Table table = encapsulate(kokkos_view); + Table table = encapsulate(kokkos_view); - REQUIRE(table.numberOfRows() == kokkos_view.extent(0)); - REQUIRE(table.numberOfColumns() == kokkos_view.extent(1)); - for (size_t i = 0; i < table.numberOfRows(); ++i) { - for (size_t j = 0; j < table.numberOfColumns(); ++j) { - REQUIRE(&table(i, j) == &kokkos_view(i, j)); - } + REQUIRE(table.numberOfRows() == kokkos_view.extent(0)); + REQUIRE(table.numberOfColumns() == kokkos_view.extent(1)); + for (size_t i = 0; i < table.numberOfRows(); ++i) { + for (size_t j = 0; j < table.numberOfColumns(); ++j) { + REQUIRE(&table(i, j) == &kokkos_view(i, j)); } } } + SECTION("output") + { + Table<double> table(3, 2); + table(0, 0) = 1; + table(0, 1) = 3; + table(1, 0) = 7; + table(1, 1) = -2; + table(2, 0) = 4; + table(2, 1) = -5; + std::ostringstream table_ost; + table_ost << table; + + std::ostringstream ref_ost; + ref_ost << "0| " << 0 << ':' << 1. << ' ' << 1 << ':' << 3. << '\n'; + ref_ost << "1| " << 0 << ':' << 7. << ' ' << 1 << ':' << -2. << '\n'; + ref_ost << "2| " << 0 << ':' << 4. << ' ' << 1 << ':' << -5. << '\n'; + + REQUIRE(table_ost.str() == ref_ost.str()); + } + #ifndef NDEBUG + SECTION("output with signaling NaN") + { + Table<double> table(3, 2); + table(0, 0) = 1; + table(1, 1) = -2; + table(2, 1) = -5; + std::ostringstream table_ost; + table_ost << table; + + std::ostringstream ref_ost; + ref_ost << "0| " << 0 << ':' << 1. << ' ' << 1 << ":nan\n"; + ref_ost << "1| " << 0 << ":nan " << 1 << ':' << -2. << '\n'; + ref_ost << "2| " << 0 << ":nan " << 1 << ':' << -5. << '\n'; + + REQUIRE(table_ost.str() == ref_ost.str()); + } + SECTION("checking for bounds violation") { REQUIRE_THROWS_AS(a(4, 0), AssertError);