From d6fc7ca79f109a6c2667e23c525faadf236016e5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Tue, 6 Apr 2021 15:07:36 +0200
Subject: [PATCH] Add bound checking assertions

Also add access to the connectivity pointer
---
 src/mesh/SubItemValuePerItem.hpp   |  14 +-
 tests/test_SubItemValuePerItem.cpp | 430 ++++++++++++++++++++---------
 2 files changed, 316 insertions(+), 128 deletions(-)

diff --git a/src/mesh/SubItemValuePerItem.hpp b/src/mesh/SubItemValuePerItem.hpp
index 170ffd76d..dedafdb9c 100644
--- a/src/mesh/SubItemValuePerItem.hpp
+++ b/src/mesh/SubItemValuePerItem.hpp
@@ -109,6 +109,17 @@ class SubItemValuePerItem
     return m_connectivity_ptr.use_count() != 0;
   }
 
+  PUGS_INLINE
+  std::shared_ptr<const IConnectivity>
+  connectivity_ptr() const noexcept
+  {
+    if constexpr (std::is_same_v<ConnectivityPtr, ConnectivitySharedPtr>) {
+      return m_connectivity_ptr;
+    } else {
+      return m_connectivity_ptr.lock();
+    }
+  }
+
   template <typename IndexType, typename SubIndexType>
   PUGS_FORCEINLINE DataType&
   operator()(IndexType item_id, SubIndexType i) const noexcept(NO_ASSERT)
@@ -128,7 +139,7 @@ class SubItemValuePerItem
   {
     static_assert(std::is_integral_v<ArrayIndexType>, "index must be an integral type");
     Assert(this->isBuilt());
-    Assert(i < m_values.size());
+    Assert(static_cast<size_t>(i) < m_values.size());
     return m_values[i];
   }
 
@@ -223,7 +234,6 @@ class SubItemValuePerItem
   {
     static_assert(not std::is_const_v<DataType>, "Cannot allocate SubItemValuePerItem of const data: only "
                                                  "view is supported");
-    ;
 
     ConnectivityMatrix connectivity_matrix = connectivity._getMatrix(item_type, sub_item_type);
 
diff --git a/tests/test_SubItemValuePerItem.cpp b/tests/test_SubItemValuePerItem.cpp
index b7549c444..15c070ddd 100644
--- a/tests/test_SubItemValuePerItem.cpp
+++ b/tests/test_SubItemValuePerItem.cpp
@@ -74,15 +74,24 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell));
 
         auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id));
-          REQUIRE(node_value_per_cell.itemValues(cell_id).size() == node_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &=
+              (cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id)) and
+              (node_value_per_cell.itemValues(cell_id).size() == node_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         const NodeValuePerCell<const int> const_node_value_per_cell = node_value_per_cell;
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(const_node_value_per_cell.itemValues(cell_id).size() ==
-                  node_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &=
+              (const_node_value_per_cell.itemValues(cell_id).size() == node_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         EdgeValuePerCell<int> edge_value_per_cell{connectivity};
@@ -90,8 +99,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell));
 
         auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerCell<int> face_value_per_cell{connectivity};
@@ -99,8 +112,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell));
 
         auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -111,8 +128,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face));
 
         auto face_to_cell_matrix = connectivity.faceToCellMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -123,8 +144,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge));
 
         auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -135,8 +160,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node));
 
         auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
       }
     }
@@ -153,8 +182,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell));
 
         auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         EdgeValuePerCell<int> edge_value_per_cell{connectivity};
@@ -162,8 +195,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell));
 
         auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerCell<int> face_value_per_cell{connectivity};
@@ -171,8 +208,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell));
 
         auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -183,8 +224,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face));
 
         auto face_to_cell_matrix = connectivity.faceToCellMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
 
         NodeValuePerFace<int> node_value_per_face{connectivity};
@@ -192,8 +237,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_face.numberOfValues() == number_of_values(node_value_per_face));
 
         auto face_to_node_matrix = connectivity.faceToNodeMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -204,8 +253,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge));
 
         auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
 
         NodeValuePerEdge<int> node_value_per_edge{connectivity};
@@ -213,8 +266,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_edge.numberOfValues() == number_of_values(node_value_per_edge));
 
         auto edge_to_node_matrix = connectivity.edgeToNodeMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -225,8 +282,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_node.numberOfValues() == number_of_values(edge_value_per_node));
 
         auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerNode<int> face_value_per_node{connectivity};
@@ -234,8 +295,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_node.numberOfValues() == number_of_values(face_value_per_node));
 
         auto node_to_face_matrix = connectivity.nodeToFaceMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
 
         CellValuePerNode<int> cell_value_per_node{connectivity};
@@ -243,8 +308,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node));
 
         auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
       }
     }
@@ -261,8 +330,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_cell.numberOfValues() == number_of_values(node_value_per_cell));
 
         auto cell_to_node_matrix = connectivity.cellToNodeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_node_matrix[cell_id].size() == node_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         EdgeValuePerCell<int> edge_value_per_cell{connectivity};
@@ -270,8 +343,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_cell.numberOfValues() == number_of_values(edge_value_per_cell));
 
         auto cell_to_edge_matrix = connectivity.cellToEdgeMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_edge_matrix[cell_id].size() == edge_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerCell<int> face_value_per_cell{connectivity};
@@ -279,8 +356,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_cell.numberOfValues() == number_of_values(face_value_per_cell));
 
         auto cell_to_face_matrix = connectivity.cellToFaceMatrix();
-        for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
-          REQUIRE(cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+        {
+          bool is_correct = true;
+          for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
+            is_correct &= (cell_to_face_matrix[cell_id].size() == face_value_per_cell.numberOfSubValues(cell_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -291,8 +372,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_face.numberOfValues() == number_of_values(cell_value_per_face));
 
         auto face_to_cell_matrix = connectivity.faceToCellMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_cell_matrix[face_id].size() == cell_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
 
         EdgeValuePerFace<int> edge_value_per_face{connectivity};
@@ -300,8 +385,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_face.numberOfValues() == number_of_values(edge_value_per_face));
 
         auto face_to_edge_matrix = connectivity.faceToEdgeMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_edge_matrix[face_id].size() == edge_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_edge_matrix[face_id].size() == edge_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
 
         NodeValuePerFace<int> node_value_per_face{connectivity};
@@ -309,8 +398,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_face.numberOfValues() == number_of_values(node_value_per_face));
 
         auto face_to_node_matrix = connectivity.faceToNodeMatrix();
-        for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
-          REQUIRE(face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id));
+        {
+          bool is_correct = true;
+          for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
+            is_correct &= (face_to_node_matrix[face_id].size() == node_value_per_face.numberOfSubValues(face_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -321,8 +414,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_edge.numberOfValues() == number_of_values(cell_value_per_edge));
 
         auto edge_to_cell_matrix = connectivity.edgeToCellMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_cell_matrix[edge_id].size() == cell_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerEdge<int> face_value_per_edge{connectivity};
@@ -330,8 +427,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_edge.numberOfValues() == number_of_values(face_value_per_edge));
 
         auto edge_to_face_matrix = connectivity.edgeToFaceMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_face_matrix[edge_id].size() == face_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_face_matrix[edge_id].size() == face_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
 
         NodeValuePerEdge<int> node_value_per_edge{connectivity};
@@ -339,8 +440,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(node_value_per_edge.numberOfValues() == number_of_values(node_value_per_edge));
 
         auto edge_to_node_matrix = connectivity.edgeToNodeMatrix();
-        for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
-          REQUIRE(edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id));
+        {
+          bool is_correct = true;
+          for (EdgeId edge_id = 0; edge_id < connectivity.numberOfEdges(); ++edge_id) {
+            is_correct &= (edge_to_node_matrix[edge_id].size() == node_value_per_edge.numberOfSubValues(edge_id));
+          }
+          REQUIRE(is_correct);
         }
       }
 
@@ -351,8 +456,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(edge_value_per_node.numberOfValues() == number_of_values(edge_value_per_node));
 
         auto node_to_edge_matrix = connectivity.nodeToEdgeMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_edge_matrix[node_id].size() == edge_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
 
         FaceValuePerNode<int> face_value_per_node{connectivity};
@@ -360,8 +469,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(face_value_per_node.numberOfValues() == number_of_values(face_value_per_node));
 
         auto node_to_face_matrix = connectivity.nodeToFaceMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_face_matrix[node_id].size() == face_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
 
         CellValuePerNode<int> cell_value_per_node{connectivity};
@@ -369,8 +482,12 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
         REQUIRE(cell_value_per_node.numberOfValues() == number_of_values(cell_value_per_node));
 
         auto node_to_cell_matrix = connectivity.nodeToCellMatrix();
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          REQUIRE(node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+        {
+          bool is_correct = true;
+          for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
+            is_correct &= (node_to_cell_matrix[node_id].size() == cell_value_per_node.numberOfSubValues(node_id));
+          }
+          REQUIRE(is_correct);
         }
       }
     }
@@ -392,20 +509,26 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
           }
         }
       }
-      for (size_t i = 0; i < edge_values_per_cell.numberOfValues(); ++i) {
-        REQUIRE(edge_values_per_cell[i] == i);
+      {
+        bool is_same = true;
+        for (size_t i = 0; i < edge_values_per_cell.numberOfValues(); ++i) {
+          is_same &= (edge_values_per_cell[i] == i);
+        }
+        REQUIRE(is_same);
       }
 
       for (size_t i = 0; i < edge_values_per_cell.numberOfValues(); ++i) {
         edge_values_per_cell[i] = i * i + 1;
       }
       {
-        size_t i = 0;
+        bool is_same = true;
+        size_t i     = 0;
         for (CellId cell_id = 0; cell_id < connectivity.numberOfCells(); ++cell_id) {
           for (size_t i_edge = 0; i_edge < edge_values_per_cell.numberOfSubValues(cell_id); ++i_edge, ++i) {
-            REQUIRE(edge_values_per_cell(cell_id, i_edge) == i * i + 1);
+            is_same &= (edge_values_per_cell(cell_id, i_edge) == i * i + 1);
           }
         }
+        REQUIRE(is_same);
       }
     }
 
@@ -423,20 +546,25 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
           }
         }
       }
-      for (size_t i = 0; i < cell_values_per_face.numberOfValues(); ++i) {
-        REQUIRE(cell_values_per_face[i] == i);
+      {
+        bool is_same = true;
+        for (size_t i = 0; i < cell_values_per_face.numberOfValues(); ++i) {
+          is_same &= (cell_values_per_face[i] == i);
+        }
+        REQUIRE(is_same);
       }
-
       for (size_t i = 0; i < cell_values_per_face.numberOfValues(); ++i) {
         cell_values_per_face[i] = 3 * i + 1;
       }
       {
-        size_t i = 0;
+        bool is_same = true;
+        size_t i     = 0;
         for (FaceId face_id = 0; face_id < connectivity.numberOfFaces(); ++face_id) {
           for (size_t i_cell = 0; i_cell < cell_values_per_face.numberOfSubValues(face_id); ++i_cell, ++i) {
-            REQUIRE(cell_values_per_face(face_id, i_cell) == 3 * i + 1);
+            is_same &= (cell_values_per_face(face_id, i_cell) == 3 * i + 1);
           }
         }
+        REQUIRE(is_same);
       }
     }
 
@@ -454,29 +582,26 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
           }
         }
       }
-      for (size_t i = 0; i < face_values_per_node.numberOfValues(); ++i) {
-        REQUIRE(face_values_per_node[i] == i);
+      {
+        bool is_same = true;
+        for (size_t i = 0; i < face_values_per_node.numberOfValues(); ++i) {
+          is_same &= (face_values_per_node[i] == i);
+        }
+        REQUIRE(is_same);
       }
 
       for (size_t i = 0; i < face_values_per_node.numberOfValues(); ++i) {
         face_values_per_node[i] = 3 + i * i;
       }
       {
-        size_t i = 0;
-        for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
-          for (size_t i_face = 0; i_face < face_values_per_node.numberOfSubValues(node_id); ++i_face, ++i) {
-            face_values_per_node(node_id, i_face) = 3 + i * i;
-          }
-        }
-      }
-
-      {
-        size_t i = 0;
+        bool is_same = true;
+        size_t i     = 0;
         for (NodeId node_id = 0; node_id < connectivity.numberOfNodes(); ++node_id) {
           for (size_t i_face = 0; i_face < face_values_per_node.numberOfSubValues(node_id); ++i_face, ++i) {
-            face_values_per_node.itemValues(node_id)[i_face] = 3 + i * i;
+            is_same &= (face_values_per_node.itemValues(node_id)[i_face] == 3 + i * i);
           }
         }
+        REQUIRE(is_same);
       }
     }
   }
@@ -526,69 +651,122 @@ TEST_CASE("SubItemValuePerItem", "[mesh]")
     }
   }
 
-  SECTION("WeakItemValue")
+  SECTION("WeakSubItemValuePerItem")
   {
-    // const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>();
-    // const Connectivity<2>& connectivity  = mesh_2d.connectivity();
+    const Mesh<Connectivity<2>>& mesh_2d = MeshDataBaseForTests::get().cartesianMesh<2>();
+    const Connectivity<2>& connectivity  = mesh_2d.connectivity();
+
+    WeakFaceValuePerCell<int> weak_face_value_per_cell{connectivity};
 
-    // WeakFaceValue<int> weak_face_value{connectivity};
+    for (size_t i = 0; i < weak_face_value_per_cell.numberOfValues(); ++i) {
+      weak_face_value_per_cell[i] = i;
+    }
 
-    // weak_face_value.fill(parallel::rank());
+    FaceValuePerCell<const int> face_value_per_cell{weak_face_value_per_cell};
 
-    // FaceValue<const int> face_value{weak_face_value};
+    REQUIRE(face_value_per_cell.connectivity_ptr() == weak_face_value_per_cell.connectivity_ptr());
 
-    // REQUIRE(face_value.connectivity_ptr() == weak_face_value.connectivity_ptr());
+    bool is_same = true;
+    for (size_t i = 0; i < weak_face_value_per_cell.numberOfValues(); ++i) {
+      is_same &= (face_value_per_cell[i] == weak_face_value_per_cell[i]);
+    }
+    REQUIRE(is_same);
   }
 
 #ifndef NDEBUG
   SECTION("error")
   {
-    SECTION("checking for build ItemValue")
+    SECTION("checking for build SubItemValuePerItem")
     {
-      // CellValue<int> cell_value;
-      // REQUIRE_THROWS_AS(cell_value[CellId{0}], AssertError);
-
-      // FaceValue<int> face_value;
-      // REQUIRE_THROWS_AS(face_value[FaceId{0}], AssertError);
-
-      // EdgeValue<int> edge_value;
-      // REQUIRE_THROWS_AS(edge_value[EdgeId{0}], AssertError);
-
-      // NodeValue<int> node_value;
-      // REQUIRE_THROWS_AS(node_value[NodeId{0}], AssertError);
+      CellValuePerNode<int> cell_value_per_node;
+      REQUIRE_THROWS_AS(cell_value_per_node[0], AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_node.itemValues(NodeId{0}), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_node(NodeId{0}, 0), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_node.numberOfValues(), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_node.numberOfItems(), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_node.numberOfSubValues(NodeId{0}), AssertError);
+
+      FaceValuePerCell<int> face_value_per_cell;
+      REQUIRE_THROWS_AS(face_value_per_cell[0], AssertError);
+      REQUIRE_THROWS_AS(face_value_per_cell.itemValues(CellId{0}), AssertError);
+      REQUIRE_THROWS_AS(face_value_per_cell(CellId{0}, 0), AssertError);
+      REQUIRE_THROWS_AS(face_value_per_cell.numberOfValues(), AssertError);
+      REQUIRE_THROWS_AS(face_value_per_cell.numberOfItems(), AssertError);
+      REQUIRE_THROWS_AS(face_value_per_cell.numberOfSubValues(CellId{0}), AssertError);
+
+      CellValuePerEdge<int> cell_value_per_edge;
+      REQUIRE_THROWS_AS(cell_value_per_edge[0], AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_edge.itemValues(EdgeId{0}), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_edge(EdgeId{0}, 0), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_edge.numberOfValues(), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_edge.numberOfItems(), AssertError);
+      REQUIRE_THROWS_AS(cell_value_per_edge.numberOfSubValues(EdgeId{0}), AssertError);
+
+      NodeValuePerFace<int> node_value_per_face;
+      REQUIRE_THROWS_AS(node_value_per_face[0], AssertError);
+      REQUIRE_THROWS_AS(node_value_per_face.itemValues(FaceId{0}), AssertError);
+      REQUIRE_THROWS_AS(node_value_per_face(FaceId{0}, 0), AssertError);
+      REQUIRE_THROWS_AS(node_value_per_face.numberOfValues(), AssertError);
+      REQUIRE_THROWS_AS(node_value_per_face.numberOfItems(), AssertError);
+      REQUIRE_THROWS_AS(node_value_per_face.numberOfSubValues(FaceId{0}), AssertError);
     }
 
     SECTION("checking for bounds violation")
     {
-      // const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
-      // const Connectivity<3>& connectivity  = mesh_3d.connectivity();
-
-      // CellValue<int> cell_value{connectivity};
-      // CellId invalid_cell_id = connectivity.numberOfCells();
-      // REQUIRE_THROWS_AS(cell_value[invalid_cell_id], AssertError);
-
-      // FaceValue<int> face_value{connectivity};
-      // FaceId invalid_face_id = connectivity.numberOfFaces();
-      // REQUIRE_THROWS_AS(face_value[invalid_face_id], AssertError);
-
-      // EdgeValue<int> edge_value{connectivity};
-      // EdgeId invalid_edge_id = connectivity.numberOfEdges();
-      // REQUIRE_THROWS_AS(edge_value[invalid_edge_id], AssertError);
+      const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
+      const Connectivity<3>& connectivity  = mesh_3d.connectivity();
 
-      // NodeValue<int> node_value{connectivity};
-      // NodeId invalid_node_id = connectivity.numberOfNodes();
-      // REQUIRE_THROWS_AS(node_value[invalid_node_id], AssertError);
-    }
+      CellValuePerFace<int> cell_value_per_face{connectivity};
+      {
+        FaceId invalid_face_id = connectivity.numberOfFaces();
+        REQUIRE_THROWS_AS(cell_value_per_face(invalid_face_id, 0), AssertError);
+      }
+      if (connectivity.numberOfFaces() > 0) {
+        FaceId face_id          = 0;
+        const auto& cell_values = cell_value_per_face.itemValues(face_id);
+        REQUIRE_THROWS_AS(cell_value_per_face(face_id, cell_values.size()), AssertError);
+        REQUIRE_THROWS_AS(cell_values[cell_values.size()], AssertError);
+        REQUIRE_THROWS_AS(cell_value_per_face.itemValues(face_id)[cell_values.size()] = 2, AssertError);
+      }
 
-    SECTION("set values from invalid array size")
-    {
-      // const Mesh<Connectivity<3>>& mesh_3d = MeshDataBaseForTests::get().cartesianMesh<3>();
-      // const Connectivity<3>& connectivity  = mesh_3d.connectivity();
+      FaceValuePerNode<int> face_value_per_node{connectivity};
+      {
+        NodeId invalid_node_id = connectivity.numberOfNodes();
+        REQUIRE_THROWS_AS(face_value_per_node(invalid_node_id, 0), AssertError);
+      }
+      if (connectivity.numberOfNodes() > 0) {
+        NodeId node_id          = 0;
+        const auto& face_values = face_value_per_node.itemValues(node_id);
+        REQUIRE_THROWS_AS(face_value_per_node(node_id, face_values.size()), AssertError);
+        REQUIRE_THROWS_AS(face_values[face_values.size()], AssertError);
+        REQUIRE_THROWS_AS(face_value_per_node.itemValues(node_id)[face_values.size()] = 2, AssertError);
+      }
 
-      // CellValue<size_t> cell_value{connectivity};
+      EdgeValuePerCell<int> edge_value_per_cell{connectivity};
+      {
+        CellId invalid_cell_id = connectivity.numberOfCells();
+        REQUIRE_THROWS_AS(edge_value_per_cell(invalid_cell_id, 0), AssertError);
+      }
+      if (connectivity.numberOfCells() > 0) {
+        CellId cell_id          = 0;
+        const auto& edge_values = edge_value_per_cell.itemValues(cell_id);
+        REQUIRE_THROWS_AS(edge_value_per_cell(cell_id, edge_values.size()), AssertError);
+        REQUIRE_THROWS_AS(edge_values[edge_values.size()], AssertError);
+        REQUIRE_THROWS_AS(edge_value_per_cell.itemValues(cell_id)[edge_values.size()] = 2, AssertError);
+      }
 
-      // Array<size_t> values{3 + cell_value.size()};
-      // REQUIRE_THROWS_AS(cell_value = values, AssertError);
+      NodeValuePerEdge<int> node_value_per_edge{connectivity};
+      {
+        EdgeId invalid_edge_id = connectivity.numberOfEdges();
+        REQUIRE_THROWS_AS(node_value_per_edge(invalid_edge_id, 0), AssertError);
+      }
+      if (connectivity.numberOfEdges() > 0) {
+        EdgeId edge_id          = 0;
+        const auto& node_values = node_value_per_edge.itemValues(edge_id);
+        REQUIRE_THROWS_AS(node_value_per_edge(edge_id, node_values.size()), AssertError);
+        REQUIRE_THROWS_AS(node_values[node_values.size()], AssertError);
+        REQUIRE_THROWS_AS(node_value_per_edge.itemValues(edge_id)[node_values.size()] = 2, AssertError);
+      }
     }
   }
 #endif   // NDEBUG
-- 
GitLab