From 94b47e42bc0621dc1bd85cb2b7177037b40b4f78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Thu, 17 Feb 2022 23:55:57 +0100
Subject: [PATCH] Support for output of ItemValue and ItemArray on ostream

- Beware that this only prints values on the printing processor in
parallel (rank 0 processor by now).

- Could also have added SubItem{Value,Array}PerItem outputs and
DiscreteFunctionP0, but it remains unclear to me if this development
is really relevant, due to the parallel defect of this
functionality. In the case of DiscreteFunctionP0, one can use the
DiscreteFunctionP0::cellValues() function to print values.
---
 src/mesh/ItemArray.hpp   |  7 +++++++
 src/mesh/ItemValue.hpp   |  7 +++++++
 tests/test_ItemArray.cpp | 21 +++++++++++++++++++++
 tests/test_ItemValue.cpp | 19 +++++++++++++++++++
 4 files changed, 54 insertions(+)

diff --git a/src/mesh/ItemArray.hpp b/src/mesh/ItemArray.hpp
index 3bd7de633..0033bb24e 100644
--- a/src/mesh/ItemArray.hpp
+++ b/src/mesh/ItemArray.hpp
@@ -171,6 +171,13 @@ class ItemArray
     return *this;
   }
 
+  friend std::ostream&
+  operator<<(std::ostream& os, const ItemArray& item_array)
+  {
+    os << item_array.m_values;
+    return os;
+  }
+
   template <typename DataType2, typename ConnectivityPtr2>
   PUGS_INLINE
   ItemArray(const ItemArray<DataType2, item_type, ConnectivityPtr2>& array_per_item) noexcept
diff --git a/src/mesh/ItemValue.hpp b/src/mesh/ItemValue.hpp
index 981ebcc19..1b888e704 100644
--- a/src/mesh/ItemValue.hpp
+++ b/src/mesh/ItemValue.hpp
@@ -159,6 +159,13 @@ class ItemValue
     return *this;
   }
 
+  friend std::ostream&
+  operator<<(std::ostream& os, const ItemValue& item_value)
+  {
+    os << item_value.m_values;
+    return os;
+  }
+
   template <typename DataType2, typename ConnectivityPtr2>
   PUGS_INLINE
   ItemValue(const ItemValue<DataType2, item_type, ConnectivityPtr2>& value_per_item) noexcept
diff --git a/tests/test_ItemArray.cpp b/tests/test_ItemArray.cpp
index 9b3b95fde..cf59acf90 100644
--- a/tests/test_ItemArray.cpp
+++ b/tests/test_ItemArray.cpp
@@ -271,6 +271,27 @@ TEST_CASE("ItemArray", "[mesh]")
     }
   }
 
+  SECTION("output")
+  {
+    auto mesh = MeshDataBaseForTests::get().unordered1DMesh();
+
+    Table<int> table{mesh->numberOfCells(), 3};
+    for (size_t i = 0; i < table.numberOfRows(); ++i) {
+      for (size_t j = 0; j < table.numberOfColumns(); ++j) {
+        table(i, j) = 2 * i + 1 + 3 * j;
+      }
+    }
+
+    CellArray<int> cell_array{mesh->connectivity(), 3};
+    cell_array = table;
+
+    std::ostringstream table_ost;
+    table_ost << table;
+    std::ostringstream cell_array_ost;
+    cell_array_ost << cell_array;
+    REQUIRE(table_ost.str() == cell_array_ost.str());
+  }
+
 #ifndef NDEBUG
   SECTION("error")
   {
diff --git a/tests/test_ItemValue.cpp b/tests/test_ItemValue.cpp
index 5ec3fdb89..fcea42470 100644
--- a/tests/test_ItemValue.cpp
+++ b/tests/test_ItemValue.cpp
@@ -218,6 +218,25 @@ TEST_CASE("ItemValue", "[mesh]")
     }
   }
 
+  SECTION("output")
+  {
+    auto mesh = MeshDataBaseForTests::get().unordered1DMesh();
+
+    Array<int> array{mesh->numberOfCells()};
+    for (size_t i = 0; i < array.size(); ++i) {
+      array[i] = 2 * i + 1;
+    }
+
+    CellValue<int> cell_value{mesh->connectivity()};
+    cell_value = array;
+
+    std::ostringstream array_ost;
+    array_ost << array;
+    std::ostringstream cell_value_ost;
+    cell_value_ost << cell_value;
+    REQUIRE(array_ost.str() == cell_value_ost.str());
+  }
+
 #ifndef NDEBUG
   SECTION("error")
   {
-- 
GitLab