diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6dc6b88789af7f82399f3ba350f60f8d9335acdf..d1b2d69f1ea2bd288621dc545771cd116d493448 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,10 @@ SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
   also supports the syntax `DUNE_THROW(ExceptionType, a << b) << c << d` and
   `DUNE_THROW(ExceptionType) << a << b`.
 
+- Add concepts `Std::three_way_comparable` and `Std::three_way_comparable_with` as well as an
+  algorithm `Std::lexicographical_compare_three_way` to provide library utilities for the `<=>`
+  comparison operator.
+
 - Add deduction guides to `TupleVector` analogous to `std::tuple`.
 
 ## Build system: Changelog
diff --git a/dune/common/std/CMakeLists.txt b/dune/common/std/CMakeLists.txt
index ebe7a94c007671b88a449a9f67ebd9b5a4e9c22d..fd07678e466fd9717ea9d0a812e1e375d80c9151 100644
--- a/dune/common/std/CMakeLists.txt
+++ b/dune/common/std/CMakeLists.txt
@@ -2,6 +2,8 @@
 # SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
 
 install(FILES
+  algorithm.hh
+  compare.hh
   default_accessor.hh
   extents.hh
   functional.hh
diff --git a/dune/common/std/algorithm.hh b/dune/common/std/algorithm.hh
new file mode 100644
index 0000000000000000000000000000000000000000..eae792643dd1e3dcc7328fd9e85081c6415013d2
--- /dev/null
+++ b/dune/common/std/algorithm.hh
@@ -0,0 +1,62 @@
+// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
+// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_COMMON_STD_ALGORITHM_HH
+#define DUNE_COMMON_STD_ALGORITHM_HH
+
+#include <version>
+#if !(__cpp_impl_three_way_comparison >= 201907L && __cpp_lib_concepts && __has_include(<compare>))
+  #error "Three-way comparison requires language support!"
+#endif
+
+#include <algorithm>
+#include <compare>
+#include <type_traits>
+
+#include <dune/common/std/compare.hh>
+
+namespace Dune::Std {
+
+/**
+ * \brief Lexicographically compares two ranges `[first1, last1)` and `[first2, last2)`
+ * using three-way comparison and produces a result of the strongest applicable
+ * comparison category type.
+ *
+ * Implementation taken from https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare_three_way
+ *
+ * The standard implementation is available with libstdc++ >= 10 and libc++ >= 17
+ */
+#if __cpp_lib_three_way_comparison >= 201907L
+
+using std::lexicographical_compare_three_way;
+
+#else // __cpp_lib_three_way_comparison
+
+template <class I1, class I2, class Cmp = Std::compare_three_way>
+constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp = {})
+    -> decltype(comp(*f1, *f2))
+{
+  using ret_t = decltype(comp(*f1, *f2));
+  static_assert(std::disjunction_v<
+                    std::is_same<ret_t, std::strong_ordering>,
+                    std::is_same<ret_t, std::weak_ordering>,
+                    std::is_same<ret_t, std::partial_ordering>>,
+                "The return type must be a comparison category type.");
+
+  bool exhaust1 = (f1 == l1);
+  bool exhaust2 = (f2 == l2);
+  for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2))
+    if (auto c = comp(*f1, *f2); c != 0)
+      return c;
+
+  return !exhaust1 ? std::strong_ordering::greater:
+         !exhaust2 ? std::strong_ordering::less:
+                     std::strong_ordering::equal;
+}
+
+#endif // __cpp_lib_three_way_comparison
+
+} // end namespace Dune::Std
+
+#endif // DUNE_COMMON_STD_ALGORITHM_HH
diff --git a/dune/common/std/compare.hh b/dune/common/std/compare.hh
new file mode 100644
index 0000000000000000000000000000000000000000..2032ee68a96067cc4411aff5cb5993d66324b92f
--- /dev/null
+++ b/dune/common/std/compare.hh
@@ -0,0 +1,127 @@
+// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
+// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_COMMON_STD_COMPARE_HH
+#define DUNE_COMMON_STD_COMPARE_HH
+
+#include <compare>
+#include <concepts>
+#include <type_traits>
+#include <utility>
+
+/**
+ * \file This file provides some concepts introduced in the c++ standard library
+ * <compare> and <concepts> not yet available in all library implementation.
+ * The code is partially extracted from https://en.cppreference.com/w/cpp/utility/compare.
+ */
+
+namespace Dune::Std {
+namespace Impl {
+
+template <class T, class Cat>
+concept comparesAs =
+  std::same_as<std::common_comparison_category_t<T, Cat>, Cat>;
+
+template <class T, class U>
+concept weaklyEqualityComparableWith =
+  requires(const std::remove_reference_t<T>& t,
+           const std::remove_reference_t<U>& u)
+  {
+    { t == u } -> std::convertible_to<bool>;
+    { t != u } -> std::convertible_to<bool>;
+    { u == t } -> std::convertible_to<bool>;
+    { u != t } -> std::convertible_to<bool>;
+  };
+
+template <class T, class U>
+concept partiallyOrderedWith =
+  requires(const std::remove_reference_t<T>& t,
+           const std::remove_reference_t<U>& u)
+  {
+    { t <  u } -> std::convertible_to<bool>;
+    { t >  u } -> std::convertible_to<bool>;
+    { t <= u } -> std::convertible_to<bool>;
+    { t >= u } -> std::convertible_to<bool>;
+    { u <  t } -> std::convertible_to<bool>;
+    { u >  t } -> std::convertible_to<bool>;
+    { u <= t } -> std::convertible_to<bool>;
+    { u >= t } -> std::convertible_to<bool>;
+  };
+
+template <class T, class U, class C = std::common_reference_t<const T&, const U&>>
+concept comparisonCommonTypeWithImpl =
+  std::same_as<std::common_reference_t<const T&, const U&>,
+               std::common_reference_t<const U&, const T&>> &&
+  requires
+  {
+    requires std::convertible_to<const T&, const C&> ||
+      std::convertible_to<T, const C&>;
+    requires std::convertible_to<const U&, const C&> ||
+      std::convertible_to<U, const C&>;
+  };
+
+template <class T, class U>
+concept comparisonCommonTypeWith =
+  comparisonCommonTypeWithImpl<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
+
+} // end namespace Impl
+
+/**
+ * \brief The concept `std::three_way_comparable` specifies that the three way
+ * comparison `operator <=>` on `T` yield results consistent with the comparison
+ * category implied by `Cat`.
+ *
+ * The standard implementation is available in libstdc++ >= 10 and libc++ >= 14.
+ */
+template <class T, class Cat = std::partial_ordering>
+concept three_way_comparable =
+  Impl::weaklyEqualityComparableWith<T, T> &&
+  Impl::partiallyOrderedWith<T, T> &&
+  requires(const std::remove_reference_t<T>& a,
+           const std::remove_reference_t<T>& b)
+  {
+    { a <=> b } -> Impl::comparesAs<Cat>;
+  };
+
+
+/**
+ * \brief The concept `std::three_way_comparable_with` specifies that the three
+ * way comparison `operator <=>` on (possibly mixed) `T` and `U` operands yield
+ * results consistent with the comparison category implied by `Cat`. Comparing
+ * mixed operands yields results equivalent to comparing the operands converted
+ * to their common type.
+ *
+ * The standard implementation is available in libstdc++ >= 10 and libc++ >= 14.
+ */
+template <class T, class U, class Cat = std::partial_ordering>
+concept three_way_comparable_with =
+  Std::three_way_comparable<T, Cat> &&
+  Std::three_way_comparable<U, Cat> &&
+  Impl::comparisonCommonTypeWith<T, U> &&
+  Std::three_way_comparable<
+    std::common_reference_t<
+      const std::remove_reference_t<T>&,
+      const std::remove_reference_t<U>&>, Cat> &&
+  Impl::weaklyEqualityComparableWith<T, U> &&
+  Impl::partiallyOrderedWith<T, U> &&
+  requires(const std::remove_reference_t<T>& t,
+           const std::remove_reference_t<U>& u)
+  {
+    { t <=> u } -> Impl::comparesAs<Cat>;
+    { u <=> t } -> Impl::comparesAs<Cat>;
+  };
+
+//! A functor implementing the three-way comparison on the arguments
+struct compare_three_way
+{
+  template <class T, class U>
+  constexpr auto operator() (T&& t, U&& u) const
+  {
+    return std::forward<T>(t) <=> std::forward<U>(u);
+  }
+};
+
+} // end namespace Dune::Std
+
+#endif // DUNE_COMMON_STD_COMPARE_HH
diff --git a/dune/common/std/test/CMakeLists.txt b/dune/common/std/test/CMakeLists.txt
index e653c875fd488e9fd6e574adee3532263e72540c..81f5d188f8eee66f190146f90885366263bdc0cc 100644
--- a/dune/common/std/test/CMakeLists.txt
+++ b/dune/common/std/test/CMakeLists.txt
@@ -7,6 +7,12 @@ link_libraries(Dune::Common)
 dune_add_test(SOURCES accessorstest.cc
               LABELS quick)
 
+dune_add_test(SOURCES algorithmtest.cc
+              LABELS quick)
+
+dune_add_test(SOURCES comparetest.cc
+              LABELS quick)
+
 dune_add_test(SOURCES extentstest.cc
               LABELS quick)
 
diff --git a/dune/common/std/test/algorithmtest.cc b/dune/common/std/test/algorithmtest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..311792e55f3490c9b6967938757d858e9efcd0c9
--- /dev/null
+++ b/dune/common/std/test/algorithmtest.cc
@@ -0,0 +1,26 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
+// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
+#include <algorithm>
+#include <array>
+
+#include <dune/common/std/algorithm.hh>
+#include <dune/common/test/testsuite.hh>
+
+int main(int argc, char** argv)
+{
+  using namespace Dune;
+  TestSuite testSuite;
+
+  std::array<double, 10> arr1{};
+  std::array<double, 10> arr2{};
+
+  std::fill(arr1.begin(), arr1.end(), 1.0);
+  std::fill(arr2.begin(), arr2.end(), 2.0);
+
+  auto cmp = Std::lexicographical_compare_three_way(arr1.begin(), arr1.end(), arr2.begin(), arr2.end());
+  testSuite.check(cmp < 0);
+
+  return testSuite.exit();
+}
diff --git a/dune/common/std/test/comparetest.cc b/dune/common/std/test/comparetest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..166057cdfc874d9336203a6dfccd654f81ab2bf7
--- /dev/null
+++ b/dune/common/std/test/comparetest.cc
@@ -0,0 +1,17 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
+// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
+#include <dune/common/std/compare.hh>
+
+int main(int argc, char** argv)
+{
+  using namespace Dune;
+
+  static_assert(Std::three_way_comparable<double>);
+  static_assert(Std::three_way_comparable_with<double,double>);
+  static_assert(Std::three_way_comparable_with<double,float>);
+  static_assert(Std::three_way_comparable_with<double,int>);
+
+  static_assert(not Std::three_way_comparable_with<unsigned int,int>);
+}