From 377831ba660c6a016d6fd0e9095d8735ab885205 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Mon, 19 Apr 2021 18:06:12 +0200
Subject: [PATCH] Add copy_to utilities for ItemValue and ItemArray

---
 src/mesh/ItemArray.hpp   | 13 +++++++++++++
 src/mesh/ItemValue.hpp   | 13 +++++++++++++
 tests/test_ItemArray.cpp |  4 ++++
 tests/test_ItemValue.cpp | 13 +++++++++++++
 4 files changed, 43 insertions(+)

diff --git a/src/mesh/ItemArray.hpp b/src/mesh/ItemArray.hpp
index 78e5f8dd6..1a2b004c9 100644
--- a/src/mesh/ItemArray.hpp
+++ b/src/mesh/ItemArray.hpp
@@ -47,6 +47,19 @@ class ItemArray
     return image;
   }
 
+  template <typename ConnectivityPtr2>
+  friend PUGS_INLINE void copy_to(const ItemArray<std::add_const_t<DataType>, item_type, ConnectivityPtr>& source,
+                                  const ItemArray<DataType, item_type, ConnectivityPtr2>& destination);
+
+  template <typename ConnectivityPtr2>
+  friend PUGS_INLINE void
+  copy_to(const ItemArray<DataType, item_type, ConnectivityPtr>& source,
+          const ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr2>& destination)
+  {
+    Assert(destination.connectivity_ptr() == source.connectivity_ptr());
+    copy_to(source.m_values, destination.m_values);
+  }
+
   PUGS_INLINE
   bool
   isBuilt() const noexcept
diff --git a/src/mesh/ItemValue.hpp b/src/mesh/ItemValue.hpp
index 0f7fe6171..ebc5f4051 100644
--- a/src/mesh/ItemValue.hpp
+++ b/src/mesh/ItemValue.hpp
@@ -47,6 +47,19 @@ class ItemValue
     return image;
   }
 
+  template <typename ConnectivityPtr2>
+  friend PUGS_INLINE void copy_to(const ItemValue<std::add_const_t<DataType>, item_type, ConnectivityPtr>& source,
+                                  const ItemValue<DataType, item_type, ConnectivityPtr2>& destination);
+
+  template <typename ConnectivityPtr2>
+  friend PUGS_INLINE void
+  copy_to(const ItemValue<DataType, item_type, ConnectivityPtr>& source,
+          const ItemValue<std::remove_const_t<DataType>, item_type, ConnectivityPtr2>& destination)
+  {
+    Assert(destination.connectivity_ptr() == source.connectivity_ptr());
+    copy_to(source.m_values, destination.m_values);
+  }
+
   PUGS_INLINE
   bool
   isBuilt() const noexcept
diff --git a/tests/test_ItemArray.cpp b/tests/test_ItemArray.cpp
index 05cdb548a..2a7627532 100644
--- a/tests/test_ItemArray.cpp
+++ b/tests/test_ItemArray.cpp
@@ -169,11 +169,15 @@ TEST_CASE("ItemArray", "[mesh]")
     CellArray<const int> const_cell_array;
     const_cell_array = copy(cell_array);
 
+    CellArray<int> duplicated_cell_array{connectivity, cell_array.sizeOfArrays()};
+    copy_to(const_cell_array, duplicated_cell_array);
+
     cell_array.fill(0);
 
     REQUIRE(is_same(cell_array, 0));
     REQUIRE(is_same(cell_array_const_view, 0));
     REQUIRE(is_same(const_cell_array, static_cast<std::int64_t>(parallel::rank())));
+    REQUIRE(is_same(duplicated_cell_array, static_cast<std::int64_t>(parallel::rank())));
   }
 
   SECTION("WeakItemArray")
diff --git a/tests/test_ItemValue.cpp b/tests/test_ItemValue.cpp
index a4bc71047..1c4ab49fa 100644
--- a/tests/test_ItemValue.cpp
+++ b/tests/test_ItemValue.cpp
@@ -191,6 +191,19 @@ TEST_CASE("ItemValue", "[mesh]")
       Array<size_t> values{3 + cell_value.numberOfItems()};
       REQUIRE_THROWS_AS(cell_value = values, AssertError);
     }
+
+    SECTION("invalid copy_to")
+    {
+      const Mesh<Connectivity<2>>& mesh_2d   = *MeshDataBaseForTests::get().cartesianMesh2D();
+      const Connectivity<2>& connectivity_2d = mesh_2d.connectivity();
+
+      const Mesh<Connectivity<3>>& mesh_3d   = *MeshDataBaseForTests::get().cartesianMesh3D();
+      const Connectivity<3>& connectivity_3d = mesh_3d.connectivity();
+
+      CellValue<int> cell_2d_value{connectivity_2d};
+      CellValue<int> cell_3d_value{connectivity_3d};
+      REQUIRE_THROWS_AS(copy_to(cell_2d_value, cell_3d_value), AssertError);
+    }
   }
 #endif   // NDEBUG
 }
-- 
GitLab