//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // // template // friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept; // // Constraints: // - layout-mapping-alike is satisfied. // - rank_ == OtherMapping::extents_type::rank() is true. // - OtherMapping::is_always_strided() is true. // // Preconditions: OtherMapping meets the layout mapping requirements ([mdspan.layout.policy.reqmts]). // // Returns: true if x.extents() == y.extents() is true, OFFSET(y) == 0 is true, and each of x.stride(r) == y.stride(r) is true for r in the range [0, x.extents().rank()). Otherwise, false. #include #include #include #include // dynamic_extent #include #include "test_macros.h" #include "../CustomTestLayouts.h" template concept layout_mapping_comparable = requires( E1 e1, E2 e2, std::array s1, std::array s2) { std::layout_stride::mapping(e1, s1) == std::layout_stride::mapping(e2, s2); }; template constexpr void test_comparison_different_rank() { constexpr size_t D = std::dynamic_extent; // sanity check same rank static_assert(layout_mapping_comparable, std::extents>); static_assert(layout_mapping_comparable, std::extents>); static_assert(layout_mapping_comparable, std::extents>); static_assert(layout_mapping_comparable, std::extents>); // not equality comparable when rank is not the same static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); static_assert(!layout_mapping_comparable, std::extents>); } template constexpr void test_comparison( bool equal, To dest_exts, From src_exts, std::array dest_strides, std::array src_strides) { std::layout_stride::mapping dest(dest_exts, dest_strides); std::layout_stride::mapping src(src_exts, src_strides); ASSERT_NOEXCEPT(dest == src); assert((dest == src) == equal); assert((dest != src) == !equal); } template constexpr void test_comparison_same_rank() { constexpr size_t D = std::dynamic_extent; test_comparison(true, std::extents(), std::extents(), std::array{}, std::array{}); test_comparison(true, std::extents(5), std::extents(5), std::array{1}, std::array{1}); test_comparison(true, std::extents(0), std::extents(0), std::array{1}, std::array{1}); test_comparison(true, std::extents(), std::extents(5), std::array{3}, std::array{3}); test_comparison(true, std::extents(5), std::extents(), std::array{1}, std::array{1}); test_comparison(true, std::extents(), std::extents< T2, 5>(), std::array{1}, std::array{1}); test_comparison(false, std::extents(), std::extents(5), std::array{2}, std::array{1}); test_comparison(false, std::extents(5), std::extents(5), std::array{2}, std::array{1}); test_comparison(false, std::extents(5), std::extents(7), std::array{1}, std::array{1}); test_comparison(false, std::extents(), std::extents(7), std::array{1}, std::array{1}); test_comparison(false, std::extents(5), std::extents(), std::array{1}, std::array{1}); test_comparison(false, std::extents(), std::extents(), std::array{1}, std::array{1}); test_comparison( true, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 7, 8, 9), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( true, std::extents(5, 7, 9), std::extents(6, 7), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( true, std::extents(5, 6, 7, 8, 9), std::extents(), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( false, std::extents(5, 6, 7, 8, 9), std::extents(), std::array{2, 20, 200, 20000, 2000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( false, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 3, 8, 9), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( false, std::extents(5, 7, 9), std::extents(6, 7), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); test_comparison( false, std::extents(5, 6, 7, 8, 9), std::extents(), std::array{2, 20, 200, 2000, 20000}, std::array{2, 20, 200, 2000, 20000}); } template constexpr void test_comparison_with( bool expect_equal, E1 e1, std::array strides, E2 e2, OtherArgs... other_args) { std::layout_stride::mapping map(e1, strides); typename OtherLayout::template mapping other_map(e2, other_args...); assert((map == other_map) == expect_equal); } template constexpr void test_comparison_with() { constexpr size_t D = std::dynamic_extent; bool is_left_based = std::is_same_v || std::is_same_v; test_comparison_with(true, std::extents(), std::array{}, std::extents()); test_comparison_with(true, std::extents(), std::array{1}, std::extents()); test_comparison_with(true, std::extents(5), std::array{1}, std::extents()); test_comparison_with(false, std::extents(5), std::array{2}, std::extents()); test_comparison_with( is_left_based, std::extents(5, 7), std::array{1, 5}, std::extents(5, 7)); test_comparison_with( !is_left_based, std::extents(5, 7), std::array{7, 1}, std::extents(5, 7)); test_comparison_with( false, std::extents(5, 7), std::array{8, 1}, std::extents(5, 7)); if constexpr (std::is_same_v) { // test layout with strides not equal to product of extents test_comparison_with( true, std::extents(5, 7), std::array{2, 10}, std::extents(5, 7), 0, 2); // make sure that offset != 0 results in false test_comparison_with( false, std::extents(5, 7), std::array{2, 10}, std::extents(5, 7), 1, 2); } } template constexpr void test_comparison_index_type() { test_comparison_same_rank(); test_comparison_different_rank(); test_comparison_with(); test_comparison_with(); test_comparison_with(); } constexpr bool test() { test_comparison_index_type(); test_comparison_index_type(); test_comparison_index_type(); test_comparison_index_type(); return true; } int main(int, char**) { test(); static_assert(test()); return 0; }