From 94554982536bc1acfa8b29bebdcec093670bb12b Mon Sep 17 00:00:00 2001
From: Nils Kohl <nils.kohl@fau.de>
Date: Wed, 30 May 2018 12:21:33 +0200
Subject: [PATCH] Implemented std::array support for send and recv buffer shift
 operators (also extended buffer test)

---
 src/core/mpi/BufferDataTypeExtensions.h | 46 +++++++++++++++++++++++++
 tests/core/mpi/BufferTest.cpp           | 18 ++++++++--
 2 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h
index b05128c4a..bf51bd9f8 100644
--- a/src/core/mpi/BufferDataTypeExtensions.h
+++ b/src/core/mpi/BufferDataTypeExtensions.h
@@ -33,6 +33,7 @@
 #include <boost/integer.hpp>
 #include <boost/uuid/uuid.hpp>
 
+#include <array>
 #include <deque>
 #include <limits>
 #include <list>
@@ -82,6 +83,51 @@ struct BufferSizeTrait< std::pair<T1,T2> > {
 // ----------------------------- Standard Container Support  -----------------------------------------------------------
 // ---------------------------------------------------------------------------------------------------------------------
 
+template< typename T,     // Element type of SendBuffer
+          typename G,     // Growth policy of SendBuffer
+          typename Cont > // Container
+void sendNonResizableContainer( GenericSendBuffer<T,G> & buf, const Cont & container )
+{
+  buf.addDebugMarker( "ar" );
+  for( const auto & it : container )
+    buf << it;
+}
+
+template< typename T,     // Element type of RecvBuffer
+          typename Cont > // Container
+void recvNonResizableContainer( GenericRecvBuffer<T> & buf, Cont & container )
+{
+  buf.readDebugMarker( "ar" );
+  for( auto & it : container )
+    buf >> it;
+}
+
+template< typename T,     // Element type of SendBuffer
+          typename G,     // Growth policy of SendBuffer
+          typename CT,    // Element type
+          std::size_t N > // Array size
+GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const std::array<CT, N> & array )
+{
+  sendNonResizableContainer(buf, array);
+  return buf;
+}
+
+template< typename T,     // Element type of RecvBuffer
+          typename CT,    // Element type
+          std::size_t N > // Array size
+GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, std::array<CT, N> & array )
+{
+  recvNonResizableContainer(buf, array);
+  return buf;
+}
+
+template<typename T, std::size_t N>
+struct BufferSizeTrait< std::array< T, N > > {
+    static const bool constantSize = true;
+    static const uint_t size = N * sizeof(T) + BUFFER_DEBUG_OVERHEAD;
+};
+
+
 template< typename T,    // Element type of SendBuffer
           typename G,    // Growth policy of SendBuffer
           typename Cont> // Container
diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp
index c34a1ef8e..741edc1f8 100644
--- a/tests/core/mpi/BufferTest.cpp
+++ b/tests/core/mpi/BufferTest.cpp
@@ -122,6 +122,16 @@ void initBoostArray( boost::array< T, N > & array )
       *it = dist( rng );
 }
 
+template<typename T, std::size_t N>
+void initStdArray( std::array< T, N > & array )
+{
+   static std::mt19937 rng;
+   std::uniform_int_distribution<T> dist;
+
+   for( auto it = array.begin(); it != array.end(); ++it )
+      *it = dist( rng );
+}
+
 
 /// Simulates one send and receive operation
 /// data is put into send buffer and copied to RecvBuffer
@@ -153,6 +163,7 @@ void bufferTest()
    std::multimap<unsigned int, walberla::int64_t> stdMultiMap, stdMultiMapEmpty;
 
    boost::array< unsigned int, 19 > boostArray;
+   std::array  < unsigned int, 19 > stdArray;
 
    initVecBool(boolStdVec);
    initIntegerContainer(stdVec);
@@ -163,6 +174,7 @@ void bufferTest()
    initIntegerMap(stdMap);
    initIntegerMap(stdMultiMap);
    initBoostArray(boostArray);
+   initStdArray(stdArray);
 
    // Create send buffer and put two values in it
    GenericSendBuffer<T> sb;
@@ -178,7 +190,7 @@ void bufferTest()
    sb << stdMultiSet << stdMultiSetEmpty;
    sb << stdMap      << stdMapEmpty;
    sb << stdMultiMap << stdMultiMapEmpty;
-   sb << boostArray;
+   sb << boostArray  << stdArray;
 
    // Copying
    //RecvBuffer<T> rb;
@@ -209,6 +221,7 @@ void bufferTest()
    std::multimap<unsigned int, walberla::int64_t> recvStdMultiMap, recvStdMultiMapEmpty;
 
    boost::array<unsigned int, 19> recvBoostArray;
+   std::array  <unsigned int, 19> recvStdArray;
 
    rb >> recvD           >> recvI;
    rb >> recvVec         >> recvMat;
@@ -222,7 +235,7 @@ void bufferTest()
    rb >> recvStdMultiSet >> recvStdMultiSetEmpty;
    rb >> recvStdMap      >> recvStdMapEmpty;
    rb >> recvStdMultiMap >> recvStdMultiMapEmpty;
-   rb >> recvBoostArray;
+   rb >> recvBoostArray  >> recvStdArray;
 
    // Validate
    WALBERLA_CHECK_FLOAT_EQUAL(recvD,testDouble);
@@ -254,6 +267,7 @@ void bufferTest()
    WALBERLA_CHECK_EQUAL(recvStdMultiMapEmpty, stdMultiMapEmpty);
 
    WALBERLA_CHECK_EQUAL(recvBoostArray, boostArray);
+   WALBERLA_CHECK_EQUAL(recvStdArray,   stdArray);
 }
 
 
-- 
GitLab