A prior commit added std::extents, this commit adds the tests. The bulk
is focussed on testing the constructors. These are split into three
groups:

1. the ctor from other extents and the copy ctor,
2. the ctor from a pack of integer-like objects,
3. the ctor from shapes, i.e. span and array.

For each group check that the ctor:
* produces an object with the expected values for extent,
* is implicit if and only if required,
* is constexpr,
* doesn't change the rank of the extent.

libstdc++-v3/ChangeLog:

        * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: New 
test.
        * testsuite/23_containers/mdspan/extents/ctor_copy.cc: New test.
        * testsuite/23_containers/mdspan/extents/ctor_ints.cc: New test.
        * testsuite/23_containers/mdspan/extents/ctor_shape.cc: New test.
        * testsuite/23_containers/mdspan/extents/custom_integer.cc: New test.
        * testsuite/23_containers/mdspan/extents/misc.cc: New test.

Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com>
---
 .../mdspan/extents/class_mandates_neg.cc      |   8 +
 .../23_containers/mdspan/extents/ctor_copy.cc |  82 +++++++
 .../23_containers/mdspan/extents/ctor_ints.cc |  62 +++++
 .../mdspan/extents/ctor_shape.cc              | 160 +++++++++++++
 .../mdspan/extents/custom_integer.cc          |  87 +++++++
 .../23_containers/mdspan/extents/misc.cc      | 223 ++++++++++++++++++
 6 files changed, 622 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
 create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc

diff --git 
a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
new file mode 100644
index 00000000000..bbb3e0ad144
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++23 } }
+#include<mdspan>
+
+std::extents<std::int32_t, size_t(1) << 32> e1; // { dg-error "from here" }
+std::extents<double, 1> e2;                     // { dg-error "from here" }
+// { dg-prune-output "dynamic or representable as _IndexType" }
+// { dg-prune-output "must be integral" }
+// { dg-prune-output "invalid use of incomplete type" }
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy.cc
new file mode 100644
index 00000000000..a7b3a169301
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy.cc
@@ -0,0 +1,82 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+// Test the copy ctor and the ctor from other extents.
+
+constexpr auto dyn = std::dynamic_extent;
+
+// Not constructible
+static_assert(!std::is_constructible_v<std::extents<int>,
+                                      std::extents<int, 1>>);
+
+static_assert(!std::is_constructible_v<std::extents<int, 1, 1>,
+                                      std::extents<int, 1>>);
+
+static_assert(!std::is_constructible_v<std::extents<int, dyn>,
+                                      std::extents<int, dyn, dyn>>);
+
+static_assert(!std::is_constructible_v<std::extents<int, 2, 2>,
+                                      std::extents<int, 1, 2>>);
+
+// Nothrow constructible
+static_assert(std::is_nothrow_constructible_v<std::extents<int, 1>,
+                                             std::extents<unsigned int, dyn>>);
+static_assert(std::is_nothrow_constructible_v<std::extents<unsigned int, dyn>,
+                                             std::extents<int, 1>>);
+
+// Implicit conversion
+static_assert(!std::is_convertible_v<std::extents<unsigned int>,
+                                    std::extents<int>>);
+static_assert(std::is_convertible_v<std::extents<int>,
+                                   std::extents<unsigned int>>);
+
+static_assert(!std::is_convertible_v<std::extents<unsigned int, 1>,
+                                    std::extents<int, 1>>);
+static_assert(std::is_convertible_v<std::extents<int, 1>,
+                                   std::extents<unsigned int, 1>>);
+
+static_assert(!std::is_convertible_v<std::extents<int, dyn>,
+                                    std::extents<int, 1>>);
+static_assert(std::is_convertible_v<std::extents<int, 1>,
+                                   std::extents<int, dyn>>);
+
+static_assert(!std::is_convertible_v<std::extents<unsigned int, 1>,
+                                    std::extents<int, dyn>>);
+static_assert(std::is_convertible_v<std::extents<int, 1>,
+                                   std::extents<unsigned int, dyn>>);
+
+template<typename T, size_t... Extents, typename Other>
+  constexpr void
+  test_ctor(const Other& other)
+  {
+    auto e = std::extents<T, Extents...>(other);
+    VERIFY(e == other);
+  }
+
+constexpr int
+test_all()
+{
+  auto e0 = std::extents<int>();
+  test_ctor<int>(e0);
+
+  auto e1 = std::extents<int, 1, 2, 3>();
+  test_ctor<int, 1, 2, 3>(e1);
+  test_ctor<int, 1, dyn, 3>(e1);
+  test_ctor<unsigned int, 1, dyn, 3>(e1);
+
+  auto e2 = std::extents<unsigned int, 1, dyn, 3>{1, 2, 3};
+  test_ctor<int, 1, 2, 3>(e2);
+  test_ctor<int, 1, dyn, 3>(e2);
+  test_ctor<int, 1, dyn, dyn>(e2);
+  return true;
+}
+
+int
+main()
+{
+  test_all();
+  static_assert(test_all());
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
new file mode 100644
index 00000000000..53cf14d9bc5
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints.cc
@@ -0,0 +1,62 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+constexpr auto dyn = std::dynamic_extent;
+
+class A {};
+
+// Not constructible if the number of integer-like arguments isn't either
+// rank() or rank_dynamic().
+static_assert(!std::is_constructible_v<std::extents<int>, int>);
+static_assert(!std::is_constructible_v<std::extents<int, dyn, dyn>, int>);
+static_assert(!std::is_constructible_v<std::extents<int, 1, dyn, 3>, int, 
int>);
+
+// Not constructible from non integer-like objects.
+static_assert(!std::is_constructible_v<std::extents<int, 1>, int, A>);
+
+// No implicit conversion from integer-like objects.
+template<typename Extent, typename... OExtents>
+  constexpr bool
+  is_explicit()
+  {
+    return std::is_nothrow_constructible_v<Extent, OExtents...>
+          && !std::is_convertible_v<Extent, OExtents...>;
+  }
+
+static_assert(is_explicit<std::extents<int, 1>, int>());
+static_assert(is_explicit<std::extents<int, 1>, unsigned int>());
+static_assert(is_explicit<std::extents<unsigned int, 1>, int>());
+
+constexpr bool
+test_all()
+{
+  auto expected = std::extents<int, 1, 2, 3>(1, 2, 3);
+
+  // From all extents.
+  VERIFY((std::extents<int, 1, 2, 3>(1, 2, 3)) == expected);
+  VERIFY((std::extents<int, dyn, 2, 3>(1, 2, 3)) == expected);
+  VERIFY((std::extents<int, dyn, 2, dyn>(1, 2, 3)) == expected);
+
+  VERIFY((std::extents<int, 1, 2, 3>{1, 2, 3}) == expected);
+  VERIFY((std::extents<int, dyn, 2, 3>{1, 2, 3}) == expected);
+  VERIFY((std::extents<int, dyn, 2, dyn>{1, 2, 3}) == expected);
+
+  // From only dynamic extents.
+  VERIFY((std::extents<int, dyn, 2, 3>(1)) == expected);
+  VERIFY((std::extents<int, dyn, 2, dyn>(1, 3)) == expected);
+
+  VERIFY((std::extents<int, dyn, 2, 3>{1}) == expected);
+  VERIFY((std::extents<int, dyn, 2, dyn>{1, 3}) == expected);
+
+  return true;
+}
+
+int
+main()
+{
+  test_all();
+  static_assert(test_all);
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape.cc
new file mode 100644
index 00000000000..72e06df42ce
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape.cc
@@ -0,0 +1,160 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+constexpr auto dyn = std::dynamic_extent;
+
+template<typename Extent, typename T, size_t N>
+  constexpr bool
+  constructible()
+  {
+    return std::is_nothrow_constructible_v<Extent, std::array<T, N>>
+          && std::is_nothrow_constructible_v<Extent, std::span<T, N>>;
+  }
+
+template<typename Extent, typename T, size_t N>
+  constexpr bool
+  not_constructible()
+  {
+    return !std::is_constructible_v<Extent, std::array<T, N>>
+          && !std::is_constructible_v<Extent, std::span<T, N>>;
+  }
+
+template<typename Extent, typename T, size_t N>
+  constexpr bool
+  convertible()
+  {
+    return std::is_convertible_v<std::array<T, N>, Extent>
+          && std::is_convertible_v<std::span<T, N>, Extent>;
+  }
+
+template<typename Extent, typename T, size_t N>
+  constexpr bool
+  not_convertible()
+  {
+    return !std::is_convertible_v<std::array<T, N>, Extent>
+          && !std::is_convertible_v<std::span<T, N>, Extent>;
+  }
+
+static_assert(constructible<std::extents<int, 1, 2>, int, 2>);
+static_assert(not_constructible<std::extents<int, 1, 2>, int, 1>);
+
+static_assert(constructible<std::extents<int>, int, 0>());
+static_assert(convertible<std::extents<int>, int, 0>());
+static_assert(convertible<std::extents<unsigned int>, int, 0>());
+static_assert(convertible<std::extents<int>, unsigned int, 0>());
+
+static_assert(constructible<std::extents<int, 1, dyn>, int, 1>());
+static_assert(convertible<std::extents<int, 1, dyn>, int, 1>());
+static_assert(convertible<std::extents<unsigned int, 1, dyn>, int, 1>());
+static_assert(convertible<std::extents<int, 1, dyn>, unsigned int, 1>());
+
+static_assert(constructible<std::extents<int, 1, dyn>, int, 2>());
+static_assert(not_convertible<std::extents<int, 1, dyn>, int, 2>());
+static_assert(not_convertible<std::extents<unsigned int, 1, dyn>, int, 2>());
+static_assert(not_convertible<std::extents<int, 1, dyn>, unsigned int, 2>());
+
+// Non-integer, but convertible.
+static_assert(constructible<std::extents<int, dyn>, double, 1>());
+static_assert(convertible<std::extents<int, dyn>, double, 1>());
+
+namespace all_extents
+{
+  template<typename Shape>
+    constexpr void
+    test_ctor(Shape shape)
+    {
+      auto expected = std::extents<int, 1, 2, 3>();
+      VERIFY((std::extents<int, 1, dyn, 3>(shape)) == expected);
+      VERIFY((std::extents<int, dyn, dyn, dyn>(shape)) == expected);
+      VERIFY((std::extents<int, 1, 2, 3>(shape)) == expected);
+    }
+
+  constexpr void
+  test_common_shapes()
+  {
+    auto array = std::array<int, 3>{1, 2, 3};
+    auto span_const = std::span<const int, 3>(array);
+    auto span = std::span<int, 3>(array);
+
+    test_ctor(array);
+    test_ctor(span);
+    test_ctor(span_const);
+  }
+
+  constexpr void
+  test_empty_shapes()
+  {
+    auto shape = std::array<int, 0>();
+    auto span = std::span<int, 0>(shape);
+
+    auto expected = std::extents<int>();
+    VERIFY((std::extents<int>(shape)) == expected);
+    VERIFY((std::extents<int>(span)) == expected);
+  }
+
+  constexpr bool
+  test_all()
+  {
+    test_common_shapes();
+    test_empty_shapes();
+    return true;
+  }
+}
+
+namespace only_dynamic_extents
+{
+  template<typename Extents, typename Shape>
+    constexpr void
+    test_ctor(const Shape& shape)
+    {
+      Extents e = shape;
+
+      VERIFY(e.rank_dynamic() == shape.size());
+
+      size_t di = 0;
+      for(size_t i = 0; i < e.rank(); ++i)
+       if(e.static_extent(i) == dyn)
+         VERIFY(e.extent(i) == shape[di++]);
+    }
+
+  template<typename Extents, typename T, size_t N>
+    constexpr void
+    test_all_shape_types(std::array<T, N> shape)
+    {
+      test_ctor<Extents>(shape);
+      test_ctor<Extents>(std::span<T, N>(shape));
+      test_ctor<Extents>(std::span<const T, N>(shape));
+    }
+
+  constexpr void
+  test_common_shapes()
+  {
+    auto s = std::array<int, 0>{};
+    auto s2 = std::array<int, 1>{2};
+    auto s123 = std::array<int, 3>{1, 2, 3};
+
+    test_all_shape_types<std::extents<int, 1, dyn, 3>>(s2);
+    test_all_shape_types<std::extents<int, dyn, dyn, dyn>>(s123);
+    test_all_shape_types<std::extents<int, 1, 2, 3>>(s);
+  }
+
+  constexpr bool
+  test_all()
+  {
+    test_common_shapes();
+    return true;
+  }
+}
+
+int
+main()
+{
+  all_extents::test_all();
+  static_assert(all_extents::test_all());
+
+  only_dynamic_extents::test_all();
+  static_assert(only_dynamic_extents::test_all());
+  return 0;
+}
diff --git 
a/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
new file mode 100644
index 00000000000..2907ad12ae7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc
@@ -0,0 +1,87 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+// Test construction from a custom integer-like object, that has
+// no copy/move ctor or copy/move assignment operator.
+
+constexpr size_t dyn = std::dynamic_extent;
+
+class IntLike
+{
+public:
+  explicit
+  IntLike(int i)
+  : _M_i(i)
+  { }
+
+  IntLike() = delete;
+  IntLike(const IntLike&) = delete;
+  IntLike(IntLike&&) = delete;
+
+  const IntLike&
+  operator=(const IntLike&) = delete;
+
+  const IntLike&
+  operator=(IntLike&&) = delete;
+
+  constexpr
+  operator int() const noexcept
+  { return _M_i; }
+
+private:
+  int _M_i;
+};
+
+static_assert(std::is_convertible_v<IntLike, int>);
+static_assert(std::is_nothrow_constructible_v<int, IntLike>);
+
+void
+test_shape(const auto& s2, const auto& s23)
+{
+  std::extents<int, 2, 3> expected;
+
+  std::extents<int, 2, 3> e1(s23);
+  VERIFY(e1 == expected);
+
+  std::extents<int, dyn, 3> e2(s2);
+  VERIFY(e2 == expected);
+
+  std::extents<int, dyn, 3> e3(s23);
+  VERIFY(e3 == expected);
+
+  std::extents<int, dyn, dyn> e4(s23);
+  VERIFY(e4 == expected);
+}
+
+void
+test_pack()
+{
+  std::extents<int, 2, 3> expected;
+
+  std::extents<int, dyn, 3> e1(IntLike(2));
+  VERIFY(e1 == expected);
+
+  std::extents<int, dyn, 3> e2(IntLike(2), IntLike(3));
+  VERIFY(e2 == expected);
+
+  std::extents<int, dyn, dyn> e3(IntLike(2), IntLike(3));
+  VERIFY(e3 == expected);
+}
+
+int
+main()
+{
+  auto a2 = std::array<IntLike, 1>{IntLike(2)};
+  auto s2 = std::span<IntLike, 1>(a2);
+
+  auto a23 = std::array<IntLike, 2>{IntLike(2), IntLike(3)};
+  auto s23 = std::span<IntLike, 2>(a23);
+
+  test_shape(a2, a23);
+  test_shape(s2, s23);
+  test_pack();
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc 
b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
new file mode 100644
index 00000000000..98c47ce7892
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc
@@ -0,0 +1,223 @@
+// { dg-do run { target c++23 } }
+#include <mdspan>
+
+#include <testsuite_hooks.h>
+
+constexpr size_t dyn = std::dynamic_extent;
+
+// Check class traits.
+static_assert(std::regular<std::extents<int>>);
+static_assert(std::regular<std::extents<int, 1>>);
+static_assert(std::regular<std::extents<int, dyn>>);
+
+static_assert(std::is_trivially_copyable_v<std::extents<int>>);
+static_assert(std::is_trivially_copyable_v<std::extents<int, 1>>);
+static_assert(std::is_trivially_copyable_v<std::extents<int, dyn>>);
+
+// Check member typedefs.
+static_assert(std::is_same_v<std::extents<int, 1, 2>::rank_type, size_t>);
+
+static_assert(std::is_unsigned_v<std::extents<int, 2>::size_type>);
+static_assert(std::is_unsigned_v<std::extents<unsigned int, 2>::size_type>);
+
+static_assert(std::is_same_v<std::extents<char, 2>::index_type, char>);
+static_assert(std::is_same_v<std::extents<int, 2>::index_type, int>);
+static_assert(std::is_same_v<std::extents<unsigned int, 2>::index_type,
+             unsigned int>);
+
+// Check `rank`.
+static_assert(std::extents<int, 1>::rank() == 1);
+static_assert(std::extents<int, dyn>::rank() == 1);
+static_assert(std::extents<int, 2, dyn>::rank() == 2);
+
+// Check `rank_dynamic`.
+static_assert(std::extents<int, 1>::rank_dynamic() == 0);
+static_assert(std::extents<int, dyn>::rank_dynamic() == 1);
+static_assert(std::extents<int, 2, dyn>::rank_dynamic() == 1);
+static_assert(std::extents<int, dyn, dyn>::rank_dynamic() == 2);
+
+template<typename T, size_t... Extents>
+  constexpr bool
+  check_rank_return_types()
+  {
+    auto e = std::extents<T, Extents...>();
+    return std::is_same_v<decltype(e.rank()), size_t>
+          && std::is_same_v<decltype(e.rank_dynamic()), size_t>;
+  }
+
+static_assert(check_rank_return_types<int, 1>());
+
+// Check that the static extents don't take up space.
+static_assert(sizeof(std::extents<int, 1, dyn>) == sizeof(int));
+static_assert(sizeof(std::extents<char, 1, dyn>) == sizeof(char));
+
+template<typename Extents>
+class Container
+{
+  int dummy;
+  [[no_unique_address]] std::extents<size_t> b0;
+};
+
+static_assert(sizeof(Container<std::extents<char, 1, 2>>) == sizeof(int));
+static_assert(sizeof(Container<std::extents<size_t, 1, 2>>) == sizeof(int));
+
+// operator=
+static_assert(std::is_nothrow_assignable_v<std::extents<int, dyn, 2>,
+                                          std::extents<int, 1, 2>>);
+
+constexpr bool
+test_assign()
+{
+  auto e1 = std::extents<int, 1, 2>();
+  auto e2 = std::extents<int, 1, 2>();
+
+  e2 = e1;
+  VERIFY(e2 == e1);
+
+  auto e5 = std::extents<int, 1, dyn>();
+  e5 = e1;
+  VERIFY(e5 == e1);
+
+  auto e3 = std::extents<int, dyn, dyn>(1, 2);
+  auto e4 = std::extents<int, dyn, dyn>(3, 4);
+  e3 = e4;
+  VERIFY(e3 == e4);
+  return true;
+}
+
+// Deduction guide
+template<size_t Rank, typename... Extents>
+constexpr void
+test_deduction(Extents... exts)
+{
+  std::array<size_t, sizeof...(exts)> shape{static_cast<size_t>(exts)...};
+  std::dextents<size_t, Rank> expected(shape);
+  std::extents e(exts...);
+  static_assert(std::is_same_v<decltype(e), std::dextents<size_t, Rank>>);
+  VERIFY(e == expected);
+}
+
+constexpr bool
+test_deduction_all()
+{
+  test_deduction<0>();
+  test_deduction<1>(1);
+  test_deduction<2>(1.0, 2.0f);
+  test_deduction<3>(int(1), char(2), size_t(3));
+  return true;
+}
+
+class A {};
+
+template<typename... Extents>
+  concept deducible = requires
+  {
+    { std::extents(Extents{}...) }
+      -> std::convertible_to<std::dextents<size_t, sizeof...(Extents)>>;
+  };
+
+static_assert(deducible<int>);
+static_assert(!deducible<A, A>);
+
+// dextents
+static_assert(std::is_same_v<std::dextents<int, 0>, std::extents<int>>);
+static_assert(std::is_same_v<std::dextents<int, 1>, std::extents<int, dyn>>);
+static_assert(std::is_same_v<std::dextents<int, 5>,
+             std::extents<int, dyn, dyn, dyn, dyn, dyn>>);
+
+static_assert(std::dextents<int, 5>::rank() == 5);
+static_assert(std::dextents<int, 5>::rank_dynamic() == 5);
+static_assert(std::is_same_v<typename std::dextents<int, 5>::index_type, int>);
+
+// static_extent
+static_assert(std::extents<int, 1, 2>::static_extent(0) == 1);
+static_assert(std::extents<int, 1, 2>::static_extent(1) == 2);
+
+static_assert(std::extents<int, 1, dyn>::static_extent(0) == 1);
+static_assert(std::extents<int, 1, dyn>::static_extent(1) == dyn);
+
+static_assert(std::extents<int, dyn, dyn>::static_extent(0) == dyn);
+static_assert(std::extents<int, dyn, dyn>::static_extent(1) == dyn);
+
+// extent
+template<typename Extent>
+  constexpr void
+  test_extent(const Extent& e, const std::array<size_t, Extent::rank()>& shape)
+  {
+    for(size_t i = 0; i < e.rank(); ++i)
+      VERIFY(e.extent(i) == shape[i]);
+  }
+
+constexpr bool
+test_extent_all()
+{
+  test_extent(std::extents<int, 1, 2>{}, {1, 2});
+  test_extent(std::extents<int, 1, dyn>{2}, {1, 2});
+  test_extent(std::extents<int, dyn, dyn>{1, 2}, {1, 2});
+  return true;
+}
+
+// operator==
+template<typename Lhs, typename Rhs>
+  constexpr void
+  test_ops_eq(const Lhs& lhs, const Rhs& rhs, bool expected)
+  {
+    VERIFY((lhs == rhs) == expected);
+    VERIFY((lhs != rhs) == !expected);
+  }
+
+constexpr void
+test_op_eq_rank_zero()
+{
+  auto e1 = std::extents<int>();
+  auto e2 = std::extents<int>();
+  auto e3 = std::extents<unsigned int>();
+
+  test_ops_eq(e1, e2, true);
+  test_ops_eq(e1, e3, true);
+}
+
+constexpr void
+test_op_eq_common()
+{
+  auto e1 = std::extents<int, 1, 2, 3>();
+  auto e2 = std::extents<int, 1, 2, 3>();
+  auto e3 = std::extents<int, 1, dyn, 3>(2);
+  auto e4 = std::extents<int, 1, dyn, 3>(3);
+
+  auto e5 = std::extents<int, 1>();
+  auto e6 = std::extents<int, 1, 3, 3>();
+
+  test_ops_eq(e1, e2, true);
+  test_ops_eq(e1, e3, true);
+  test_ops_eq(e1, e4, false);
+
+  test_ops_eq(e1, e5, false);
+  test_ops_eq(e1, e6, false);
+  test_ops_eq(e3, e6, false);
+}
+
+constexpr bool
+test_op_eq_all()
+{
+  test_op_eq_rank_zero();
+  test_op_eq_common();
+  return true;
+}
+
+int
+main()
+{
+  test_assign();
+  static_assert(test_assign());
+
+  test_deduction_all();
+  static_assert(test_deduction_all());
+
+  test_extent_all();
+  static_assert(test_extent_all());
+
+  test_op_eq_all();
+  static_assert(test_op_eq_all());
+  return 0;
+}
-- 
2.49.0

Reply via email to