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
9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10
11// <mdspan>
12//
13// template<class OtherElementType>
14// constexpr operator default_accessor<OtherElementType>() const noexcept;
15//
16// Constraints: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true.
17
18#include <mdspan>
19#include <cassert>
20#include <cstdint>
21#include <type_traits>
22
23#include "test_macros.h"
24
25#include "../MinimalElementType.h"
26
27struct Base {};
28struct Derived : public Base {};
29
30template <class FromT, size_t FromN, class ToT>
31constexpr void test_conversion() {
32 std::aligned_accessor<FromT, FromN> from;
33 ASSERT_NOEXCEPT(std::default_accessor<ToT>(from));
34 [[maybe_unused]] std::default_accessor<ToT> to(from);
35 // check that the conversion is implicit
36 static_assert(std::is_nothrow_convertible_v<std::aligned_accessor<FromT, FromN>, std::default_accessor<ToT>>);
37 static_assert(std::is_nothrow_constructible_v<std::default_accessor<ToT>, std::aligned_accessor<FromT, FromN>>);
38}
39
40template <class From, class To>
41constexpr void test_it() {
42 constexpr size_t N = alignof(From);
43 test_conversion<From, N, To>();
44 test_conversion<From, 2 * N, To>();
45 test_conversion<From, 4 * N, To>();
46 test_conversion<From, 8 * N, To>();
47 test_conversion<From, 16 * N, To>();
48 test_conversion<From, 32 * N, To>();
49}
50
51constexpr bool test() {
52 test_it<int, int>();
53 test_it<int, const int>();
54 test_it<const int, const int>();
55 test_it<MinimalElementType, MinimalElementType>();
56 test_it<MinimalElementType, const MinimalElementType>();
57 test_it<const MinimalElementType, const MinimalElementType>();
58
59 // char is convertible to int, but accessors are not
60 static_assert(!std::is_constructible_v<std::default_accessor<int>, std::aligned_accessor<char, 4>>);
61 // don't allow conversion from const elements to non-const
62 static_assert(!std::is_constructible_v<std::default_accessor<int>, std::aligned_accessor<const int, 8>>);
63 // MinimalElementType is constructible from int, but accessors should not be convertible
64 static_assert(!std::is_constructible_v<std::default_accessor<MinimalElementType>, std::aligned_accessor<int, 4>>);
65 // don't allow conversion from const elements to non-const
66 static_assert(!std::is_constructible_v<std::default_accessor<MinimalElementType>,
67 std::aligned_accessor<const MinimalElementType, 4>>);
68 // don't allow conversion from Base to Derived
69 static_assert(!std::is_constructible_v<std::default_accessor<Derived>, std::aligned_accessor<Base, 1>>);
70 // don't allow conversion from Derived to Base
71 static_assert(!std::is_constructible_v<std::default_accessor<Base>, std::aligned_accessor<Derived, 1>>);
72
73 return true;
74}
75
76int main(int, char**) {
77 test();
78 static_assert(test());
79 return 0;
80}
81

source code of libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp