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

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