A prior commit added std::extents, this commits 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/assign_copy.cc: New test. * testsuite/23_containers/mdspan/extents/assign_copy_01_neg.cc: New test. * testsuite/23_containers/mdspan/extents/class_traits.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_01_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_02_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_constexpr.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_implicit_00.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_implicit_01.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_implicit_02_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_implicit_03_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_copy_implicit_04_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_00.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_01.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_02_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_03_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_constexpr.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_implicit_00_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_ints_implicit_01_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_00.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_01.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_02_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_03_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_constexpr.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_implicit_00.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_implicit_01.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_implicit_02_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_implicit_03_neg.cc: New test. * testsuite/23_containers/mdspan/extents/ctor_shape_implicit_04.cc: New test. * testsuite/23_containers/mdspan/extents/custom_integer.cc: New test. * testsuite/23_containers/mdspan/extents/deduction_guide_00.cc: New test. * testsuite/23_containers/mdspan/extents/deduction_guide_01_neg.cc: New test. * testsuite/23_containers/mdspan/extents/dextents.cc: New test. * testsuite/23_containers/mdspan/extents/extent.cc: New test. * testsuite/23_containers/mdspan/extents/index_type.cc: New test. * testsuite/23_containers/mdspan/extents/ops_eq.cc: New test. * testsuite/23_containers/mdspan/extents/rank.cc: New test. * testsuite/23_containers/mdspan/extents/rank_dynamic.cc: New test. * testsuite/23_containers/mdspan/extents/rank_return_type.cc: New test. * testsuite/23_containers/mdspan/extents/rank_type.cc: New test. * testsuite/23_containers/mdspan/extents/size_type.cc: New test. * testsuite/23_containers/mdspan/extents/sizeof.cc: New test. * testsuite/23_containers/mdspan/extents/static_extent.cc: New test. Signed-off-by: Luc Grosheintz <luc.groshei...@gmail.com> --- .../mdspan/extents/assign_copy.cc | 26 ++++++ .../mdspan/extents/assign_copy_01_neg.cc | 15 ++++ .../mdspan/extents/class_traits.cc | 20 +++++ .../23_containers/mdspan/extents/ctor_copy.cc | 34 ++++++++ .../mdspan/extents/ctor_copy_01_neg.cc | 10 +++ .../mdspan/extents/ctor_copy_02_neg.cc | 10 +++ .../mdspan/extents/ctor_copy_constexpr.cc | 20 +++++ .../mdspan/extents/ctor_copy_implicit_00.cc | 28 ++++++ .../mdspan/extents/ctor_copy_implicit_01.cc | 22 +++++ .../extents/ctor_copy_implicit_02_neg.cc | 10 +++ .../extents/ctor_copy_implicit_03_neg.cc | 9 ++ .../extents/ctor_copy_implicit_04_neg.cc | 9 ++ .../mdspan/extents/ctor_ints_00.cc | 30 +++++++ .../mdspan/extents/ctor_ints_01.cc | 24 ++++++ .../mdspan/extents/ctor_ints_02_neg.cc | 9 ++ .../mdspan/extents/ctor_ints_03_neg.cc | 9 ++ .../mdspan/extents/ctor_ints_constexpr.cc | 12 +++ .../extents/ctor_ints_implicit_00_neg.cc | 9 ++ .../extents/ctor_ints_implicit_01_neg.cc | 9 ++ .../mdspan/extents/ctor_shape_00.cc | 35 ++++++++ .../mdspan/extents/ctor_shape_01.cc | 17 ++++ .../mdspan/extents/ctor_shape_02_neg.cc | 10 +++ .../mdspan/extents/ctor_shape_03_neg.cc | 11 +++ .../mdspan/extents/ctor_shape_constexpr.cc | 23 +++++ .../mdspan/extents/ctor_shape_implicit_00.cc | 42 +++++++++ .../mdspan/extents/ctor_shape_implicit_01.cc | 19 ++++ .../extents/ctor_shape_implicit_02_neg.cc | 11 +++ .../extents/ctor_shape_implicit_03_neg.cc | 12 +++ .../mdspan/extents/ctor_shape_implicit_04.cc | 24 ++++++ .../mdspan/extents/custom_integer.cc | 86 +++++++++++++++++++ .../mdspan/extents/deduction_guide_00.cc | 23 +++++ .../mdspan/extents/deduction_guide_01_neg.cc | 10 +++ .../23_containers/mdspan/extents/dextents.cc | 11 +++ .../23_containers/mdspan/extents/extent.cc | 27 ++++++ .../mdspan/extents/index_type.cc | 14 +++ .../23_containers/mdspan/extents/ops_eq.cc | 58 +++++++++++++ .../23_containers/mdspan/extents/rank.cc | 10 +++ .../mdspan/extents/rank_dynamic.cc | 11 +++ .../mdspan/extents/rank_return_type.cc | 14 +++ .../23_containers/mdspan/extents/rank_type.cc | 7 ++ .../23_containers/mdspan/extents/size_type.cc | 16 ++++ .../23_containers/mdspan/extents/sizeof.cc | 10 +++ .../mdspan/extents/static_extent.cc | 15 ++++ 43 files changed, 831 insertions(+) create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy_01_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/class_traits.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_copy_01_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_02_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_constexpr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_00.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_01.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_02_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_03_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_04_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_00.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_01.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_02_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_03_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_constexpr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_00_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_01_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_00.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_01.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_02_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_03_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_constexpr.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_00.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_01.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_02_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_03_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_04.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_00.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_01_neg.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/dextents.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/extent.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/index_type.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/ops_eq.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/rank.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_dynamic.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_return_type.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_type.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/size_type.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/sizeof.cc create mode 100644 libstdc++-v3/testsuite/23_containers/mdspan/extents/static_extent.cc diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy.cc new file mode 100644 index 00000000000..ba7e495a817 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy.cc @@ -0,0 +1,26 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +int +main() +{ + 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 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy_01_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy_01_neg.cc new file mode 100644 index 00000000000..8a514f2207b --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/assign_copy_01_neg.cc @@ -0,0 +1,15 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +void +test_assigment() +{ + auto e1 = std::extents<int, 1, 2>(); + auto e2 = std::extents<int, 1, dyn>(); + + e1 = e2; +} + +// { dg-error "no match for 'operator=" "" { target *-*-* } 12 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_traits.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_traits.cc new file mode 100644 index 00000000000..ae6ea988a1a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_traits.cc @@ -0,0 +1,20 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + +template <std::regular T> + struct is_regular + { + static constexpr bool value = true; + }; + +constexpr auto dyn = std::dynamic_extent; + +static_assert(is_regular<std::extents<int>>::value); +static_assert(is_regular<std::extents<int, 1>>::value); +static_assert(is_regular<std::extents<int, dyn>>::value); + +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>>); 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..02cd1444e3f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy.cc @@ -0,0 +1,34 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +// Test that ctor from other extents creates an object from that's equal to the +// original. + +constexpr auto dyn = std::dynamic_extent; + +template<class T, size_t ... Extents, class Other> + void + test_copy_ctor_explicit(const Other& other) + { + auto e = std::extents<T, Extents...>(other); + VERIFY(e == other); + } + +int +main() +{ + auto e0 = std::extents<int>(); + test_copy_ctor_explicit<int>(e0); + + auto e1 = std::extents<int, 1, 2, 3>(); + test_copy_ctor_explicit<int, 1, 2, 3>(e1); + test_copy_ctor_explicit<int, 1, dyn, 3>(e1); + + auto e2 = std::extents<int, 1, dyn, 3>{1, 2, 3}; + test_copy_ctor_explicit<int, 1, 2, 3>(e2); + test_copy_ctor_explicit<int, 1, dyn, 3>(e2); + test_copy_ctor_explicit<int, 1, dyn, dyn>(e2); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_01_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_01_neg.cc new file mode 100644 index 00000000000..8a859924e6a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_01_neg.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check Self::rank != Other::rank + +constexpr auto dyn = std::dynamic_extent; +std::extents<int, 1, dyn> e1; +std::extents<int, 1, dyn, 3> e2(e1); + +// { dg-error "no matching function for call" "" { target *-*-* } 8 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_02_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_02_neg.cc new file mode 100644 index 00000000000..51fab74ccbd --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_02_neg.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check when static extents differ. + +constexpr auto dyn = std::dynamic_extent; +std::extents<int, 1, dyn> e1; +std::extents<int, 2, dyn> e2(e1); + +// { dg-error "no matching function for call" "" { target *-*-* } 8 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_constexpr.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_constexpr.cc new file mode 100644 index 00000000000..49fa023c354 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_constexpr.cc @@ -0,0 +1,20 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Test that the ctor from other extents is constexpr. + +constexpr auto dyn = std::dynamic_extent; + +constexpr std::extents<int> e0; +constexpr std::extents<int> e1 = e0; + +constexpr std::extents<int, 1> e2; +constexpr std::extents<int, 1> e3 = e2; +static_assert(e3 == e2); + +constexpr std::extents<int, dyn> e4 = e2; +static_assert(e4 == e2); + +constexpr std::extents<int, 3, 5> e5; +constexpr std::extents<int, dyn, 5> e6 = e5; +static_assert(e6 == e5); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_00.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_00.cc new file mode 100644 index 00000000000..1c8b0b9f011 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_00.cc @@ -0,0 +1,28 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +// Test that implicit conversion is permitted if the extents can't be +// incompatible. +int +main() +{ + constexpr auto dyn = std::dynamic_extent; + + auto e1 = std::extents<int, 1, 2, 3>(); + std::extents<int, 1, 2, 3> e2 = e1; + VERIFY(e1 == e2); + + auto shape = std::array<int, 3>{1, 2, 3}; + auto e3 = std::extents<int, 1, dyn, 3>(shape); + std::extents<int, 1, dyn, 3> e4 = e3; + VERIFY(e4 == e3); + + std::extents<int, 1, dyn, dyn> e5 = e3; + VERIFY(e5 == e3); + + std::extents<unsigned int, 1, dyn, 3> e6 = e1; + VERIFY(e6 == e1); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_01.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_01.cc new file mode 100644 index 00000000000..13c082be729 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_01.cc @@ -0,0 +1,22 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +// Test that implicit conversion is permitted if overflow isn't possible. +int +main() +{ + constexpr auto dyn = std::dynamic_extent; + + auto e0 = std::extents<int>(); + std::extents<unsigned int> e1 = e0; + + auto e3 = std::extents<int, 1, 2, 3>(); + std::extents<unsigned int, 1, 2, 3> e4 = e3; + VERIFY(e4 == e3); + + std::extents<unsigned int, 1, dyn, 3> e5 = e3; + VERIFY(e5 == e3); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_02_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_02_neg.cc new file mode 100644 index 00000000000..ed570f6a10f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_02_neg.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Implicit conversion must not happen when a static extent in self is dynamic +// in other. + +constexpr auto e1 = std::extents<int, 1, std::dynamic_extent, 3>(); +std::extents<int, 1, 2, 3> e2 = e1; + +// { dg-error "conversion from 'extents" "" { target *-*-* } 8 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_03_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_03_neg.cc new file mode 100644 index 00000000000..66b60e38bf1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_03_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Implicit conversion must not when overflow is possible. + +std::extents<unsigned int, 1, 2, 3> e1; +std::extents<int, 1, 2, 3> e2 = e1; + +// { dg-error "conversion from 'extents" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_04_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_04_neg.cc new file mode 100644 index 00000000000..dbf3f7e679a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_copy_implicit_04_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// No implicit conversion because of the IndexType. + +std::extents<unsigned int> e1; +std::extents<int> e2 = e1; + +// { dg-error "conversion from 'extents" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_00.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_00.cc new file mode 100644 index 00000000000..1d7739e6240 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_00.cc @@ -0,0 +1,30 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +template<class IndexType, size_t ... Extents, class Array> + void + test_ctor_ints_00(const std::extents<IndexType, Extents...>& e, + const Array& shape) + { + for(size_t i = 0; i < sizeof...(Extents); ++i) + VERIFY(e.extent(i) == shape[i]); + } + +int +main() +{ + auto shape = std::array<int, 3>{1, 2, 3}; + + test_ctor_ints_00(std::extents<int, 1, 2, 3>(1, 2, 3), shape); + test_ctor_ints_00(std::extents<int, dyn, 2, 3>(1, 2, 3), shape); + test_ctor_ints_00(std::extents<int, dyn, 2, dyn>(1, 2, 3), shape); + + test_ctor_ints_00(std::extents<int, 1, 2, 3>{1, 2, 3}, shape); + test_ctor_ints_00(std::extents<int, dyn, 2, 3>{1, 2, 3}, shape); + test_ctor_ints_00(std::extents<int, dyn, 2, dyn>{1, 2, 3}, shape); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_01.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_01.cc new file mode 100644 index 00000000000..86baf5b5800 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_01.cc @@ -0,0 +1,24 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +template<class Lhs, class Rhs> + void + verify(const Lhs& lhs, const Rhs& rhs) + { VERIFY(lhs == rhs); } + +int +main() +{ + auto expected = std::extents<int, 1, 2, 3>(); + + 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 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_02_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_02_neg.cc new file mode 100644 index 00000000000..e8605c1a980 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_02_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check N != rank && N != rank_dynamic + +constexpr auto dyn = std::dynamic_extent; +std::extents<int, 1, dyn, 3> e1(1, 3); + +// { dg-error "no matching function for call" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_03_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_03_neg.cc new file mode 100644 index 00000000000..9c3ea800283 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_03_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check N != rank && N != rank_dynamic + +constexpr auto dyn = std::dynamic_extent; +std::extents<int, dyn, dyn> e1(1); + +// { dg-error "no matching function for call" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_constexpr.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_constexpr.cc new file mode 100644 index 00000000000..11f1520c652 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_constexpr.cc @@ -0,0 +1,12 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +constexpr auto e0 = std::extents<int, 1, 2>(1, 2); +constexpr auto e1 = std::extents<int, 1, dyn>(2); +constexpr auto e3 = std::extents<int, dyn, dyn>(1, 2); + +constexpr auto e4 = std::extents<int, 1, 2>{1, 2}; +constexpr auto e5 = std::extents<int, 1, dyn>{2}; +constexpr auto e6 = std::extents<int, dyn, dyn>{1, 2}; diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_00_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_00_neg.cc new file mode 100644 index 00000000000..d7713fd2bda --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_00_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Implicit conversion must not happen, via the ctor from +// int-like objects. + +std::extents<int, 1> e = 1; + +// { dg-error "conversion from 'int'" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_01_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_01_neg.cc new file mode 100644 index 00000000000..e18e56b430f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_ints_implicit_01_neg.cc @@ -0,0 +1,9 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Implicit conversion must not happen, via the ctor from +// int-like objects. + +std::extents<int, std::dynamic_extent> e = 1; + +// { dg-error "conversion from 'int'" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_00.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_00.cc new file mode 100644 index 00000000000..3fd726517fb --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_00.cc @@ -0,0 +1,35 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +template<typename Lhs, typename Rhs> + void + verify(const Lhs& lhs, const Rhs& rhs) + { VERIFY(lhs == rhs); } + +int +main() +{ + auto shape = std::array<int, 3>{1, 2, 3}; + auto span_const = std::span<const int, 3>(shape); + auto span = std::span<int, 3>(shape); + + auto expected = std::extents<int, 1, 2, 3>(); + + verify(std::extents<int, dyn, 2, 3>(shape), expected); + 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); + + verify(std::extents<int, 1, dyn, 3>(span_const), expected); + verify(std::extents<int, dyn, dyn, dyn>(span_const), expected); + verify(std::extents<int, 1, 2, 3>(span_const), expected); + + verify(std::extents<int, 1, dyn, 3>(span), expected); + verify(std::extents<int, dyn, dyn, dyn>(span), expected); + verify(std::extents<int, 1, 2, 3>(span), expected); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_01.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_01.cc new file mode 100644 index 00000000000..086ad471a72 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_01.cc @@ -0,0 +1,17 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +int +main() +{ + auto e1 = std::extents<int>(); + auto e2 = std::extents<unsigned int>(); + + VERIFY(e1 == e1); + VERIFY(e1 == e2); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_02_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_02_neg.cc new file mode 100644 index 00000000000..8566cf2eeb2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_02_neg.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check N != rank && N != rank_dynamic + +auto s = std::array<int, 1>{}; + +std::extents<int, 1, 2> e1(s); + +// { dg-error "no matching function for call" "" { target *-*-* } 8 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_03_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_03_neg.cc new file mode 100644 index 00000000000..94d75597ae6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_03_neg.cc @@ -0,0 +1,11 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Check N != rank && N != rank_dynamic + +constexpr auto dyn = std::dynamic_extent; + +auto s = std::array<int, 1>{}; +std::extents<int, dyn, dyn> e1(s); + +// { dg-error "no matching function for call" "" { target *-*-* } 9 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_constexpr.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_constexpr.cc new file mode 100644 index 00000000000..8abe069c8c6 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_constexpr.cc @@ -0,0 +1,23 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +constexpr auto a0 = std::array<int, 0>{}; +constexpr auto a1 = std::array<int, 1>{2}; +constexpr auto a2 = std::array<int, 2>{1, 2}; + +constexpr auto e0 = std::extents<int, 1, 2>(a0); +constexpr auto e1 = std::extents<int, 1, dyn>(a1); +constexpr auto e2 = std::extents<int, 1, 2>(a2); +constexpr auto e3 = std::extents<int, dyn, dyn>(a2); + +constexpr auto s0 = std::span<const int, 0>(a0); +constexpr auto s1 = std::span<const int, 1>(a1); +constexpr auto s2 = std::span<const int, 2>(a2); + +constexpr auto e4 = std::extents<int, 1, 2>(s0); +constexpr auto e5 = std::extents<int, 1, dyn>(s1); +constexpr auto e6 = std::extents<int, 1, 2>(s2); +constexpr auto e7 = std::extents<int, dyn, dyn>(s2); + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_00.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_00.cc new file mode 100644 index 00000000000..427d03d6379 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_00.cc @@ -0,0 +1,42 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +// Test construction from an shape (array or span) of exclusively +// dynamic extents. + +constexpr size_t dyn = std::dynamic_extent; + +template<class IndexType, size_t ... Extents, class Shape> + void + test_ctor_from_dynamic_extents(const Shape& shape) + { + std::extents<IndexType, Extents...> e = shape; + + VERIFY(e.rank_dynamic() == shape.size()); + + size_t di = 0; + for(size_t i = 0; i < sizeof...(Extents); ++i) + if(e.static_extent(i) == dyn) + VERIFY(e.extent(i) == shape[di++]); + } + +int +main() +{ + auto sxxx = std::array<int, 0>{}; + auto sx2x = std::array<int, 1>{2}; + auto s123 = std::array<int, 3>{1, 2, 3}; + + test_ctor_from_dynamic_extents<int, 1, dyn>(sx2x); + + test_ctor_from_dynamic_extents<int, 1, dyn, 3>(sx2x); + test_ctor_from_dynamic_extents<int, dyn, dyn, dyn>(s123); + test_ctor_from_dynamic_extents<int, 1, 2, 3>(sxxx); + + test_ctor_from_dynamic_extents<int, 1, dyn, 3>(std::span<int, 1>(sx2x)); + test_ctor_from_dynamic_extents<int, dyn, dyn, dyn>(std::span<int, 3>(s123)); + test_ctor_from_dynamic_extents<int, 1, 2, 3>(std::span<int, 0>(sxxx)); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_01.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_01.cc new file mode 100644 index 00000000000..c0d24ea9015 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_01.cc @@ -0,0 +1,19 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +// Test implicit conversion for convertible integer types. + +constexpr size_t dyn = std::dynamic_extent; + +auto a0 = std::array<int, 0>{}; +std::extents<int> e0 = a0; +std::extents<unsigned int> e1 = a0; + +auto a1 = std::array<int, 1>{2}; +std::extents<int, 1, dyn, 3> e2 = a1; +std::extents<unsigned int, 1, dyn, 3> e3 = a1; + +auto a2 = std::array<unsigned int, 1>{2}; +std::extents<int, 1, dyn, 3> e4 = a2; +std::extents<unsigned int, 1, dyn, 3> e5 = a2; + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_02_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_02_neg.cc new file mode 100644 index 00000000000..76cd9d05a8d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_02_neg.cc @@ -0,0 +1,11 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> +#include <memory> + +// Implicit conversion must not happen when the span contains at least one +// static extent. + +auto s = std::array<int, 3>{1, 2, 3}; +std::extents<int, 1, std::dynamic_extent, 3> e = s; + +// { dg-error "conversion from 'std::array" "" { target *-*-* } 9 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_03_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_03_neg.cc new file mode 100644 index 00000000000..8bffa799cec --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_03_neg.cc @@ -0,0 +1,12 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> +#include <memory> + +// Implicit conversion must not happen when the span contains at least one +// static extent. + +auto a = std::array<int, 3>{1, 2, 3}; +auto s = std::span<int, 3>(a); +std::extents<int, 1, std::dynamic_extent, 3> e = s; + +// { dg-error "conversion from 'std::span" "" { target *-*-* } 10 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_04.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_04.cc new file mode 100644 index 00000000000..4a8da4aaeb7 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ctor_shape_implicit_04.cc @@ -0,0 +1,24 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +// Implicit conversion from shapes requires the constraint: convertible and the +// pre-condition: non-negative & representable, e.g. the follwing seems to be +// intended to work. + +int +main() +{ + auto a = std::array<double, 1>{2.0}; + auto s = std::span<double, 1>(a); + + std::extents<int, 1, 2> expected; + + std::extents<int, 1, std::dynamic_extent> e1 = a; + VERIFY(e1 == expected); + + std::extents<int, 1, std::dynamic_extent> e2 = s; + VERIFY(e2 == expected); + 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..aae23a73af3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/custom_integer.cc @@ -0,0 +1,86 @@ +// { 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: + 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>{2}; + auto s2 = std::span<IntLike, 1>(a2); + + auto a23 = std::array<IntLike, 2>{2, 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/deduction_guide_00.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_00.cc new file mode 100644 index 00000000000..d7f3a51b9f3 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_00.cc @@ -0,0 +1,23 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + +constexpr auto dyn = std::dynamic_extent; + +constexpr auto e0 = std::extents(); +static_assert(std::is_same_v<decltype(e0), const std::dextents<size_t, 0>>); +static_assert(e0 == std::extents<size_t>()); + +constexpr auto e1 = std::extents(1); +static_assert(std::is_same_v<decltype(e1), const std::dextents<size_t, 1>>); +static_assert(e1 == std::extents<size_t, 1>()); + +constexpr auto e2 = std::extents(1.0, 2.0f); +static_assert(std::is_same_v<decltype(e2), const std::dextents<size_t, 2>>); +static_assert(e2 == std::extents<size_t, 1, 2>()); + +constexpr auto e3 = std::extents(int(1), char(2), size_t(3)); +static_assert(std::is_same_v<decltype(e3), const std::dextents<size_t, 3>>); +static_assert(e3 == std::extents<size_t, 1, 2, 3>()); + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_01_neg.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_01_neg.cc new file mode 100644 index 00000000000..d276634279c --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/deduction_guide_01_neg.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +struct A +{ }; + +constexpr auto e0 = std::extents(A{}); + +// { dg-error "no matching function for call" "" { target *-*-* } 7 } +// { dg-error "class template argument deduction failed" "" { target *-*-* } 7 } diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/dextents.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/dextents.cc new file mode 100644 index 00000000000..31544373c72 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/dextents.cc @@ -0,0 +1,11 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + +constexpr auto dyn = std::dynamic_extent; + +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>>); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/extent.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extent.cc new file mode 100644 index 00000000000..41886cabd19 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/extent.cc @@ -0,0 +1,27 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_extent; + +template<typename IndexType, size_t... Extents> + void + test_extent(const std::extents<IndexType, Extents...>& e) + { + VERIFY(e.extent(0) == 1); + VERIFY(e.extent(1) == 2); + } + +int +main() +{ + auto e1 = std::extents<int, 1, 2>(); + auto e2 = std::extents<int, 1, dyn>(e1); + auto e3 = std::extents<int, dyn, dyn>(e1); + + test_extent(e1); + test_extent(e2); + test_extent(e3); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/index_type.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/index_type.cc new file mode 100644 index 00000000000..96c412779ae --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/index_type.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + +template<typename T> + constexpr bool + index_type_is_identity() + { + return std::is_same_v<typename std::extents<T, 1, 2, 3>::index_type, T>; + } + +static_assert(index_type_is_identity<int>()); +static_assert(index_type_is_identity<unsigned int>()); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/ops_eq.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ops_eq.cc new file mode 100644 index 00000000000..4a1b0641d9d --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/ops_eq.cc @@ -0,0 +1,58 @@ +// { dg-do run { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +template<class Lhs, class Rhs> + void + test_ops_eq(const Lhs& lhs, const Rhs& rhs, bool expected) + { + VERIFY((lhs == rhs) == expected); + VERIFY((lhs != rhs) == !expected); + } + +constexpr auto dyn = std::dynamic_extent; + +static_assert(std::extents<int, 1, 2, 3>() == std::extents<int, 1, 2, 3>()); +static_assert(std::extents<int, 1, 2, 3>() != std::extents<int, 1, 2>()); +static_assert(std::extents<int, 1, 2, 3>() == std::extents<int, 1, dyn, 3>(2)); +static_assert(std::extents<int, 1, 2, 3>() != std::extents<int, 1, dyn, 3>(3)); + +void +test_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); +} + +void +test_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); +} + +int +main() +{ + test_rank_zero(); + test_common(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank.cc new file mode 100644 index 00000000000..0836a965396 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +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); + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_dynamic.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_dynamic.cc new file mode 100644 index 00000000000..fc6bbc22618 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_dynamic.cc @@ -0,0 +1,11 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +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); + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_return_type.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_return_type.cc new file mode 100644 index 00000000000..fef87359256 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_return_type.cc @@ -0,0 +1,14 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +template<class T, size_t ... Extents> + constexpr bool + test_return_type() + { + auto e = std::extents<T, Extents...>(); + return std::is_same_v<decltype(e.rank()), size_t>; + } + +static_assert(test_return_type<int, 1>()); +static_assert(test_return_type<int, 1, 2>()); +static_assert(test_return_type<int, 1, 3, 4>()); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_type.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_type.cc new file mode 100644 index 00000000000..420159fff86 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/rank_type.cc @@ -0,0 +1,7 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + +static_assert(std::is_same_v<typename std::extents<int, 1, 2>::rank_type, + size_t>); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/size_type.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/size_type.cc new file mode 100644 index 00000000000..1c054a1c7d2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/size_type.cc @@ -0,0 +1,16 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <type_traits> + + +template<typename T, size_t... Extents> + constexpr bool + test_size_type() + { + return std::is_unsigned_v<typename std::extents<T, Extents...>::size_type>; + } + +static_assert(test_size_type<int, 1, 2>); +static_assert(test_size_type<unsigned int, 1, 2>); + diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/sizeof.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/sizeof.cc new file mode 100644 index 00000000000..27c2d5dd25f --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/sizeof.cc @@ -0,0 +1,10 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +constexpr auto dyn = std::dynamic_extent; + +static_assert(sizeof(std::extents<int, 1, 2>) == 1); +static_assert(sizeof(std::extents<int>) == 1); + +static_assert(sizeof(std::extents<int, 1, dyn>) == sizeof(int)); +static_assert(sizeof(std::extents<char, 1, dyn>) == sizeof(char)); diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/static_extent.cc b/libstdc++-v3/testsuite/23_containers/mdspan/extents/static_extent.cc new file mode 100644 index 00000000000..18b310887e1 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/static_extent.cc @@ -0,0 +1,15 @@ +// { dg-do compile { target c++23 } } +#include <mdspan> + +#include <testsuite_hooks.h> + +constexpr auto dyn = std::dynamic_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); -- 2.49.0