xref: /llvm-project/libcxx/test/std/containers/views/mdspan/mdspan/swap.pass.cpp (revision 5e19fd172063c8957a35c7fa3596620f79ebba97)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9 
10 // <mdspan>
11 //
12 // friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
13 //
14 // Effects: Equivalent to:
15 //   swap(x.ptr_, y.ptr_);
16 //   swap(x.map_, y.map_);
17 //   swap(x.acc_, y.acc_);
18 
19 #include <mdspan>
20 #include <cassert>
21 #include <concepts>
22 #include <span> // dynamic_extent
23 #include <type_traits>
24 
25 #include "test_macros.h"
26 
27 #include "../MinimalElementType.h"
28 #include "../CustomTestLayouts.h"
29 
30 template <class MDS>
31 constexpr void test_swap(MDS a, MDS b) {
32   auto org_a = a;
33   auto org_b = b;
34   swap(a, b);
35   assert(a.extents() == org_b.extents());
36   assert(b.extents() == org_a.extents());
37   if constexpr (std::equality_comparable<typename MDS::mapping_type>) {
38     assert(a.mapping() == org_b.mapping());
39     assert(b.mapping() == org_a.mapping());
40   }
41   if constexpr (std::equality_comparable<typename MDS::data_handle_type>) {
42     assert(a.data_handle() == org_b.data_handle());
43     assert(b.data_handle() == org_a.data_handle());
44   }
45   // This check uses a side effect of layout_wrapping_integral::swap to make sure
46   // mdspan calls the underlying components' swap via ADL
47   if (!std::is_constant_evaluated()) {
48     if constexpr (std::is_same_v<typename MDS::layout_type, layout_wrapping_integral<4>>) {
49       assert(MDS::mapping_type::swap_counter() > 0);
50     }
51   }
52 }
53 
54 constexpr bool test() {
55   using extents_t = std::extents<int, 4, std::dynamic_extent>;
56   float data_a[1024];
57   float data_b[1024];
58   {
59     std::mdspan a(data_a, extents_t(12));
60     std::mdspan b(data_b, extents_t(5));
61     test_swap(a, b);
62   }
63   {
64     layout_wrapping_integral<4>::mapping<extents_t> map_a(extents_t(12), not_extents_constructible_tag()),
65         map_b(extents_t(5), not_extents_constructible_tag());
66     std::mdspan a(data_a, map_a);
67     std::mdspan b(data_b, map_b);
68     test_swap(a, b);
69   }
70   return true;
71 }
72 
73 int main(int, char**) {
74   test();
75   static_assert(test());
76   return 0;
77 }
78