diff --git a/CMakeLists.txt b/CMakeLists.txt
index b579381c6aa1455481c396bfac8644e7d83740f4..14c5d015fa5c8010f2c1ea1b40bf06ef37ecac21 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -474,6 +474,30 @@ else()
    endif()
 endif()
 
+try_compile( WALBERLA_USE_STD_ANY "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdAny.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_ANY -std=c++14 )
+if( WALBERLA_USE_STD_ANY )
+   message( STATUS "Found std::any")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_ANY "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdAny.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_ANY -std=c++14 )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_ANY )
+      message( STATUS "Found std::experimental::any")
+   endif()
+endif()
+
+try_compile( WALBERLA_USE_STD_OPTIONAL "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdOptional.cpp"
+             COMPILE_DEFINITIONS -DWALBERLA_USE_STD_OPTIONAL -std=c++14 )
+if( WALBERLA_USE_STD_OPTIONAL )
+   message( STATUS "Found std::optional")
+else()
+   try_compile( WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/cmake/TestStdOptional.cpp"
+                COMPILE_DEFINITIONS -DWALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL -std=c++14 )
+   if( WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL )
+      message( STATUS "Found std::experimental::optional")
+   endif()
+endif()
+
 
 
 ############################################################################################################################
diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
index 695cc61f63a56b412975a7cc9c912dc39fe016af..ed907fc37b06df8e3e54691bebc52bc7ea7c495f 100644
--- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
+++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
@@ -1285,7 +1285,7 @@ public:
       markEmptyBlocks_( markEmptyBlocks ), state_( state )
    {}
    
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
@@ -1309,7 +1309,7 @@ struct Pseudo2DPhantomWeightPackUnpack
       buffer << block.getData< Pseudo2DPhantomWeight >().weight();
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       Pseudo2DPhantomWeight::weight_t w;
       buffer >> w;
diff --git a/cmake/TestStdAny.cpp b/cmake/TestStdAny.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b7e22269737d293cab1daba5d4030c186b5fcd8
--- /dev/null
+++ b/cmake/TestStdAny.cpp
@@ -0,0 +1,16 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_ANY)
+#include <any>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+#include <experimental/any>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_ANY)
+   auto a = std::any(42);
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+   auto a = std::experimental::any(42);
+#endif
+   std::cout << std::experimental::any_cast<int>(a) << std::endl;
+   return 0;
+}
diff --git a/cmake/TestStdOptional.cpp b/cmake/TestStdOptional.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc3a148c128e534eb37fc635c697d1e88961a6db
--- /dev/null
+++ b/cmake/TestStdOptional.cpp
@@ -0,0 +1,19 @@
+#include <iostream>
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+#include <optional>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+#include <experimental/optional>
+#endif
+
+int main() {
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+   auto a = std::optional<int>();
+   auto b = std::optional<int>(42);
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+   auto a = std::experimental::optional<int>();
+   auto b = std::experimental::optional<int>(42);
+#endif
+   if (b)
+      std::cout << a.value_or(b.value()) << std::endl;
+   return 0;
+}
diff --git a/src/blockforest/PhantomBlock.h b/src/blockforest/PhantomBlock.h
index a209e1a17b4a87e79351360c2e314ece047b342e..7f42061abc56b1332af0be31cd1fdfbeda83beb3 100644
--- a/src/blockforest/PhantomBlock.h
+++ b/src/blockforest/PhantomBlock.h
@@ -28,11 +28,10 @@
 #include "core/debug/Debug.h"
 #include "core/math/AABB.h"
 #include "core/uid/SUID.h"
+#include "core/Any.h"
 
 #include <vector>
 
-#include <boost/any.hpp>
-
 
 
 namespace walberla {
@@ -86,7 +85,7 @@ public:
    void addData( const T & data ) { data_ = data; }
    
    template< typename T >
-   T getData() const { return boost::any_cast<T>( data_ ); }
+   T getData() const { return walberla::any_cast<T>( data_ ); }
    
    bool hasData() const { return !(data_.empty()); }
    
@@ -143,7 +142,7 @@ private:
    uint_t level_;
 
    // set by the user/application via callback
-   boost::any data_;
+   walberla::any data_;
 
    std::vector< NeighborBlock* > neighborhoodSection_[26]; // the 26 neighborhood sections (can be restored from 'neighborhood_')
    std::vector< NeighborBlock  > neighborhood_;            // all neighbor blocks
diff --git a/src/blockforest/PhantomBlockForest.cpp b/src/blockforest/PhantomBlockForest.cpp
index 691cfe744bffa45cf7c790c86699f7a5e84dcba5..196ba5529e2b24b8825ea8a5903d9191cc83814f 100644
--- a/src/blockforest/PhantomBlockForest.cpp
+++ b/src/blockforest/PhantomBlockForest.cpp
@@ -256,13 +256,13 @@ void PhantomBlockForest::assignBlockData( const PhantomBlockDataAssignmentFuncti
 {
    if( function )
    {
-      std::vector< std::pair< const PhantomBlock *, boost::any > > blockData;
+      std::vector< std::pair< const PhantomBlock *, walberla::any > > blockData;
    
       for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
       {
          auto & block = it->second;
          WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
-         blockData.push_back( std::make_pair( block.get(), boost::any() ) );
+         blockData.push_back( std::make_pair( block.get(), walberla::any() ) );
       }
       
       function( blockData, *this );
@@ -484,7 +484,7 @@ void PhantomBlockForest::migrate( const PhantomBlockDataPackFunction & packBlock
          if( unpackBlockData )
          {
             WALBERLA_ASSERT( static_cast<bool>(packBlockData) );
-            boost::any data;
+            walberla::any data;
             unpackBlockData( buffer, *phantom, data );
             phantom->addData( data );
          }
diff --git a/src/blockforest/PhantomBlockForest.h b/src/blockforest/PhantomBlockForest.h
index 797a29cbe28ee0a0463d69a9cd5417e90347a8b6..1c7285167da9295ab15394133195f812406e1626 100644
--- a/src/blockforest/PhantomBlockForest.h
+++ b/src/blockforest/PhantomBlockForest.h
@@ -45,7 +45,7 @@ public:
    typedef std::function< Set<SUID> ( const std::vector< std::pair< BlockID, Set<SUID> > > & source, const BlockID & destintation ) >
            BlockStateDeterminationFunction;
 
-   typedef std::function< void ( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData,
+   typedef std::function< void ( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData,
                                    const PhantomBlockForest & phantomForest ) >
            PhantomBlockDataAssignmentFunction;
 
@@ -58,7 +58,7 @@ public:
            MigrationPreparationFunction; // = load balancing
 
    typedef std::function< void ( mpi::SendBuffer & buffer, const PhantomBlock & block ) >                    PhantomBlockDataPackFunction;
-   typedef std::function< void ( mpi::RecvBuffer & buffer, const PhantomBlock & block, boost::any & data ) > PhantomBlockDataUnpackFunction;
+   typedef std::function< void ( mpi::RecvBuffer & buffer, const PhantomBlock & block, walberla::any & data ) > PhantomBlockDataUnpackFunction;
 
 
 
diff --git a/src/blockforest/loadbalancing/DynamicParMetis.h b/src/blockforest/loadbalancing/DynamicParMetis.h
index 1fa7667ee3aa4932015291edccd2fbd87c336d0b..927ca25698c5257a667674535d9838191634c1a6 100644
--- a/src/blockforest/loadbalancing/DynamicParMetis.h
+++ b/src/blockforest/loadbalancing/DynamicParMetis.h
@@ -119,7 +119,7 @@ struct DynamicParMetisBlockInfoPackUnpack
       block.getData< DynamicParMetisBlockInfo >().toBuffer( buffer );
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       data = DynamicParMetisBlockInfo( buffer );
    }
diff --git a/src/blockforest/loadbalancing/PODPhantomData.h b/src/blockforest/loadbalancing/PODPhantomData.h
index ccf514a1f6ec3af8192d70cd48f58e07af1e5561..2be8c77cecf13525222529e9dfbc2d31dfd35cea 100644
--- a/src/blockforest/loadbalancing/PODPhantomData.h
+++ b/src/blockforest/loadbalancing/PODPhantomData.h
@@ -53,7 +53,7 @@ struct PODPhantomWeightPackUnpack
       buffer << block.getData< PODPhantomWeight<T> >().weight();
    }
 
-   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, boost::any & data )
+   void operator()( mpi::RecvBuffer & buffer, const PhantomBlock &, walberla::any & data )
    {
       typename PODPhantomWeight<T>::weight_t w;
       buffer >> w;
diff --git a/src/core/Any.h b/src/core/Any.h
new file mode 100644
index 0000000000000000000000000000000000000000..2799c1e8525fc4176e6dc7b98c3e791716c43f13
--- /dev/null
+++ b/src/core/Any.h
@@ -0,0 +1,48 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) any later version.
+//
+//  waLBerla is distributed in the hope that it will be useful, but WITHOUT
+//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Any.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_ANY)
+#include <any>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+#include <experimental/any>
+#else
+#include <boost/any.hpp>
+#endif
+
+
+
+namespace walberla {
+
+#if defined(WALBERLA_USE_STD_ANY)
+using std::any;
+using std::any_cast;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_ANY)
+using std::experimental::any;
+using std::experimental::any_cast;
+#else
+using boost::any;
+using boost::any_cast;
+#endif
+
+}
diff --git a/src/core/Optional.h b/src/core/Optional.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad23d1666a07716c717591f4b188291869a74626
--- /dev/null
+++ b/src/core/Optional.h
@@ -0,0 +1,48 @@
+//======================================================================================================================
+//
+//  This file is part of waLBerla. waLBerla is free software: you can
+//  redistribute it and/or modify it under the terms of the GNU General Public
+//  License as published by the Free Software Foundation, either version 3 of
+//  the License, or (at your option) OPTIONAL later version.
+//
+//  waLBerla is distributed in the hope that it will be useful, but WITHOUT
+//  OPTIONAL WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+//  for more details.
+//
+//  You should have received a copy of the GNU General Public License along
+//  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
+//
+//! \file Optional.h
+//! \ingroup core
+//! \author Michael Kuron <mkuron@icp.uni-stuttgart.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+#include <optional>
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+#include <experimental/optional>
+#else
+#include <boost/optional.hpp>
+#endif
+
+
+
+namespace walberla {
+
+#if defined(WALBERLA_USE_STD_OPTIONAL)
+using std::optional;
+using std::nullopt;
+#elif defined(WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL)
+using std::experimental::optional;
+using std::experimental::nullopt;
+#else
+using boost::optional;
+const boost::none_t nullopt = boost::none;
+#endif
+
+}
diff --git a/src/core/mpi/BufferDataTypeExtensions.h b/src/core/mpi/BufferDataTypeExtensions.h
index 47d22bacac8bbdd0659dedc8792762289ce1e60a..b05128c4a193aebd46f9f31fec2ed89dc41c30ec 100644
--- a/src/core/mpi/BufferDataTypeExtensions.h
+++ b/src/core/mpi/BufferDataTypeExtensions.h
@@ -27,10 +27,10 @@
 #include "SendBuffer.h"
 #include "core/Conversion.h"
 #include "core/DataTypes.h"
+#include "core/Optional.h"
 
 #include <boost/array.hpp>
 #include <boost/integer.hpp>
-#include <boost/optional.hpp>
 #include <boost/uuid/uuid.hpp>
 
 #include <deque>
@@ -465,18 +465,18 @@ struct BufferSizeTrait< std::multimap<K,T,C,A> > { static const bool constantSiz
 
 
 // ---------------------------------------------------------------------------------------------------------------------
-// ------------------------------------- Boost optional Support --------------------------------------------------------
+// ------------------------------------------- optional Support --------------------------------------------------------
 // ---------------------------------------------------------------------------------------------------------------------
 
 template< typename T,    // Element type of SendBuffer
           typename G,    // Growth policy of SendBuffer
           typename OT>   // Optional type
-GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const boost::optional<OT> & o )
+GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const walberla::optional<OT> & o )
 {
    buf.addDebugMarker( "op" );
 
    bool hasContent = true;
-   if (o == boost::none)
+   if (o == walberla::nullopt)
       hasContent = false;
 
    buf << hasContent;
@@ -489,7 +489,7 @@ GenericSendBuffer<T,G>& operator<<( GenericSendBuffer<T,G> & buf, const boost::o
 
 template< typename T,    // Element type of RecvBuffer
           typename OT>   // Optional type
-GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, boost::optional<OT> & o )
+GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, walberla::optional<OT> & o )
 {
    buf.readDebugMarker( "op" );
 
@@ -509,7 +509,7 @@ GenericRecvBuffer<T>& operator>>( GenericRecvBuffer<T> & buf, boost::optional<OT
    }
    else
    {
-      o = boost::none;
+      o = walberla::nullopt;
    }
 
    return buf;
diff --git a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
index 3b03af49e8dfcf5b48772351c7afac2678f7204f..bed28616694dbdbff30914cba828d0ed22c6d6fe 100644
--- a/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/MetisAssignmentFunctor.h
@@ -38,7 +38,7 @@ public:
    MetisAssignmentFunctor( const shared_ptr<InfoCollection>& ic ) : ic_( ic )
    {}
 
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
diff --git a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
index 3a6b5d9b2ad34969bbdcfcd0e021ff42bcd33f60..a2cd0fc06937291b14c119f912fdafb1005f340a 100644
--- a/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
+++ b/src/pe/amr/weight_assignment/WeightAssignmentFunctor.h
@@ -40,7 +40,7 @@ public:
 
    WeightAssignmentFunctor( shared_ptr<InfoCollection>& ic ) : ic_(ic) {}
 
-   void operator()( std::vector< std::pair< const PhantomBlock *, boost::any > > & blockData, const PhantomBlockForest & )
+   void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
       for( auto it = blockData.begin(); it != blockData.end(); ++it )
       {
diff --git a/src/waLBerlaDefinitions.in.h b/src/waLBerlaDefinitions.in.h
index 703bee6fc4abe6601631380f31fe9e50b28e3eba..26b6627685ab451ae693fb32f8af4dfe0080d8aa 100644
--- a/src/waLBerlaDefinitions.in.h
+++ b/src/waLBerlaDefinitions.in.h
@@ -44,6 +44,10 @@
 
 #cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_FILESYSTEM
 #cmakedefine WALBERLA_USE_STD_FILESYSTEM
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_ANY
+#cmakedefine WALBERLA_USE_STD_ANY
+#cmakedefine WALBERLA_USE_STD_EXPERIMENTAL_OPTIONAL
+#cmakedefine WALBERLA_USE_STD_OPTIONAL
 
 // SIMD
 #cmakedefine WALBERLA_SIMD_FORCE_SCALAR
diff --git a/tests/core/mpi/BufferTest.cpp b/tests/core/mpi/BufferTest.cpp
index 34f961f1a5505211c2e538e5dcf82edf758424ef..c34a1ef8e89d2a138031ba1dde8092be69e7f40a 100644
--- a/tests/core/mpi/BufferTest.cpp
+++ b/tests/core/mpi/BufferTest.cpp
@@ -263,7 +263,7 @@ void bufferTestUInt8()
 {
    std::string stdString("Hello World!"), stdStringEmpty;
 
-   boost::optional<int> optional0, optional1, optional2, optional3;
+   walberla::optional<int> optional0, optional1, optional2, optional3;
    optional2 = 23;
    optional3 = 42;
 
@@ -277,7 +277,7 @@ void bufferTestUInt8()
 
    std::string recvStdString, recvStdStringEmpty;
 
-   boost::optional<int> recvOptional0, recvOptional1, recvOptional2, recvOptional3;
+   walberla::optional<int> recvOptional0, recvOptional1, recvOptional2, recvOptional3;
 
    recvOptional0 = 123;
    recvOptional1 = 123;