diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h
index 4c348dfe7f6e934fb9fb5403abfd5761e256a9ae..e4c755d104988335a71158aaf2f9955e12d523a9 100644
--- a/src/core/DataTypes.h
+++ b/src/core/DataTypes.h
@@ -120,6 +120,34 @@ inline void static_assert_uint_t() {
                  !std::numeric_limits<UINT>::is_signed, "Unsigned integer type required/expected!" );
 }
 
+template< uint_t size > struct uintFromBitWidth;
+template<> struct uintFromBitWidth<  8 > { typedef uint8_t  type; };
+template<> struct uintFromBitWidth< 16 > { typedef uint16_t type; };
+template<> struct uintFromBitWidth< 32 > { typedef uint32_t type; };
+template<> struct uintFromBitWidth< 64 > { typedef uint64_t type; };
+
+constexpr uint_t leastUnsignedIntegerBitWidth( uint_t width )
+{
+   if ( width <=  8 ) return  8;
+   if ( width <= 16 ) return 16;
+   if ( width <= 32 ) return 32;
+   if ( width <= 64 ) return 64;
+   return width;
+}
+
+/// \brief Provides the smallest unsigned integer type that has at least minSize bits.
+///
+/// Example:
+///
+///   leastUnsignedInteger< 5 >::type a; // a is an 8-bit unsigned integer
+///   leastUnsignedInteger< 9 >::type b; // b is a 16-bit unsigned integer
+///
+template< uint_t minSize >
+struct leastUnsignedInteger
+{
+   typedef typename uintFromBitWidth< leastUnsignedIntegerBitWidth( minSize ) >::type type;
+};
+
 /// \cond internal
 static const uint_t UINT_BITS  = static_cast< uint_t >( std::numeric_limits< uint_t >::digits );
 static const uint_t UINT_BYTES = static_cast< uint_t >( std::numeric_limits< uint_t >::digits ) >> 3;
diff --git a/src/core/math/GenericAABB.h b/src/core/math/GenericAABB.h
index 309d16f94887684c26f9f20117f426854a2bb380..9a11d29281b2d11da771c2ced3dc25f44f59ad54 100644
--- a/src/core/math/GenericAABB.h
+++ b/src/core/math/GenericAABB.h
@@ -27,7 +27,6 @@
 #include "core/mpi/RecvBuffer.h"
 #include "core/mpi/SendBuffer.h"
 
-#include <boost/array.hpp>
 #include <boost/type_traits/is_floating_point.hpp>
 
 #include <random>
@@ -148,7 +147,7 @@ public:
    inline value_type sqDistance( const GenericAABB & other ) const;
    inline value_type sqMaxDistance( const GenericAABB & other ) const;
 
-   inline boost::array< vector_type, 8 > corners() const;
+   inline std::array< vector_type, 8 > corners() const;
 
    // Modifiers
    inline void init();
diff --git a/src/core/math/GenericAABB.impl.h b/src/core/math/GenericAABB.impl.h
index 00503076fc82fc8390cb60feb5ca5456edbf686c..7d24f164f2fbae77cbb715d3e4ac2fb35ba987ff 100644
--- a/src/core/math/GenericAABB.impl.h
+++ b/src/core/math/GenericAABB.impl.h
@@ -1270,9 +1270,9 @@ inline typename GenericAABB< T >::value_type GenericAABB< T >::sqMaxDistance( co
  * \returns An array of size eight containing the corner points. Indices match those of the stencil::D3CornerStencil
  */
 template< typename T >
-inline boost::array< typename GenericAABB< T >::vector_type, 8 > GenericAABB< T >::corners() const
+inline std::array< typename GenericAABB< T >::vector_type, 8 > GenericAABB< T >::corners() const
 {
-   boost::array< vector_type, 8 > cornerArray;
+   std::array< vector_type, 8 > cornerArray;
 
    // TNE
    cornerArray[0][0] = maxCorner_[0];
diff --git a/src/core/math/ParserOMP.cpp b/src/core/math/ParserOMP.cpp
index b849c5bcac561c4426922a21d653bde197e6f6bc..e39786837abbfc112959137f1783e7238950838f 100644
--- a/src/core/math/ParserOMP.cpp
+++ b/src/core/math/ParserOMP.cpp
@@ -53,7 +53,7 @@ void FunctionParserOMP::parse(const std::string & eq)
    #endif
    for (int t = 0; t < omp_get_max_threads(); ++t)
    {
-      parser_[t].parse(eq);
+      parser_[uint_c(t)].parse(eq);
    }
 }
 
@@ -61,7 +61,7 @@ double FunctionParserOMP::evaluate(const std::map<std::string,double> & symbolTa
 {
    WALBERLA_ASSERT_EQUAL(omp_get_max_threads(), num_parsers_);
 
-   return parser_[omp_get_thread_num()].evaluate(symbolTable);
+   return parser_[uint_c(omp_get_thread_num())].evaluate(symbolTable);
 }
 
 
diff --git a/src/core/math/ParserOMP.h b/src/core/math/ParserOMP.h
index 3c270f0d92d675062e438cfe0bd301e0f71a00fb..7a3939e18f74245a9fcef2459adedf9274c7d678 100644
--- a/src/core/math/ParserOMP.h
+++ b/src/core/math/ParserOMP.h
@@ -22,8 +22,8 @@
 #pragma once
 
 #include "Parser.h"
-#include <boost/shared_array.hpp>
 
+#include <memory>
 
 namespace walberla {
 namespace math {
@@ -39,7 +39,7 @@ public:
    inline bool symbolExists(const std::string & symbol) const { return parser_[0].symbolExists(symbol); }
 
 private:
-   boost::shared_array<FunctionParser> parser_;
+   std::unique_ptr< FunctionParser[] > parser_;
 #ifndef NDEBUG
    int num_parsers_;
 #endif
diff --git a/src/core/math/Uint.h b/src/core/math/Uint.h
index 14dd3ed100a7dfbdd82726c4945b63f1fe2c7326..ac880252073d3a58f8e4ed20e10acab59e55a4c6 100644
--- a/src/core/math/Uint.h
+++ b/src/core/math/Uint.h
@@ -26,7 +26,6 @@
 #include "core/debug/Debug.h"
 
 #include <boost/type_traits/is_unsigned.hpp>
-#include <boost/integer.hpp>
 
 
 namespace walberla {
diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h
index bf51bd9f83ad3390976f72fea1502799c337317c..145e1d3aa2a0238cde5b3cf205ede98e4daf75f9 100644
--- a/src/core/mpi/BufferDataTypeExtensions.h
+++ b/src/core/mpi/BufferDataTypeExtensions.h
@@ -29,8 +29,6 @@
 #include "core/DataTypes.h"
 #include "core/Optional.h"
 
-#include <boost/array.hpp>
-#include <boost/integer.hpp>
 #include <boost/uuid/uuid.hpp>
 
 #include <array>
@@ -277,7 +275,7 @@ template< typename T,    // Element type of SendBuffer
 GenericSendBuffer<T,G>& packBoolVectorWithoutSize(GenericSendBuffer<T,G> & buf, const std::vector<bool> & bools )
 {
    // Use an unsigned type at least as large as the SendBuffer base type as container for the bools
-   typedef typename boost::uint_t<std::numeric_limits<T>::digits>::least ContainerType;
+   typedef typename leastUnsignedInteger< std::numeric_limits<T>::digits >::type ContainerType;
    static const size_t NUM_BITS = std::numeric_limits<ContainerType>::digits;
 
    auto it = bools.begin();
@@ -298,7 +296,7 @@ template< typename T >    // Element type  of RecvBuffer
 GenericRecvBuffer<T>& unpackBoolVectorWithoutSize(GenericRecvBuffer<T> & buf, std::vector<bool> & bools, size_t size )
 {
    // Use an unsigned type at least as large as the RecvBuffer base type as container for the bools
-   typedef typename boost::uint_t<std::numeric_limits<T>::digits>::least ContainerType;
+   typedef typename leastUnsignedInteger<std::numeric_limits<T>::digits>::type ContainerType;
    static const size_t NUM_BITS = std::numeric_limits<ContainerType>::digits;
 
    bools.resize(size);
@@ -593,37 +591,5 @@ inline RecvBuffer & operator>>( RecvBuffer & buf, boost::uuids::uuid & uuid )
 }
 
 
-// ---------------------------------------------------------------------------------------------------------------------
-// --------------------------------------- Boost array Support ----------------------------------------------------------
-// ---------------------------------------------------------------------------------------------------------------------
-
-template<typename T, std::size_t N>
-struct BufferSizeTrait< boost::array< T, N > > {
-   static const bool constantSize = true;
-   static const uint_t size = N * sizeof(T) + BUFFER_DEBUG_OVERHEAD;
-};
-
-
-template<typename ET, typename G, typename T, std::size_t N>
-inline GenericSendBuffer<ET, G> & operator<<( GenericSendBuffer<ET, G> & buf, const boost::array< T, N > & array )
-{
-   buf.addDebugMarker( "ba" );
-   for( auto it = array.begin(); it != array.end(); ++it )
-      buf << *it;
-
-   return buf;
-}
-
-
-template<typename ET, typename T, std::size_t N>
-inline GenericRecvBuffer<ET> & operator>>( GenericRecvBuffer<ET> & buf, boost::array< T, N > & array )
-{
-   buf.readDebugMarker( "ba" );
-   for( auto it = array.begin(); it != array.end(); ++it )
-      buf >> *it;
-
-   return buf;
-}
-
 } //namespace mpi
 } //namespace walberla
diff --git a/src/field/FlagField.h b/src/field/FlagField.h
index 2785dd199fac3964a2ae835c3bf7c15299ff213a..147ab57833f53d6d0b5c5e32ec6765399410ad39 100644
--- a/src/field/FlagField.h
+++ b/src/field/FlagField.h
@@ -31,9 +31,9 @@
 #include "core/debug/Debug.h"
 #include "core/math/Uint.h"
 
-#include <boost/array.hpp>
 #include <boost/type_traits/is_same.hpp>
 
+#include <array>
 #include <iostream>
 #include <map>
 #include <sstream>
@@ -214,7 +214,7 @@ protected:
       {}
 
       /// Maps bitNr's to strings
-      boost::array<FlagUID, sizeof(flag_t)*8> flagToUID;
+      std::array<FlagUID, sizeof(flag_t)*8> flagToUID;
 
       /// Maps strings to bit-masks
       std::map<FlagUID, flag_t> uidToFlag;
diff --git a/src/lbm/boundary/Curved.h b/src/lbm/boundary/Curved.h
index a3d47ccbcfca07184830c50d26107213c6f2332f..d5f7aa08ff5480a1d58ba6a0fd11e22010150509 100644
--- a/src/lbm/boundary/Curved.h
+++ b/src/lbm/boundary/Curved.h
@@ -35,8 +35,7 @@
 
 #include "stencil/Directions.h"
 
-#include <boost/array.hpp>
-
+#include <array>
 #include <vector>
 
 namespace walberla {
@@ -53,7 +52,7 @@ class Curved : public Boundary< typename FlagField_T::flag_t >
    typedef typename LatticeModel_T::Stencil  Stencil;
    typedef typename FlagField_T::flag_t      flag_t;
 
-   typedef GhostLayerField< shared_ptr< boost::array<real_t, Stencil::Size> >, 1 >  WeightField;
+   typedef GhostLayerField< shared_ptr< std::array<real_t, Stencil::Size> >, 1 >  WeightField;
 
 public:
 
@@ -105,9 +104,9 @@ public:
 private:
 
    inline static real_t deltaToWeight( const real_t delta ) { return ( real_t( 1 ) - real_t( 2 ) * delta ) / ( real_t( 1 ) + real_t( 2 ) * delta ); }
-   inline static shared_ptr< boost::array<real_t, Stencil::Size> > makeDeltaArray()
+   inline static shared_ptr< std::array<real_t, Stencil::Size> > makeDeltaArray()
    {
-      return walberla::shared_ptr< boost::array<real_t, Stencil::Size> >( new boost::array<real_t, Stencil::Size> );
+      return walberla::shared_ptr< std::array<real_t, Stencil::Size> >( new std::array<real_t, Stencil::Size> );
    }
 
    const FlagUID uid_;
diff --git a/src/pe/Types.h b/src/pe/Types.h
index c71ee80907fa5506206c58de904e21d2bebc4550..ce32a6205035cfab3e9bab555c7105e0759068ef 100644
--- a/src/pe/Types.h
+++ b/src/pe/Types.h
@@ -25,8 +25,7 @@
 #include "core/math/AABBFwd.h"
 #include "stencil/D3Q27.h"
 
-#include <boost/array.hpp>
-
+#include <array>
 #include <memory>
 #include <vector>
 
@@ -188,7 +187,7 @@ struct StorageSelect
 };
 
 ///Container for local and shadow body storage
-typedef boost::array<BodyStorage, 2> Storage;
+typedef std::array<BodyStorage, 2> Storage;
 
 }  // namespace pe
 }  // namespace walberla
diff --git a/src/pe/vtk/BodyVtkOutput.h b/src/pe/vtk/BodyVtkOutput.h
index 9822510062189db2ba0f0c4cccea1e01e6520f64..3898f6f10b86f17cbba3e965fcf7e45dadad4561 100644
--- a/src/pe/vtk/BodyVtkOutput.h
+++ b/src/pe/vtk/BodyVtkOutput.h
@@ -32,8 +32,6 @@
 
 #include <vector>
 
-#include <boost/array.hpp>
-
 namespace walberla {
 namespace pe {
 
diff --git a/src/pe/vtk/SphereVtkOutput.h b/src/pe/vtk/SphereVtkOutput.h
index 25290f2265b69b5986384052cb73dcfe2f282c74..56ea0146798c5c03b708b0c92c3d796f3ee2629b 100755
--- a/src/pe/vtk/SphereVtkOutput.h
+++ b/src/pe/vtk/SphereVtkOutput.h
@@ -36,8 +36,6 @@
 
 #include <vector>
 
-#include <boost/array.hpp>
-
 namespace walberla {
 namespace pe {
 
diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp
index 741edc1f85340215798bc848b7a275adeb9e30c6..b5d43f478ea9f03da32a12627cc09d1ab7044351 100644
--- a/tests/core/mpi/BufferTest.cpp
+++ b/tests/core/mpi/BufferTest.cpp
@@ -112,15 +112,6 @@ void initCellContainer( T & container )
       container.insert( container.end(), Cell( dist(rng), dist(rng), dist(rng) ) );
 }
 
-template<typename T, std::size_t N>
-void initBoostArray( boost::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 );
-}
 
 template<typename T, std::size_t N>
 void initStdArray( std::array< T, N > & array )
@@ -162,7 +153,6 @@ void bufferTest()
    std::map     <unsigned int, walberla::int64_t> stdMap,      stdMapEmpty;
    std::multimap<unsigned int, walberla::int64_t> stdMultiMap, stdMultiMapEmpty;
 
-   boost::array< unsigned int, 19 > boostArray;
    std::array  < unsigned int, 19 > stdArray;
 
    initVecBool(boolStdVec);
@@ -173,7 +163,6 @@ void bufferTest()
    initIntegerAssocContainer(stdMultiSet);
    initIntegerMap(stdMap);
    initIntegerMap(stdMultiMap);
-   initBoostArray(boostArray);
    initStdArray(stdArray);
 
    // Create send buffer and put two values in it
@@ -190,7 +179,7 @@ void bufferTest()
    sb << stdMultiSet << stdMultiSetEmpty;
    sb << stdMap      << stdMapEmpty;
    sb << stdMultiMap << stdMultiMapEmpty;
-   sb << boostArray  << stdArray;
+   sb << stdArray;
 
    // Copying
    //RecvBuffer<T> rb;
@@ -220,7 +209,6 @@ void bufferTest()
    std::map     <unsigned int, walberla::int64_t> recvStdMap,      recvStdMapEmpty;
    std::multimap<unsigned int, walberla::int64_t> recvStdMultiMap, recvStdMultiMapEmpty;
 
-   boost::array<unsigned int, 19> recvBoostArray;
    std::array  <unsigned int, 19> recvStdArray;
 
    rb >> recvD           >> recvI;
@@ -235,7 +223,7 @@ void bufferTest()
    rb >> recvStdMultiSet >> recvStdMultiSetEmpty;
    rb >> recvStdMap      >> recvStdMapEmpty;
    rb >> recvStdMultiMap >> recvStdMultiMapEmpty;
-   rb >> recvBoostArray  >> recvStdArray;
+   rb >> recvStdArray;
 
    // Validate
    WALBERLA_CHECK_FLOAT_EQUAL(recvD,testDouble);
@@ -266,7 +254,6 @@ void bufferTest()
    WALBERLA_CHECK_EQUAL(recvStdMultiMap,      stdMultiMap);
    WALBERLA_CHECK_EQUAL(recvStdMultiMapEmpty, stdMultiMapEmpty);
 
-   WALBERLA_CHECK_EQUAL(recvBoostArray, boostArray);
    WALBERLA_CHECK_EQUAL(recvStdArray,   stdArray);
 }