[libcxx] Add mdspan/extents

This patch adds std::extents. extents is one of the core classes used by std::mdspan. It describes a multi-dimensional index space with a mix of compile time and runtime sizes. Furthermore, it is templated on the index type used to describe the multi-dimensional index space.

The class is designed to be highly optimizable in performance critical code sections, and is fully useable in constant expressions contexts.

Testing of this class tends to be somewhat combinatorical, due to the large number of possible corner cases involved in situations where we have both runtime and compile time extents. To add to this, the class is designed to be interoperable (in particular constructible) from arguments which only need to be convertible to the index_type, but are otherwise arbitrary user types. For a larger discussion on the design of this class refer to: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html

Co-authored-by: Damien L-G <dalg24@gmail.com>

Reviewed By: ldionne, #libc

Spies: libcxx-commits, H-G-Hristov, tschuett, philnik, arichardson, Mordante, crtrott

Differential Revision: https://reviews.llvm.org/D148067
This commit is contained in:
Christian Trott 2023-05-16 12:38:11 -07:00 committed by Nikolas Klauser
parent 02a029f7fb
commit fcaccf817d
44 changed files with 2220 additions and 287 deletions

View File

@ -92,6 +92,11 @@ E: stl@microsoft.com
E: stl@nuwen.net
D: Implemented floating-point to_chars.
N: Damien Lebrun-Grandie
E: dalg24@gmail.com
E: lebrungrandt@ornl.gov
D: Implementation of mdspan.
N: Microsoft Corporation
D: Contributed floating-point to_chars.
@ -149,6 +154,10 @@ N: Stephan Tolksdorf
E: st@quanttec.com
D: Minor <atomic> fix
N: Christian Trott
E: crtrott@sandia.gov
D: Implementation of mdspan.
N: Ruben Van Boxem
E: vanboxem dot ruben at gmail dot com
D: Initial Windows patches.

View File

@ -332,6 +332,8 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_is_scoped_enum`` ``202011L``
------------------------------------------------- -----------------
``__cpp_lib_mdspan`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_move_only_function`` *unimplemented*
------------------------------------------------- -----------------
``__cpp_lib_optional`` ``202110L``

View File

@ -51,7 +51,7 @@
"`P2442R1 <https://wg21.link/P2442R1>`__","LWG","Windowing range adaptors: ``views::chunk`` and ``views::slide``","February 2022","","","|ranges|"
"`P2443R1 <https://wg21.link/P2443R1>`__","LWG","``views::chunk_by``","February 2022","","","|ranges|"
"","","","","","",""
"`P0009R18 <https://wg21.link/P0009R18>`__","LWG","mdspan: A Non-Owning Multidimensional Array Reference","July 2022","",""
"`P0009R18 <https://wg21.link/P0009R18>`__","LWG","mdspan: A Non-Owning Multidimensional Array Reference","July 2022","|In progress|",""
"`P0429R9 <https://wg21.link/P0429R9>`__","LWG","A Standard ``flat_map``","July 2022","",""
"`P1169R4 <https://wg21.link/P1169R4>`__","LWG","``static operator()``","July 2022","|Complete|","16.0"
"`P1222R4 <https://wg21.link/P1222R4>`__","LWG","A Standard ``flat_set``","July 2022","",""

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -463,6 +463,7 @@ set(files
__locale_dir/locale_base_api/bsd_locale_fallbacks.h
__locale_dir/locale_base_api/locale_guard.h
__mbstate_t.h
__mdspan/extents.h
__memory/addressof.h
__memory/align.h
__memory/aligned_alloc.h
@ -913,6 +914,7 @@ set(files
locale.h
map
math.h
mdspan
memory
memory_resource
mutex

View File

@ -0,0 +1,460 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// 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
//
// Kokkos v. 4.0
// Copyright (2022) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
//===---------------------------------------------------------------------===//
#ifndef _LIBCPP___MDSPAN_EXTENTS_H
#define _LIBCPP___MDSPAN_EXTENTS_H
#include <__assert>
#include <__config>
#include <__type_traits/common_type.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_same.h>
#include <__type_traits/make_unsigned.h>
#include <__utility/integer_sequence.h>
#include <__utility/unreachable.h>
#include <array>
#include <cinttypes>
#include <concepts>
#include <cstddef>
#include <limits>
#include <span>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 23
namespace __mdspan_detail {
// ------------------------------------------------------------------
// ------------ __static_array --------------------------------------
// ------------------------------------------------------------------
// array like class which provides an array of static values with get
template <class _Tp, _Tp... _Values>
struct __static_array {
static constexpr array<_Tp, sizeof...(_Values)> __array = {_Values...};
public:
_LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Values); }
_LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get(size_t __index) noexcept { return __array[__index]; }
template <size_t _Index>
_LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get() {
return __get(_Index);
}
};
// ------------------------------------------------------------------
// ------------ __possibly_empty_array -----------------------------
// ------------------------------------------------------------------
// array like class which provides get function and operator [], and
// has a specialization for the size 0 case.
// This is needed to make the __maybe_static_array be truly empty, for
// all static values.
template <class _Tp, size_t _Size>
struct __possibly_empty_array {
_Tp __vals_[_Size];
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t __index) { return __vals_[__index]; }
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __index) const { return __vals_[__index]; }
};
template <class _Tp>
struct __possibly_empty_array<_Tp, 0> {
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t) { __libcpp_unreachable(); }
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t) const { __libcpp_unreachable(); }
};
// ------------------------------------------------------------------
// ------------ static_partial_sums ---------------------------------
// ------------------------------------------------------------------
// Provides a compile time partial sum one can index into
template <size_t... _Values>
struct __static_partial_sums {
_LIBCPP_HIDE_FROM_ABI static constexpr array<size_t, sizeof...(_Values)> __static_partial_sums_impl() {
array<size_t, sizeof...(_Values)> __values{_Values...};
array<size_t, sizeof...(_Values)> __partial_sums{{}};
size_t __running_sum = 0;
for (int __i = 0; __i != sizeof...(_Values); ++__i) {
__partial_sums[__i] = __running_sum;
__running_sum += __values[__i];
}
return __partial_sums;
}
static constexpr array<size_t, sizeof...(_Values)> __result{__static_partial_sums_impl()};
_LIBCPP_HIDE_FROM_ABI static constexpr size_t __get(size_t __index) { return __result[__index]; }
};
// ------------------------------------------------------------------
// ------------ __maybe_static_array --------------------------------
// ------------------------------------------------------------------
// array like class which has a mix of static and runtime values but
// only stores the runtime values.
// The type of the static and the runtime values can be different.
// The position of a dynamic value is indicated through a tag value.
template <class _TDynamic, class _TStatic, _TStatic _DynTag, _TStatic... _Values>
struct __maybe_static_array {
static_assert(is_convertible<_TStatic, _TDynamic>::value,
"__maybe_static_array: _TStatic must be convertible to _TDynamic");
static_assert(is_convertible<_TDynamic, _TStatic>::value,
"__maybe_static_array: _TDynamic must be convertible to _TStatic");
private:
// Static values member
static constexpr size_t __size_ = sizeof...(_Values);
static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0);
using _StaticValues = __static_array<_TStatic, _Values...>;
using _DynamicValues = __possibly_empty_array<_TDynamic, __size_dynamic_>;
// Dynamic values member
_LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_;
// static mapping of indices to the position in the dynamic values array
using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>;
template <size_t... Indices>
_LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<Indices...>) noexcept {
return _DynamicValues{((void)Indices, 0)...};
}
public:
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept
: __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {}
// constructors from dynamic values only -- this covers the case for rank() == 0
template <class... _DynVals>
requires(sizeof...(_DynVals) == __size_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals)
: __dyn_vals_{static_cast<_TDynamic>(__vals)...} {}
template <class _Tp, size_t _Size >
requires(_Size == __size_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array([[maybe_unused]] const span<_Tp, _Size>& __vals) {
if constexpr (_Size > 0) {
for (size_t __i = 0; __i < _Size; __i++)
__dyn_vals_[__i] = static_cast<_TDynamic>(__vals[__i]);
}
}
// constructors from all values -- here rank will be greater than 0
template <class... _DynVals>
requires(sizeof...(_DynVals) != __size_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) {
static_assert((sizeof...(_DynVals) == __size_), "Invalid number of values.");
_TDynamic __values[__size_] = {static_cast<_TDynamic>(__vals)...};
for (size_t __i = 0; __i < __size_; __i++) {
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
}
// Precondition check
else
_LIBCPP_ASSERT(__values[__i] == static_cast<_TDynamic>(__static_val),
"extents construction: mismatch of provided arguments with static extents.");
}
}
template <class _Tp, size_t _Size>
requires(_Size != __size_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) {
static_assert((_Size == __size_) || (__size_ == dynamic_extent));
for (size_t __i = 0; __i < __size_; __i++) {
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
}
// Precondition check
else
_LIBCPP_ASSERT(static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
"extents construction: mismatch of provided arguments with static extents.");
}
}
// access functions
_LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept {
_LIBCPP_ASSERT(__i < __size_, "extents access: index must be less than rank");
return _StaticValues::__get(__i);
}
_LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const {
_LIBCPP_ASSERT(__i < __size_, "extents access: index must be less than rank");
_TStatic __static_val = _StaticValues::__get(__i);
return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val);
}
_LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const {
_LIBCPP_ASSERT(__i < __size_, "extents access: index must be less than rank");
return __value(__i);
}
// observers
_LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return __size_; }
_LIBCPP_HIDE_FROM_ABI static constexpr size_t __size_dynamic() { return __size_dynamic_; }
};
// Function to check whether a value is representable as another type
// value must be a positive integer otherwise returns false
// if _From is not an integral, we just check positivity
template <integral _To, class _From>
requires(is_integral_v<_From>)
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
using _To_u = make_unsigned_t<_To>;
using _From_u = make_unsigned_t<_From>;
if constexpr (is_signed_v<_From>) {
if (__value < 0)
return false;
}
if constexpr (static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(numeric_limits<_From>::max())) {
return true;
} else {
return static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(__value);
}
}
template <integral _To, class _From>
requires(!is_integral_v<_From>)
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
if constexpr (is_signed_v<_To>) {
if (static_cast<_To>(__value) < 0)
return false;
}
return true;
}
template <integral _To, class... _From>
_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(_From... __values) {
return (__mdspan_detail::__is_representable_as<_To>(__values) && ... && true);
}
template <integral _To, class _From, size_t _Size>
_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(span<_From, _Size> __values) {
for (size_t __i = 0; __i < _Size; __i++)
if (!__mdspan_detail::__is_representable_as<_To>(__values[__i]))
return false;
return true;
}
} // namespace __mdspan_detail
// ------------------------------------------------------------------
// ------------ extents ---------------------------------------------
// ------------------------------------------------------------------
// Class to describe the extents of a multi dimensional array.
// Used by mdspan, mdarray and layout mappings.
// See ISO C++ standard [mdspan.extents]
template <class _IndexType, size_t... _Extents>
class extents {
public:
// typedefs for integral types used
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
using rank_type = size_t;
static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value,
"extents::index_type must be a signed or unsigned integer type");
static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
"extents ctor: arguments must be representable as index_type and nonnegative");
private:
static constexpr rank_type __rank_ = sizeof...(_Extents);
static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0);
// internal storage type using __maybe_static_array
using _Values = __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>;
[[no_unique_address]] _Values __vals_;
public:
// [mdspan.extents.obs], observers of multidimensional index space
_LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; }
_LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; }
_LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); }
_LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept {
return _Values::__static_value(__r);
}
// [mdspan.extents.cons], constructors
_LIBCPP_HIDE_FROM_ABI constexpr extents() noexcept = default;
// Construction from just dynamic or all values.
// Precondition check is deferred to __maybe_static_array constructor
template <class... _OtherIndexTypes>
requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) &&
(is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
(sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
_LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
: __vals_(static_cast<index_type>(__dynvals)...) {
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
(_Size == __rank_ || _Size == __rank_dynamic_))
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(span(__exts)) {
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
(_Size == __rank_ || _Size == __rank_dynamic_))
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(__exts) {
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(__exts),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
private:
// Function to construct extents storage from other extents.
template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
requires(_Idx < __rank_)
_LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
integral_constant<size_t, _DynCount>,
integral_constant<size_t, _Idx>,
const _OtherExtents& __exts,
_DynamicValues... __dynamic_values) noexcept {
if constexpr (static_extent(_Idx) == dynamic_extent)
return __construct_vals_from_extents(
integral_constant<size_t, _DynCount + 1>(),
integral_constant<size_t, _Idx + 1>(),
__exts,
__dynamic_values...,
__exts.extent(_Idx));
else
return __construct_vals_from_extents(
integral_constant<size_t, _DynCount>(), integral_constant<size_t, _Idx + 1>(), __exts, __dynamic_values...);
}
template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues>
requires((_Idx == __rank_) && (_DynCount == __rank_dynamic_))
_LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents(
integral_constant<size_t, _DynCount>,
integral_constant<size_t, _Idx>,
const _OtherExtents&,
_DynamicValues... __dynamic_values) noexcept {
return _Values{static_cast<index_type>(__dynamic_values)...};
}
public:
// Converting constructor from other extents specializations
template <class _OtherIndexType, size_t... _OtherExtents>
requires((sizeof...(_OtherExtents) == sizeof...(_Extents)) &&
((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...))
explicit((((_Extents != dynamic_extent) && (_OtherExtents == dynamic_extent)) || ...) ||
(static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())))
_LIBCPP_HIDE_FROM_ABI constexpr extents(const extents<_OtherIndexType, _OtherExtents...>& __other) noexcept
: __vals_(
__construct_vals_from_extents(integral_constant<size_t, 0>(), integral_constant<size_t, 0>(), __other)) {
if constexpr (rank() > 0) {
for (size_t __r = 0; __r < rank(); __r++) {
if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
_LIBCPP_ASSERT(__mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
_LIBCPP_ASSERT(
(_Values::__static_value(__r) == dynamic_extent) ||
(static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
"extents construction: mismatch of provided arguments with static extents.");
}
}
}
// Comparison operator
template <class _OtherIndexType, size_t... _OtherExtents>
_LIBCPP_HIDE_FROM_ABI friend constexpr bool
operator==(const extents& __lhs, const extents<_OtherIndexType, _OtherExtents...>& __rhs) noexcept {
if constexpr (rank() != sizeof...(_OtherExtents)) {
return false;
} else {
for (rank_type __r = 0; __r < __rank_; __r++) {
// avoid warning when comparing signed and unsigner integers and pick the wider of two types
using _CommonType = common_type_t<index_type, _OtherIndexType>;
if (static_cast<_CommonType>(__lhs.extent(__r)) != static_cast<_CommonType>(__rhs.extent(__r))) {
return false;
}
}
}
return true;
}
};
// Recursive helper classes to implement dextents alias for extents
namespace __mdspan_detail {
template <class _IndexType, size_t _Rank, class _Extents = extents<_IndexType>>
struct __make_dextents;
template <class _IndexType, size_t _Rank, size_t... _ExtentsPack>
struct __make_dextents< _IndexType, _Rank, extents<_IndexType, _ExtentsPack...>> {
using type =
typename __make_dextents< _IndexType, _Rank - 1, extents<_IndexType, dynamic_extent, _ExtentsPack...>>::type;
};
template <class _IndexType, size_t... _ExtentsPack>
struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> {
using type = extents<_IndexType, _ExtentsPack...>;
};
} // end namespace __mdspan_detail
// [mdspan.extents.dextents], alias template
template <class _IndexType, size_t _Rank>
using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type;
// Deduction guide for extents
template <class... _IndexTypes>
extents(_IndexTypes...) -> extents<size_t, size_t((_IndexTypes(), dynamic_extent))...>;
// Helper type traits for identifying a class as extents.
namespace __mdspan_detail {
template <class _Tp>
struct __is_extents : false_type {};
template <class _IndexType, size_t... _ExtentsPack>
struct __is_extents<extents<_IndexType, _ExtentsPack...>> : true_type {};
template <class _Tp>
inline constexpr bool __is_extents_v = __is_extents<_Tp>::value;
} // namespace __mdspan_detail
#endif // _LIBCPP_STD_VER >= 23
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___MDSPAN_EXTENTS_H

View File

@ -33,6 +33,7 @@
{ include: [ "@<__ios/.*>", "private", "<ios>", "public" ] },
{ include: [ "@<__iterator/.*>", "private", "<iterator>", "public" ] },
{ include: [ "@<__locale_dir/.*>", "private", "<locale>", "public" ] },
{ include: [ "@<__mdspan/.*>", "private", "<mdspan>", "public" ] },
{ include: [ "@<__memory/.*>", "private", "<memory>", "public" ] },
{ include: [ "@<__memory_resource/.*>", "private", "<memory_resource>", "public" ] },
{ include: [ "@<__mutex/.*>", "private", "<mutex>", "public" ] },

69
libcxx/include/mdspan Normal file
View File

@ -0,0 +1,69 @@
// -*-C++ - *-
//===----------------------------------------------------------------------===//
//
// 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
//
//===---------------------------------------------------------------------===//
/*
extents synopsis
namespace std {
template<class _IndexType, size_t... _Extents>
class extents {
public:
using index_type = _IndexType;
using size_type = make_unsigned_t<index_type>;
using rank_type = size_t;
// [mdspan.extents.obs], observers of the multidimensional index space
static constexpr rank_type rank() noexcept { return sizeof...(_Extents); }
static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
static constexpr size_t static_extent(rank_type) noexcept;
constexpr index_type extent(rank_type) const noexcept;
// [mdspan.extents.cons], constructors
constexpr extents() noexcept = default;
template<class _OtherIndexType, size_t... _OtherExtents>
constexpr explicit(see below)
extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
template<class... _OtherIndexTypes>
constexpr explicit extents(_OtherIndexTypes...) noexcept;
template<class _OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
extents(span<_OtherIndexType, N>) noexcept;
template<class _OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
extents(const array<_OtherIndexType, N>&) noexcept;
// [mdspan.extents.cmp], comparison operators
template<class _OtherIndexType, size_t... _OtherExtents>
friend constexpr bool operator==(const extents&,
const extents<_OtherIndexType, _OtherExtents...>&) noexcept;
private:
// libcxx note: we do not use an array here, but we need to preserve the as-if behavior
// for example the default constructor must zero initialize dynamic extents
array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only
};
template<class... Integrals>
explicit extents(Integrals...)
-> see below;
}
*/
#ifndef _LIBCPP_MDSPAN
#define _LIBCPP_MDSPAN
#include <__config>
#include <__mdspan/extents.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
#endif // _LIBCPP_MDSPAN

View File

@ -1162,6 +1162,16 @@ module std [system] {
export initializer_list
export *
}
module mdspan {
header "mdspan"
export array
export span
export *
module __mdspan {
module extents { private header "__mdspan/extents.h" }
}
}
module memory {
header "memory"
export *

View File

@ -123,6 +123,7 @@ __cpp_lib_make_unique 201304L <memory>
__cpp_lib_map_try_emplace 201411L <map>
__cpp_lib_math_constants 201907L <numbers>
__cpp_lib_math_special_functions 201603L <cmath>
__cpp_lib_mdspan 202207L <mdspan>
__cpp_lib_memory_resource 201603L <memory_resource>
__cpp_lib_move_iterator_concept 202207L <iterator>
__cpp_lib_move_only_function 202110L <functional>
@ -408,6 +409,7 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_forward_like 202207L
# define __cpp_lib_invoke_r 202106L
# define __cpp_lib_is_scoped_enum 202011L
// # define __cpp_lib_mdspan 202207L
// # define __cpp_lib_move_only_function 202110L
# undef __cpp_lib_optional
# define __cpp_lib_optional 202110L

View File

@ -418,330 +418,336 @@ int main(int, char**) { return 0; }
// RUN: %{build} -DTEST_71
#if defined(TEST_71)
# include <memory>
# include <mdspan>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_72
#if defined(TEST_72)
# include <memory_resource>
# include <memory>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_73
#if defined(TEST_73) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <mutex>
#if defined(TEST_73)
# include <memory_resource>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_74
#if defined(TEST_74)
# include <new>
#if defined(TEST_74) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <mutex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_75
#if defined(TEST_75)
# include <numbers>
# include <new>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_76
#if defined(TEST_76)
# include <numeric>
# include <numbers>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_77
#if defined(TEST_77)
# include <optional>
# include <numeric>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_78
#if defined(TEST_78) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <ostream>
#if defined(TEST_78)
# include <optional>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_79
#if defined(TEST_79)
# include <queue>
#if defined(TEST_79) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <ostream>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_80
#if defined(TEST_80)
# include <random>
# include <queue>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_81
#if defined(TEST_81)
# include <ranges>
# include <random>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_82
#if defined(TEST_82)
# include <ratio>
# include <ranges>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_83
#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <regex>
#if defined(TEST_83)
# include <ratio>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_84
#if defined(TEST_84)
# include <scoped_allocator>
#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <regex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_85
#if defined(TEST_85) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <semaphore>
#if defined(TEST_85)
# include <scoped_allocator>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_86
#if defined(TEST_86)
#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <semaphore>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_87
#if defined(TEST_87)
# include <set>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_88
#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <shared_mutex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_89
#if defined(TEST_89)
# include <source_location>
#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <shared_mutex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_90
#if defined(TEST_90)
# include <span>
# include <source_location>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_91
#if defined(TEST_91) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <sstream>
#if defined(TEST_91)
# include <span>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_92
#if defined(TEST_92)
#if defined(TEST_92) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <sstream>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_93
#if defined(TEST_93)
# include <stack>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_96
#if defined(TEST_96)
// RUN: %{build} -DTEST_97
#if defined(TEST_97)
# include <stdexcept>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_100
#if defined(TEST_100) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
// RUN: %{build} -DTEST_101
#if defined(TEST_101) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <streambuf>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_101
#if defined(TEST_101)
// RUN: %{build} -DTEST_102
#if defined(TEST_102)
# include <string>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_103
#if defined(TEST_103)
// RUN: %{build} -DTEST_104
#if defined(TEST_104)
# include <string_view>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_104
#if defined(TEST_104) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
// RUN: %{build} -DTEST_105
#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <strstream>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_105
#if defined(TEST_105)
// RUN: %{build} -DTEST_106
#if defined(TEST_106)
# include <system_error>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_107
#if defined(TEST_107) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <thread>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_108
#if defined(TEST_108)
# include <tuple>
#if defined(TEST_108) && !defined(_LIBCPP_HAS_NO_THREADS)
# include <thread>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_109
#if defined(TEST_109)
# include <type_traits>
# include <tuple>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_110
#if defined(TEST_110)
# include <typeindex>
# include <type_traits>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_111
#if defined(TEST_111)
# include <typeinfo>
# include <typeindex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_113
#if defined(TEST_113)
# include <unordered_map>
// RUN: %{build} -DTEST_112
#if defined(TEST_112)
# include <typeinfo>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_114
#if defined(TEST_114)
# include <unordered_set>
# include <unordered_map>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_115
#if defined(TEST_115)
# include <utility>
# include <unordered_set>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_116
#if defined(TEST_116)
# include <valarray>
# include <utility>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_117
#if defined(TEST_117)
# include <variant>
# include <valarray>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_118
#if defined(TEST_118)
# include <vector>
# include <variant>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_119
#if defined(TEST_119)
# include <version>
# include <vector>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_122
#if defined(TEST_122) && __cplusplus >= 201103L
# include <experimental/deque>
// RUN: %{build} -DTEST_120
#if defined(TEST_120)
# include <version>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_123
#if defined(TEST_123) && __cplusplus >= 201103L
# include <experimental/forward_list>
# include <experimental/deque>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_124
#if defined(TEST_124) && __cplusplus >= 201103L
# include <experimental/iterator>
# include <experimental/forward_list>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_125
#if defined(TEST_125) && __cplusplus >= 201103L
# include <experimental/list>
# include <experimental/iterator>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_126
#if defined(TEST_126) && __cplusplus >= 201103L
# include <experimental/map>
# include <experimental/list>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_127
#if defined(TEST_127) && __cplusplus >= 201103L
# include <experimental/memory_resource>
# include <experimental/map>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_128
#if defined(TEST_128) && __cplusplus >= 201103L
# include <experimental/propagate_const>
# include <experimental/memory_resource>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_129
#if defined(TEST_129) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
# include <experimental/regex>
#if defined(TEST_129) && __cplusplus >= 201103L
# include <experimental/propagate_const>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_130
#if defined(TEST_130) && __cplusplus >= 201103L
# include <experimental/set>
#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
# include <experimental/regex>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_131
#if defined(TEST_131) && __cplusplus >= 201103L
# include <experimental/simd>
# include <experimental/set>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_132
#if defined(TEST_132) && __cplusplus >= 201103L
# include <experimental/string>
# include <experimental/simd>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_133
#if defined(TEST_133) && __cplusplus >= 201103L
# include <experimental/type_traits>
# include <experimental/string>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_134
#if defined(TEST_134) && __cplusplus >= 201103L
# include <experimental/unordered_map>
# include <experimental/type_traits>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_135
#if defined(TEST_135) && __cplusplus >= 201103L
# include <experimental/unordered_set>
# include <experimental/unordered_map>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_136
#if defined(TEST_136) && __cplusplus >= 201103L
# include <experimental/utility>
# include <experimental/unordered_set>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_137
#if defined(TEST_137) && __cplusplus >= 201103L
# include <experimental/utility>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif
// RUN: %{build} -DTEST_138
#if defined(TEST_138) && __cplusplus >= 201103L
# include <experimental/vector>
using HandlerType = decltype(std::__libcpp_verbose_abort);
#endif

View File

@ -134,6 +134,7 @@ END-SCRIPT
#endif
#include <map>
#include <math.h>
#include <mdspan>
#include <memory>
#include <memory_resource>
#if !defined(_LIBCPP_HAS_NO_THREADS)

View File

@ -132,6 +132,7 @@ END-SCRIPT
#endif
#include <map>
#include <math.h>
#include <mdspan>
#include <memory>
#include <memory_resource>
#if !defined(_LIBCPP_HAS_NO_THREADS)

View File

@ -203,6 +203,8 @@ TEST_MACROS();
TEST_MACROS();
#include <math.h>
TEST_MACROS();
#include <mdspan>
TEST_MACROS();
#include <memory>
TEST_MACROS();
#include <memory_resource>

View File

@ -465,405 +465,410 @@ END-SCRIPT
// RUN: echo 'TEST_71=$!' >> %t.sh
// RUN: echo "wait $TEST_55" >> %t.sh
#if defined(TEST_71)
#include <memory>
#include <mdspan>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_72 &' >> %t.sh
// RUN: echo 'TEST_72=$!' >> %t.sh
// RUN: echo "wait $TEST_56" >> %t.sh
#if defined(TEST_72)
#include <memory_resource>
#include <memory>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_73 &' >> %t.sh
// RUN: echo 'TEST_73=$!' >> %t.sh
// RUN: echo "wait $TEST_57" >> %t.sh
#if defined(TEST_73) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <mutex>
#if defined(TEST_73)
#include <memory_resource>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_74 &' >> %t.sh
// RUN: echo 'TEST_74=$!' >> %t.sh
// RUN: echo "wait $TEST_58" >> %t.sh
#if defined(TEST_74)
#include <new>
#if defined(TEST_74) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <mutex>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_75 &' >> %t.sh
// RUN: echo 'TEST_75=$!' >> %t.sh
// RUN: echo "wait $TEST_59" >> %t.sh
#if defined(TEST_75)
#include <numbers>
#include <new>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_76 &' >> %t.sh
// RUN: echo 'TEST_76=$!' >> %t.sh
// RUN: echo "wait $TEST_60" >> %t.sh
#if defined(TEST_76)
#include <numeric>
#include <numbers>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_77 &' >> %t.sh
// RUN: echo 'TEST_77=$!' >> %t.sh
// RUN: echo "wait $TEST_61" >> %t.sh
#if defined(TEST_77)
#include <optional>
#include <numeric>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_78 &' >> %t.sh
// RUN: echo 'TEST_78=$!' >> %t.sh
// RUN: echo "wait $TEST_62" >> %t.sh
#if defined(TEST_78) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <ostream>
#if defined(TEST_78)
#include <optional>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_79 &' >> %t.sh
// RUN: echo 'TEST_79=$!' >> %t.sh
// RUN: echo "wait $TEST_63" >> %t.sh
#if defined(TEST_79)
#include <queue>
#if defined(TEST_79) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <ostream>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_80 &' >> %t.sh
// RUN: echo 'TEST_80=$!' >> %t.sh
// RUN: echo "wait $TEST_64" >> %t.sh
#if defined(TEST_80)
#include <random>
#include <queue>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_81 &' >> %t.sh
// RUN: echo 'TEST_81=$!' >> %t.sh
// RUN: echo "wait $TEST_65" >> %t.sh
#if defined(TEST_81)
#include <ranges>
#include <random>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_82 &' >> %t.sh
// RUN: echo 'TEST_82=$!' >> %t.sh
// RUN: echo "wait $TEST_66" >> %t.sh
#if defined(TEST_82)
#include <ratio>
#include <ranges>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_83 &' >> %t.sh
// RUN: echo 'TEST_83=$!' >> %t.sh
// RUN: echo "wait $TEST_67" >> %t.sh
#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <regex>
#if defined(TEST_83)
#include <ratio>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_84 &' >> %t.sh
// RUN: echo 'TEST_84=$!' >> %t.sh
// RUN: echo "wait $TEST_68" >> %t.sh
#if defined(TEST_84)
#include <scoped_allocator>
#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <regex>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_85 &' >> %t.sh
// RUN: echo 'TEST_85=$!' >> %t.sh
// RUN: echo "wait $TEST_69" >> %t.sh
#if defined(TEST_85) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <semaphore>
#if defined(TEST_85)
#include <scoped_allocator>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_86 &' >> %t.sh
// RUN: echo 'TEST_86=$!' >> %t.sh
// RUN: echo "wait $TEST_70" >> %t.sh
#if defined(TEST_86)
#include <set>
#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <semaphore>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_87 &' >> %t.sh
// RUN: echo 'TEST_87=$!' >> %t.sh
// RUN: echo "wait $TEST_71" >> %t.sh
#if defined(TEST_87)
#include <setjmp.h>
#include <set>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_88 &' >> %t.sh
// RUN: echo 'TEST_88=$!' >> %t.sh
// RUN: echo "wait $TEST_72" >> %t.sh
#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <shared_mutex>
#if defined(TEST_88)
#include <setjmp.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_89 &' >> %t.sh
// RUN: echo 'TEST_89=$!' >> %t.sh
// RUN: echo "wait $TEST_73" >> %t.sh
#if defined(TEST_89)
#include <source_location>
#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <shared_mutex>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_90 &' >> %t.sh
// RUN: echo 'TEST_90=$!' >> %t.sh
// RUN: echo "wait $TEST_74" >> %t.sh
#if defined(TEST_90)
#include <span>
#include <source_location>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_91 &' >> %t.sh
// RUN: echo 'TEST_91=$!' >> %t.sh
// RUN: echo "wait $TEST_75" >> %t.sh
#if defined(TEST_91) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <sstream>
#if defined(TEST_91)
#include <span>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_92 &' >> %t.sh
// RUN: echo 'TEST_92=$!' >> %t.sh
// RUN: echo "wait $TEST_76" >> %t.sh
#if defined(TEST_92)
#include <stack>
#if defined(TEST_92) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <sstream>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_93 &' >> %t.sh
// RUN: echo 'TEST_93=$!' >> %t.sh
// RUN: echo "wait $TEST_77" >> %t.sh
#if defined(TEST_93) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
#include <stdatomic.h>
#if defined(TEST_93)
#include <stack>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_94 &' >> %t.sh
// RUN: echo 'TEST_94=$!' >> %t.sh
// RUN: echo "wait $TEST_78" >> %t.sh
#if defined(TEST_94)
#include <stdbool.h>
#if defined(TEST_94) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS)
#include <stdatomic.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_95 &' >> %t.sh
// RUN: echo 'TEST_95=$!' >> %t.sh
// RUN: echo "wait $TEST_79" >> %t.sh
#if defined(TEST_95)
#include <stddef.h>
#include <stdbool.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_96 &' >> %t.sh
// RUN: echo 'TEST_96=$!' >> %t.sh
// RUN: echo "wait $TEST_80" >> %t.sh
#if defined(TEST_96)
#include <stdexcept>
#include <stddef.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_97 &' >> %t.sh
// RUN: echo 'TEST_97=$!' >> %t.sh
// RUN: echo "wait $TEST_81" >> %t.sh
#if defined(TEST_97)
#include <stdint.h>
#include <stdexcept>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_98 &' >> %t.sh
// RUN: echo 'TEST_98=$!' >> %t.sh
// RUN: echo "wait $TEST_82" >> %t.sh
#if defined(TEST_98)
#include <stdio.h>
#include <stdint.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_99 &' >> %t.sh
// RUN: echo 'TEST_99=$!' >> %t.sh
// RUN: echo "wait $TEST_83" >> %t.sh
#if defined(TEST_99)
#include <stdlib.h>
#include <stdio.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_100 &' >> %t.sh
// RUN: echo 'TEST_100=$!' >> %t.sh
// RUN: echo "wait $TEST_84" >> %t.sh
#if defined(TEST_100) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <streambuf>
#if defined(TEST_100)
#include <stdlib.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_101 &' >> %t.sh
// RUN: echo 'TEST_101=$!' >> %t.sh
// RUN: echo "wait $TEST_85" >> %t.sh
#if defined(TEST_101)
#include <string>
#if defined(TEST_101) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <streambuf>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_102 &' >> %t.sh
// RUN: echo 'TEST_102=$!' >> %t.sh
// RUN: echo "wait $TEST_86" >> %t.sh
#if defined(TEST_102)
#include <string.h>
#include <string>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_103 &' >> %t.sh
// RUN: echo 'TEST_103=$!' >> %t.sh
// RUN: echo "wait $TEST_87" >> %t.sh
#if defined(TEST_103)
#include <string_view>
#include <string.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_104 &' >> %t.sh
// RUN: echo 'TEST_104=$!' >> %t.sh
// RUN: echo "wait $TEST_88" >> %t.sh
#if defined(TEST_104) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <strstream>
#if defined(TEST_104)
#include <string_view>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_105 &' >> %t.sh
// RUN: echo 'TEST_105=$!' >> %t.sh
// RUN: echo "wait $TEST_89" >> %t.sh
#if defined(TEST_105)
#include <system_error>
#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_LOCALIZATION)
#include <strstream>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_106 &' >> %t.sh
// RUN: echo 'TEST_106=$!' >> %t.sh
// RUN: echo "wait $TEST_90" >> %t.sh
#if defined(TEST_106)
#include <tgmath.h>
#include <system_error>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_107 &' >> %t.sh
// RUN: echo 'TEST_107=$!' >> %t.sh
// RUN: echo "wait $TEST_91" >> %t.sh
#if defined(TEST_107) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <thread>
#if defined(TEST_107)
#include <tgmath.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_108 &' >> %t.sh
// RUN: echo 'TEST_108=$!' >> %t.sh
// RUN: echo "wait $TEST_92" >> %t.sh
#if defined(TEST_108)
#include <tuple>
#if defined(TEST_108) && !defined(_LIBCPP_HAS_NO_THREADS)
#include <thread>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_109 &' >> %t.sh
// RUN: echo 'TEST_109=$!' >> %t.sh
// RUN: echo "wait $TEST_93" >> %t.sh
#if defined(TEST_109)
#include <type_traits>
#include <tuple>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_110 &' >> %t.sh
// RUN: echo 'TEST_110=$!' >> %t.sh
// RUN: echo "wait $TEST_94" >> %t.sh
#if defined(TEST_110)
#include <typeindex>
#include <type_traits>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_111 &' >> %t.sh
// RUN: echo 'TEST_111=$!' >> %t.sh
// RUN: echo "wait $TEST_95" >> %t.sh
#if defined(TEST_111)
#include <typeinfo>
#include <typeindex>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_112 &' >> %t.sh
// RUN: echo 'TEST_112=$!' >> %t.sh
// RUN: echo "wait $TEST_96" >> %t.sh
#if defined(TEST_112)
#include <uchar.h>
#include <typeinfo>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_113 &' >> %t.sh
// RUN: echo 'TEST_113=$!' >> %t.sh
// RUN: echo "wait $TEST_97" >> %t.sh
#if defined(TEST_113)
#include <unordered_map>
#include <uchar.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_114 &' >> %t.sh
// RUN: echo 'TEST_114=$!' >> %t.sh
// RUN: echo "wait $TEST_98" >> %t.sh
#if defined(TEST_114)
#include <unordered_set>
#include <unordered_map>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_115 &' >> %t.sh
// RUN: echo 'TEST_115=$!' >> %t.sh
// RUN: echo "wait $TEST_99" >> %t.sh
#if defined(TEST_115)
#include <utility>
#include <unordered_set>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_116 &' >> %t.sh
// RUN: echo 'TEST_116=$!' >> %t.sh
// RUN: echo "wait $TEST_100" >> %t.sh
#if defined(TEST_116)
#include <valarray>
#include <utility>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_117 &' >> %t.sh
// RUN: echo 'TEST_117=$!' >> %t.sh
// RUN: echo "wait $TEST_101" >> %t.sh
#if defined(TEST_117)
#include <variant>
#include <valarray>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_118 &' >> %t.sh
// RUN: echo 'TEST_118=$!' >> %t.sh
// RUN: echo "wait $TEST_102" >> %t.sh
#if defined(TEST_118)
#include <vector>
#include <variant>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_119 &' >> %t.sh
// RUN: echo 'TEST_119=$!' >> %t.sh
// RUN: echo "wait $TEST_103" >> %t.sh
#if defined(TEST_119)
#include <version>
#include <vector>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_120 &' >> %t.sh
// RUN: echo 'TEST_120=$!' >> %t.sh
// RUN: echo "wait $TEST_104" >> %t.sh
#if defined(TEST_120) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#include <wchar.h>
#if defined(TEST_120)
#include <version>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_121 &' >> %t.sh
// RUN: echo 'TEST_121=$!' >> %t.sh
// RUN: echo "wait $TEST_105" >> %t.sh
#if defined(TEST_121) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#include <wctype.h>
#include <wchar.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_122 &' >> %t.sh
// RUN: echo 'TEST_122=$!' >> %t.sh
// RUN: echo "wait $TEST_106" >> %t.sh
#if defined(TEST_122) && __cplusplus >= 201103L
#include <experimental/deque>
#if defined(TEST_122) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#include <wctype.h>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_123 &' >> %t.sh
// RUN: echo 'TEST_123=$!' >> %t.sh
// RUN: echo "wait $TEST_107" >> %t.sh
#if defined(TEST_123) && __cplusplus >= 201103L
#include <experimental/forward_list>
#include <experimental/deque>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_124 &' >> %t.sh
// RUN: echo 'TEST_124=$!' >> %t.sh
// RUN: echo "wait $TEST_108" >> %t.sh
#if defined(TEST_124) && __cplusplus >= 201103L
#include <experimental/iterator>
#include <experimental/forward_list>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_125 &' >> %t.sh
// RUN: echo 'TEST_125=$!' >> %t.sh
// RUN: echo "wait $TEST_109" >> %t.sh
#if defined(TEST_125) && __cplusplus >= 201103L
#include <experimental/list>
#include <experimental/iterator>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_126 &' >> %t.sh
// RUN: echo 'TEST_126=$!' >> %t.sh
// RUN: echo "wait $TEST_110" >> %t.sh
#if defined(TEST_126) && __cplusplus >= 201103L
#include <experimental/map>
#include <experimental/list>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_127 &' >> %t.sh
// RUN: echo 'TEST_127=$!' >> %t.sh
// RUN: echo "wait $TEST_111" >> %t.sh
#if defined(TEST_127) && __cplusplus >= 201103L
#include <experimental/memory_resource>
#include <experimental/map>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_128 &' >> %t.sh
// RUN: echo 'TEST_128=$!' >> %t.sh
// RUN: echo "wait $TEST_112" >> %t.sh
#if defined(TEST_128) && __cplusplus >= 201103L
#include <experimental/propagate_const>
#include <experimental/memory_resource>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_129 &' >> %t.sh
// RUN: echo 'TEST_129=$!' >> %t.sh
// RUN: echo "wait $TEST_113" >> %t.sh
#if defined(TEST_129) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
#include <experimental/regex>
#if defined(TEST_129) && __cplusplus >= 201103L
#include <experimental/propagate_const>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_130 &' >> %t.sh
// RUN: echo 'TEST_130=$!' >> %t.sh
// RUN: echo "wait $TEST_114" >> %t.sh
#if defined(TEST_130) && __cplusplus >= 201103L
#include <experimental/set>
#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L
#include <experimental/regex>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_131 &' >> %t.sh
// RUN: echo 'TEST_131=$!' >> %t.sh
// RUN: echo "wait $TEST_115" >> %t.sh
#if defined(TEST_131) && __cplusplus >= 201103L
#include <experimental/simd>
#include <experimental/set>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_132 &' >> %t.sh
// RUN: echo 'TEST_132=$!' >> %t.sh
// RUN: echo "wait $TEST_116" >> %t.sh
#if defined(TEST_132) && __cplusplus >= 201103L
#include <experimental/string>
#include <experimental/simd>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_133 &' >> %t.sh
// RUN: echo 'TEST_133=$!' >> %t.sh
// RUN: echo "wait $TEST_117" >> %t.sh
#if defined(TEST_133) && __cplusplus >= 201103L
#include <experimental/type_traits>
#include <experimental/string>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_134 &' >> %t.sh
// RUN: echo 'TEST_134=$!' >> %t.sh
// RUN: echo "wait $TEST_118" >> %t.sh
#if defined(TEST_134) && __cplusplus >= 201103L
#include <experimental/unordered_map>
#include <experimental/type_traits>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_135 &' >> %t.sh
// RUN: echo 'TEST_135=$!' >> %t.sh
// RUN: echo "wait $TEST_119" >> %t.sh
#if defined(TEST_135) && __cplusplus >= 201103L
#include <experimental/unordered_set>
#include <experimental/unordered_map>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_136 &' >> %t.sh
// RUN: echo 'TEST_136=$!' >> %t.sh
// RUN: echo "wait $TEST_120" >> %t.sh
#if defined(TEST_136) && __cplusplus >= 201103L
#include <experimental/utility>
#include <experimental/unordered_set>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_137 &' >> %t.sh
// RUN: echo 'TEST_137=$!' >> %t.sh
// RUN: echo "wait $TEST_121" >> %t.sh
#if defined(TEST_137) && __cplusplus >= 201103L
#include <experimental/utility>
#endif
// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_138 &' >> %t.sh
// RUN: echo 'TEST_138=$!' >> %t.sh
// RUN: echo "wait $TEST_122" >> %t.sh
#if defined(TEST_138) && __cplusplus >= 201103L
#include <experimental/vector>
#endif
// RUN: echo "wait $TEST_122" >> %t.sh
// RUN: echo "wait $TEST_123" >> %t.sh
// RUN: echo "wait $TEST_124" >> %t.sh
// RUN: echo "wait $TEST_125" >> %t.sh
@ -879,5 +884,6 @@ END-SCRIPT
// RUN: echo "wait $TEST_135" >> %t.sh
// RUN: echo "wait $TEST_136" >> %t.sh
// RUN: echo "wait $TEST_137" >> %t.sh
// RUN: echo "wait $TEST_138" >> %t.sh
// RUN: bash %t.sh
// GENERATED-MARKER

View File

@ -257,6 +257,7 @@ END-SCRIPT
#endif
#include <map>
#include <math.h>
#include <mdspan>
#include <memory>
#include <memory_resource>
#if !defined(_LIBCPP_HAS_NO_THREADS)

View File

@ -129,6 +129,7 @@ END-SCRIPT
#endif
#include <map>
#include <math.h>
#include <mdspan>
#include <memory>
#include <memory_resource>
#if !defined(_LIBCPP_HAS_NO_THREADS)

View File

@ -493,6 +493,7 @@ END-SCRIPT
#include <__iterator/wrap_iter.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/wrap_iter.h'}}
#include <__locale> // expected-error@*:* {{use of private header from outside its module: '__locale'}}
#include <__mbstate_t.h> // expected-error@*:* {{use of private header from outside its module: '__mbstate_t.h'}}
#include <__mdspan/extents.h> // expected-error@*:* {{use of private header from outside its module: '__mdspan/extents.h'}}
#include <__memory/addressof.h> // expected-error@*:* {{use of private header from outside its module: '__memory/addressof.h'}}
#include <__memory/align.h> // expected-error@*:* {{use of private header from outside its module: '__memory/align.h'}}
#include <__memory/aligned_alloc.h> // expected-error@*:* {{use of private header from outside its module: '__memory/aligned_alloc.h'}}

View File

@ -317,224 +317,228 @@ END-SCRIPT
#if defined(TEST_69)
#include <map>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 > /dev/null 2> %t/header.memory
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 > /dev/null 2> %t/header.mdspan
#if defined(TEST_71)
#include <mdspan>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 > /dev/null 2> %t/header.memory
#if defined(TEST_72)
#include <memory>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 > /dev/null 2> %t/header.memory_resource
#if defined(TEST_72)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 > /dev/null 2> %t/header.memory_resource
#if defined(TEST_73)
#include <memory_resource>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 > /dev/null 2> %t/header.mutex
#if defined(TEST_73)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 > /dev/null 2> %t/header.mutex
#if defined(TEST_74)
#include <mutex>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 > /dev/null 2> %t/header.new
#if defined(TEST_74)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 > /dev/null 2> %t/header.new
#if defined(TEST_75)
#include <new>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 > /dev/null 2> %t/header.numbers
#if defined(TEST_75)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 > /dev/null 2> %t/header.numbers
#if defined(TEST_76)
#include <numbers>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 > /dev/null 2> %t/header.numeric
#if defined(TEST_76)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 > /dev/null 2> %t/header.numeric
#if defined(TEST_77)
#include <numeric>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 > /dev/null 2> %t/header.optional
#if defined(TEST_77)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 > /dev/null 2> %t/header.optional
#if defined(TEST_78)
#include <optional>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 > /dev/null 2> %t/header.ostream
#if defined(TEST_78)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 > /dev/null 2> %t/header.ostream
#if defined(TEST_79)
#include <ostream>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 > /dev/null 2> %t/header.queue
#if defined(TEST_79)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 > /dev/null 2> %t/header.queue
#if defined(TEST_80)
#include <queue>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 > /dev/null 2> %t/header.random
#if defined(TEST_80)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 > /dev/null 2> %t/header.random
#if defined(TEST_81)
#include <random>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 > /dev/null 2> %t/header.ranges
#if defined(TEST_81)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 > /dev/null 2> %t/header.ranges
#if defined(TEST_82)
#include <ranges>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 > /dev/null 2> %t/header.ratio
#if defined(TEST_82)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 > /dev/null 2> %t/header.ratio
#if defined(TEST_83)
#include <ratio>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 > /dev/null 2> %t/header.regex
#if defined(TEST_83)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 > /dev/null 2> %t/header.regex
#if defined(TEST_84)
#include <regex>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 > /dev/null 2> %t/header.scoped_allocator
#if defined(TEST_84)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 > /dev/null 2> %t/header.scoped_allocator
#if defined(TEST_85)
#include <scoped_allocator>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 > /dev/null 2> %t/header.semaphore
#if defined(TEST_85)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 > /dev/null 2> %t/header.semaphore
#if defined(TEST_86)
#include <semaphore>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 > /dev/null 2> %t/header.set
#if defined(TEST_86)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_87 > /dev/null 2> %t/header.set
#if defined(TEST_87)
#include <set>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_88 > /dev/null 2> %t/header.shared_mutex
#if defined(TEST_88)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 > /dev/null 2> %t/header.shared_mutex
#if defined(TEST_89)
#include <shared_mutex>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 > /dev/null 2> %t/header.source_location
#if defined(TEST_89)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 > /dev/null 2> %t/header.source_location
#if defined(TEST_90)
#include <source_location>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 > /dev/null 2> %t/header.span
#if defined(TEST_90)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 > /dev/null 2> %t/header.span
#if defined(TEST_91)
#include <span>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 > /dev/null 2> %t/header.sstream
#if defined(TEST_91)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 > /dev/null 2> %t/header.sstream
#if defined(TEST_92)
#include <sstream>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 > /dev/null 2> %t/header.stack
#if defined(TEST_92)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_93 > /dev/null 2> %t/header.stack
#if defined(TEST_93)
#include <stack>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_96 > /dev/null 2> %t/header.stdexcept
#if defined(TEST_96)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_97 > /dev/null 2> %t/header.stdexcept
#if defined(TEST_97)
#include <stdexcept>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_100 > /dev/null 2> %t/header.streambuf
#if defined(TEST_100)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 > /dev/null 2> %t/header.streambuf
#if defined(TEST_101)
#include <streambuf>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 > /dev/null 2> %t/header.string
#if defined(TEST_101)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_102 > /dev/null 2> %t/header.string
#if defined(TEST_102)
#include <string>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_103 > /dev/null 2> %t/header.string_view
#if defined(TEST_103)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 > /dev/null 2> %t/header.string_view
#if defined(TEST_104)
#include <string_view>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 > /dev/null 2> %t/header.strstream
#if defined(TEST_104)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 > /dev/null 2> %t/header.strstream
#if defined(TEST_105)
#include <strstream>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 > /dev/null 2> %t/header.system_error
#if defined(TEST_105)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_106 > /dev/null 2> %t/header.system_error
#if defined(TEST_106)
#include <system_error>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_107 > /dev/null 2> %t/header.thread
#if defined(TEST_107)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 > /dev/null 2> %t/header.thread
#if defined(TEST_108)
#include <thread>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 > /dev/null 2> %t/header.tuple
#if defined(TEST_108)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 > /dev/null 2> %t/header.tuple
#if defined(TEST_109)
#include <tuple>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 > /dev/null 2> %t/header.type_traits
#if defined(TEST_109)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 > /dev/null 2> %t/header.type_traits
#if defined(TEST_110)
#include <type_traits>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 > /dev/null 2> %t/header.typeindex
#if defined(TEST_110)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 > /dev/null 2> %t/header.typeindex
#if defined(TEST_111)
#include <typeindex>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 > /dev/null 2> %t/header.typeinfo
#if defined(TEST_111)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_112 > /dev/null 2> %t/header.typeinfo
#if defined(TEST_112)
#include <typeinfo>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_113 > /dev/null 2> %t/header.unordered_map
#if defined(TEST_113)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 > /dev/null 2> %t/header.unordered_map
#if defined(TEST_114)
#include <unordered_map>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 > /dev/null 2> %t/header.unordered_set
#if defined(TEST_114)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 > /dev/null 2> %t/header.unordered_set
#if defined(TEST_115)
#include <unordered_set>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 > /dev/null 2> %t/header.utility
#if defined(TEST_115)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 > /dev/null 2> %t/header.utility
#if defined(TEST_116)
#include <utility>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 > /dev/null 2> %t/header.valarray
#if defined(TEST_116)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 > /dev/null 2> %t/header.valarray
#if defined(TEST_117)
#include <valarray>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 > /dev/null 2> %t/header.variant
#if defined(TEST_117)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 > /dev/null 2> %t/header.variant
#if defined(TEST_118)
#include <variant>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 > /dev/null 2> %t/header.vector
#if defined(TEST_118)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 > /dev/null 2> %t/header.vector
#if defined(TEST_119)
#include <vector>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 > /dev/null 2> %t/header.version
#if defined(TEST_119)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_120 > /dev/null 2> %t/header.version
#if defined(TEST_120)
#include <version>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_122 > /dev/null 2> %t/header.experimental_deque
#if defined(TEST_122)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 > /dev/null 2> %t/header.experimental_deque
#if defined(TEST_123)
#include <experimental/deque>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 > /dev/null 2> %t/header.experimental_forward_list
#if defined(TEST_123)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 > /dev/null 2> %t/header.experimental_forward_list
#if defined(TEST_124)
#include <experimental/forward_list>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 > /dev/null 2> %t/header.experimental_iterator
#if defined(TEST_124)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 > /dev/null 2> %t/header.experimental_iterator
#if defined(TEST_125)
#include <experimental/iterator>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 > /dev/null 2> %t/header.experimental_list
#if defined(TEST_125)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 > /dev/null 2> %t/header.experimental_list
#if defined(TEST_126)
#include <experimental/list>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 > /dev/null 2> %t/header.experimental_map
#if defined(TEST_126)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 > /dev/null 2> %t/header.experimental_map
#if defined(TEST_127)
#include <experimental/map>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 > /dev/null 2> %t/header.experimental_memory_resource
#if defined(TEST_127)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 > /dev/null 2> %t/header.experimental_memory_resource
#if defined(TEST_128)
#include <experimental/memory_resource>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 > /dev/null 2> %t/header.experimental_propagate_const
#if defined(TEST_128)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 > /dev/null 2> %t/header.experimental_propagate_const
#if defined(TEST_129)
#include <experimental/propagate_const>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 > /dev/null 2> %t/header.experimental_regex
#if defined(TEST_129)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 > /dev/null 2> %t/header.experimental_regex
#if defined(TEST_130)
#include <experimental/regex>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 > /dev/null 2> %t/header.experimental_set
#if defined(TEST_130)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 > /dev/null 2> %t/header.experimental_set
#if defined(TEST_131)
#include <experimental/set>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 > /dev/null 2> %t/header.experimental_simd
#if defined(TEST_131)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 > /dev/null 2> %t/header.experimental_simd
#if defined(TEST_132)
#include <experimental/simd>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 > /dev/null 2> %t/header.experimental_string
#if defined(TEST_132)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 > /dev/null 2> %t/header.experimental_string
#if defined(TEST_133)
#include <experimental/string>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 > /dev/null 2> %t/header.experimental_type_traits
#if defined(TEST_133)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 > /dev/null 2> %t/header.experimental_type_traits
#if defined(TEST_134)
#include <experimental/type_traits>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 > /dev/null 2> %t/header.experimental_unordered_map
#if defined(TEST_134)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 > /dev/null 2> %t/header.experimental_unordered_map
#if defined(TEST_135)
#include <experimental/unordered_map>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 > /dev/null 2> %t/header.experimental_unordered_set
#if defined(TEST_135)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 > /dev/null 2> %t/header.experimental_unordered_set
#if defined(TEST_136)
#include <experimental/unordered_set>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 > /dev/null 2> %t/header.experimental_utility
#if defined(TEST_136)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 > /dev/null 2> %t/header.experimental_utility
#if defined(TEST_137)
#include <experimental/utility>
#endif
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 > /dev/null 2> %t/header.experimental_vector
#if defined(TEST_137)
// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_138 > /dev/null 2> %t/header.experimental_vector
#if defined(TEST_138)
#include <experimental/vector>
#endif
// RUN: %{python} %S/transitive_includes_to_csv.py %t > %t/transitive_includes.csv

View File

@ -515,6 +515,12 @@ map tuple
map type_traits
map utility
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory atomic
memory compare
memory concepts

1 algorithm atomic
515 map type_traits
516 map utility
517 map version
518 mdspan array
519 mdspan cinttypes
520 mdspan concepts
521 mdspan cstddef
522 mdspan limits
523 mdspan span
524 memory atomic
525 memory compare
526 memory concepts

View File

@ -515,6 +515,12 @@ map tuple
map type_traits
map utility
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory atomic
memory compare
memory concepts

1 algorithm atomic
515 map type_traits
516 map utility
517 map version
518 mdspan array
519 mdspan cinttypes
520 mdspan concepts
521 mdspan cstddef
522 mdspan limits
523 mdspan span
524 memory atomic
525 memory compare
526 memory concepts

View File

@ -517,6 +517,12 @@ map tuple
map type_traits
map utility
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory atomic
memory compare
memory concepts

1 algorithm atomic
517 map type_traits
518 map utility
519 map version
520 mdspan array
521 mdspan cinttypes
522 mdspan concepts
523 mdspan cstddef
524 mdspan limits
525 mdspan span
526 memory atomic
527 memory compare
528 memory concepts

View File

@ -517,6 +517,12 @@ map tuple
map type_traits
map utility
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory atomic
memory compare
memory concepts

1 algorithm atomic
517 map type_traits
518 map utility
519 map version
520 mdspan array
521 mdspan cinttypes
522 mdspan concepts
523 mdspan cstddef
524 mdspan limits
525 mdspan span
526 memory atomic
527 memory compare
528 memory concepts

View File

@ -523,6 +523,12 @@ map tuple
map type_traits
map utility
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory atomic
memory compare
memory concepts

1 algorithm atomic
523 map type_traits
524 map utility
525 map version
526 mdspan array
527 mdspan cinttypes
528 mdspan concepts
529 mdspan cstddef
530 mdspan limits
531 mdspan span
532 memory atomic
533 memory compare
534 memory concepts

View File

@ -351,6 +351,12 @@ map optional
map stdexcept
map tuple
map version
mdspan array
mdspan cinttypes
mdspan concepts
mdspan cstddef
mdspan limits
mdspan span
memory compare
memory cstddef
memory cstdint

1 algorithm climits
351 map stdexcept
352 map tuple
353 map version
354 mdspan array
355 mdspan cinttypes
356 mdspan concepts
357 mdspan cstddef
358 mdspan limits
359 mdspan span
360 memory compare
361 memory cstddef
362 memory cstdint

View File

@ -0,0 +1,22 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H
#define TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H
struct IntType {
int val;
constexpr IntType() = default;
constexpr IntType(int v) noexcept : val(v){};
constexpr bool operator==(const IntType& rhs) const { return val == rhs.val; }
constexpr operator int() const noexcept { return val; }
constexpr operator unsigned char() const noexcept { return val; }
};
#endif // TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H

View File

@ -0,0 +1,99 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
#include <mdspan>
#include <cassert>
#include <array>
#include <span>
#include "ConvertibleToIntegral.h"
#include "test_macros.h"
// Helper file to implement combinatorical testing of extents constructor
//
// std::extents can be constructed from just indices, a std::array, or a std::span
// In each of those cases one can either provide all extents, or just the dynamic ones
// If constructed from std::span, the span needs to have a static extent
// Furthermore, the indices/array/span can have integer types other than index_type
template <class E, class AllExtents>
constexpr void test_runtime_observers(E ext, AllExtents expected) {
for (typename E::rank_type r = 0; r < ext.rank(); r++) {
ASSERT_SAME_TYPE(decltype(ext.extent(0)), typename E::index_type);
ASSERT_NOEXCEPT(ext.extent(0));
assert(ext.extent(r) == static_cast<typename E::index_type>(expected[r]));
}
}
template <class E, class AllExtents>
constexpr void test_implicit_construction_call(E e, AllExtents all_ext) {
test_runtime_observers(e, all_ext);
}
template <class E, class Test, class AllExtents>
constexpr void test_construction(AllExtents all_ext) {
// test construction from all extents
Test::template test_construction<E>(all_ext, all_ext, std::make_index_sequence<E::rank()>());
// test construction from just dynamic extents
// create an array of just the extents corresponding to dynamic values
std::array<typename AllExtents::value_type, E::rank_dynamic()> dyn_ext{0};
size_t dynamic_idx = 0;
for (size_t r = 0; r < E::rank(); r++) {
if (E::static_extent(r) == std::dynamic_extent) {
dyn_ext[dynamic_idx] = all_ext[r];
dynamic_idx++;
}
}
Test::template test_construction<E>(all_ext, dyn_ext, std::make_index_sequence<E::rank_dynamic()>());
}
template <class T, class TArg, class Test>
constexpr void test() {
constexpr size_t D = std::dynamic_extent;
test_construction<std::extents<T>, Test>(std::array<TArg, 0>{});
test_construction<std::extents<T, 3>, Test>(std::array<TArg, 1>{3});
test_construction<std::extents<T, D>, Test>(std::array<TArg, 1>{3});
test_construction<std::extents<T, 3, 7>, Test>(std::array<TArg, 2>{3, 7});
test_construction<std::extents<T, 3, D>, Test>(std::array<TArg, 2>{3, 7});
test_construction<std::extents<T, D, 7>, Test>(std::array<TArg, 2>{3, 7});
test_construction<std::extents<T, D, D>, Test>(std::array<TArg, 2>{3, 7});
test_construction<std::extents<T, 3, 7, 9>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, 3, 7, D>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, 3, D, D>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, D, 7, D>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, D, D, D>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, 3, D, 9>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, D, D, 9>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, D, 7, 9>, Test>(std::array<TArg, 3>{3, 7, 9});
test_construction<std::extents<T, 1, 2, 3, 4, 5, 6, 7, 8, 9>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9});
test_construction<std::extents<T, D, 2, 3, D, 5, D, 7, D, 9>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9});
test_construction<std::extents<T, D, D, D, D, D, D, D, D, D>, Test>(std::array<TArg, 9>{1, 2, 3, 4, 5, 6, 7, 8, 9});
}
template <class Test>
constexpr bool test_index_type_combo() {
test<int, int, Test>();
test<int, size_t, Test>();
test<unsigned, int, Test>();
test<char, size_t, Test>();
test<long long, unsigned, Test>();
test<size_t, int, Test>();
test<size_t, size_t, Test>();
test<int, IntType, Test>();
test<unsigned char, IntType, Test>();
return true;
}

View File

@ -0,0 +1,57 @@
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// XFAIL: availability-verbose_abort-missing
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
// <mdspan>
// template<class OtherIndexType, size_t... OtherExtents>
// constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
//
// Constraints:
// * sizeof...(OtherExtents) == rank() is true.
// * ((OtherExtents == dynamic_extent || Extents == dynamic_extent ||
// OtherExtents == Extents) && ...) is true.
//
// Preconditions:
// * other.extent(r) equals Er for each r for which Er is a static extent, and
// * either
// - sizeof...(OtherExtents) is zero, or
// - other.extent(r) is representable as a value of type index_type for
// every rank index r of other.
//
// Remarks: The expression inside explicit is equivalent to:
// (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
// (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
#include <mdspan>
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
constexpr size_t D = std::dynamic_extent;
std::extents<int, D, D> arg{1000, 5};
// working case
{
[[maybe_unused]] std::extents<size_t, D, 5> e(arg); // should work
}
// mismatch of static extent
{
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<int, D, 3> e(arg); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e(arg); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
}

View File

@ -0,0 +1,69 @@
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// XFAIL: availability-verbose_abort-missing
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
// <mdspan>
// Test construction from array:
//
// template<class OtherIndexType, size_t N>
// constexpr explicit(N != rank_dynamic()) extents(const array<OtherIndexType, N>& exts) noexcept;
//
// Constraints:
// * is_convertible_v<const OtherIndexType&, index_type> is true,
// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - N is zero, or
// - exts[r] is nonnegative and is representable as a value of type index_type
// for every rank index r.
//
#include <mdspan>
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
constexpr size_t D = std::dynamic_extent;
// working case
{
[[maybe_unused]] std::extents<int, D, 5> e1(std::array{1000, 5}); // should work
}
// mismatch of static extent
{
TEST_LIBCPP_ASSERT_FAILURE(
([] {
std::extents<int, D, 5> e1(std::array{1000, 3});
}()),
"extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
TEST_LIBCPP_ASSERT_FAILURE(
([] {
std::extents<char, D, 5> e1(std::array{1000, 5});
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
// negative value
{
TEST_LIBCPP_ASSERT_FAILURE(
([] {
std::extents<char, D, 5> e1(std::array{-1, 5});
}()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
}

View File

@ -0,0 +1,62 @@
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// XFAIL: availability-verbose_abort-missing
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
// <mdspan>
// Test construction from integral:
//
// template<class ... OtherIndexTypes>
// constexpr explicit extents(OtherIndexTypes ... exts) noexcept;
//
// Let N be sizeof...(OtherIndexTypes), and let
// exts_arr be array<index_type, N>{static_cast<index_type>(std::move(exts))...}.
//
// Constraints:
// * (is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
// * (is_nothrow_constructible_v<index_type, OtherIndexType> && ...) is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts_arr[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - sizeof...(exts) == 0 is true, or
// - each element of exts is nonnegative and is representable as a value of type index_type.
//
#include <mdspan>
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
constexpr size_t D = std::dynamic_extent;
// working case
{
[[maybe_unused]] std::extents<int, D, 5> e1(1000, 5); // should work
}
// mismatch of static extent
{
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<int, D, 5> e1(1000, 3); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<char, D, 5> e1(1000, 5); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
// negative value
{
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<char, D, 5> e1(-1, 5); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
}

View File

@ -0,0 +1,62 @@
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// XFAIL: availability-verbose_abort-missing
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
// Test construction from span:
//
// template<class OtherIndexType, size_t N>
// constexpr explicit(N != rank_dynamic()) extents(span<OtherIndexType, N> exts) noexcept;
//
// Constraints:
// * is_convertible_v<const OtherIndexType&, index_type> is true,
// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - N is zero, or
// - exts[r] is nonnegative and is representable as a value of type index_type
// for every rank index r.
//
#include <mdspan>
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
constexpr size_t D = std::dynamic_extent;
// working case sanity check
{
std::array args{1000, 5};
[[maybe_unused]] std::extents<int, D, 5> e1(std::span{args});
}
// mismatch of static extent
{
std::array args{1000, 3};
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<int, D, 5> e1(std::span{args}); }()),
"extents construction: mismatch of provided arguments with static extents.");
}
// value out of range
{
std::array args{1000, 5};
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e1(std::span{args}); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
// negative value
{
std::array args{-1, 5};
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e1(std::span{args}); }()),
"extents ctor: arguments must be representable as index_type and nonnegative");
}
return 0;
}

View File

@ -0,0 +1,65 @@
//
// 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
//
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
// XFAIL: availability-verbose_abort-missing
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
// <mdspan>
// static constexpr size_t static_extent(rank_type i) noexcept;
//
// Preconditions: i < rank() is true.
//
// Returns: Ei.
//
//
// constexpr index_type extent(rank_type i) const noexcept;
//
// Preconditions: i < rank() is true.
//
// Returns: Di.
#include <mdspan>
#include <cassert>
#include "check_assertion.h"
int main(int, char**) {
constexpr size_t D = std::dynamic_extent;
// mismatch of static extent
{
std::extents<int> e;
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(0); }()), "extents access: index must be less than rank");
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(0); }()), "extents access: index must be less than rank");
}
{
std::extents<int, D> e;
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, 5> e;
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, D, 5> e;
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(2); }()), "extents access: index must be less than rank");
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(2); }()), "extents access: index must be less than rank");
}
{
std::extents<int, 1, 2, 3, 4, 5, 6, 7, 8> e;
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.extent(9); }()), "extents access: index must be less than rank");
TEST_LIBCPP_ASSERT_FAILURE(([=] { e.static_extent(9); }()), "extents access: index must be less than rank");
}
// check that static_extent works in constant expression with assertions enabled
static_assert(std::extents<int, D, 5>::static_extent(1) == 5);
return 0;
}

View File

@ -0,0 +1,95 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
//
// template<class OtherIndexType, size_t... OtherExtents>
// friend constexpr bool operator==(const extents& lhs,
// const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
//
// Returns: true if lhs.rank() equals rhs.rank() and
// if lhs.extent(r) equals rhs.extent(r) for every rank index r of rhs, otherwise false.
//
#include <mdspan>
#include <type_traits>
#include <concepts>
#include <cassert>
#include "test_macros.h"
template <class To, class From>
constexpr void test_comparison(bool equal, To dest, From src) {
ASSERT_NOEXCEPT(dest == src);
assert((dest == src) == equal);
assert((dest != src) == !equal);
}
template <class T1, class T2>
constexpr void test_comparison_different_rank() {
constexpr size_t D = std::dynamic_extent;
test_comparison(false, std::extents<T1>(), std::extents<T2, D>(1));
test_comparison(false, std::extents<T1>(), std::extents<T2, 1>());
test_comparison(false, std::extents<T1, D>(1), std::extents<T2>());
test_comparison(false, std::extents<T1, 1>(), std::extents<T2>());
test_comparison(false, std::extents<T1, D>(5), std::extents<T2, D, D>(5, 5));
test_comparison(false, std::extents<T1, 5>(), std::extents<T2, 5, D>(5));
test_comparison(false, std::extents<T1, 5>(), std::extents<T2, 5, 1>());
test_comparison(false, std::extents<T1, D, D>(5, 5), std::extents<T2, D>(5));
test_comparison(false, std::extents<T1, 5, D>(5), std::extents<T2, D>(5));
test_comparison(false, std::extents<T1, 5, 5>(), std::extents<T2, 5>());
}
template <class T1, class T2>
constexpr void test_comparison_same_rank() {
constexpr size_t D = std::dynamic_extent;
test_comparison(true, std::extents<T1>(), std::extents<T2>());
test_comparison(true, std::extents<T1, D>(5), std::extents<T2, D>(5));
test_comparison(true, std::extents<T1, 5>(), std::extents<T2, D>(5));
test_comparison(true, std::extents<T1, D>(5), std::extents<T2, 5>());
test_comparison(true, std::extents<T1, 5>(), std::extents< T2, 5>());
test_comparison(false, std::extents<T1, D>(5), std::extents<T2, D>(7));
test_comparison(false, std::extents<T1, 5>(), std::extents<T2, D>(7));
test_comparison(false, std::extents<T1, D>(5), std::extents<T2, 7>());
test_comparison(false, std::extents<T1, 5>(), std::extents<T2, 7>());
test_comparison(true, std::extents<T1, D, D, D, D, D>(5, 6, 7, 8, 9), std::extents<T2, D, D, D, D, D>(5, 6, 7, 8, 9));
test_comparison(true, std::extents<T1, D, 6, D, 8, D>(5, 7, 9), std::extents<T2, 5, D, D, 8, 9>(6, 7));
test_comparison(true, std::extents<T1, 5, 6, 7, 8, 9>(5, 6, 7, 8, 9), std::extents<T2, 5, 6, 7, 8, 9>());
test_comparison(
false, std::extents<T1, D, D, D, D, D>(5, 6, 7, 8, 9), std::extents<T2, D, D, D, D, D>(5, 6, 3, 8, 9));
test_comparison(false, std::extents<T1, D, 6, D, 8, D>(5, 7, 9), std::extents<T2, 5, D, D, 3, 9>(6, 7));
test_comparison(false, std::extents<T1, 5, 6, 7, 8, 9>(5, 6, 7, 8, 9), std::extents<T2, 5, 6, 7, 3, 9>());
}
template <class T1, class T2>
constexpr void test_comparison() {
test_comparison_same_rank<T1, T2>();
test_comparison_different_rank<T1, T2>();
}
constexpr bool test() {
test_comparison<int, int>();
test_comparison<int, size_t>();
test_comparison<size_t, int>();
test_comparison<size_t, long>();
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}

View File

@ -0,0 +1,138 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// template<class OtherIndexType, size_t... OtherExtents>
// constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents...>&) noexcept;
//
// Constraints:
// * sizeof...(OtherExtents) == rank() is true.
// * ((OtherExtents == dynamic_extent || Extents == dynamic_extent ||
// OtherExtents == Extents) && ...) is true.
//
// Preconditions:
// * other.extent(r) equals Er for each r for which Er is a static extent, and
// * either
// - sizeof...(OtherExtents) is zero, or
// - other.extent(r) is representable as a value of type index_type for
// every rank index r of other.
//
// Remarks: The expression inside explicit is equivalent to:
// (((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||
// (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
#include <mdspan>
#include <type_traits>
#include <concepts>
#include <cassert>
#include <limits>
#include "test_macros.h"
template <class To, class From>
constexpr void test_implicit_conversion(To dest, From src) {
assert(dest == src);
}
template <bool implicit, class To, class From>
constexpr void test_conversion(From src) {
To dest(src);
assert(dest == src);
if constexpr (implicit) {
dest = src;
assert(dest == src);
test_implicit_conversion<To, From>(src, src);
}
}
template <class T1, class T2>
constexpr void test_conversion() {
constexpr size_t D = std::dynamic_extent;
constexpr bool idx_convertible =
static_cast<size_t>(std::numeric_limits<T1>::max()) >= static_cast<size_t>(std::numeric_limits<T2>::max());
// clang-format off
test_conversion<idx_convertible && true, std::extents<T1>>(std::extents<T2>());
test_conversion<idx_convertible && true, std::extents<T1, D>>(std::extents<T2, D>(5));
test_conversion<idx_convertible && false, std::extents<T1, 5>>(std::extents<T2, D>(5));
test_conversion<idx_convertible && true, std::extents<T1, 5>>(std::extents<T2, 5>());
test_conversion<idx_convertible && false, std::extents<T1, 5, D>>(std::extents<T2, D, D>(5, 5));
test_conversion<idx_convertible && true, std::extents<T1, D, D>>(std::extents<T2, D, D>(5, 5));
test_conversion<idx_convertible && true, std::extents<T1, D, D>>(std::extents<T2, D, 7>(5));
test_conversion<idx_convertible && true, std::extents<T1, 5, 7>>(std::extents<T2, 5, 7>());
test_conversion<idx_convertible && false, std::extents<T1, 5, D, 8, D, D>>(std::extents<T2, D, D, 8, 9, 1>(5, 7));
test_conversion<idx_convertible && true, std::extents<T1, D, D, D, D, D>>(
std::extents<T2, D, D, D, D, D>(5, 7, 8, 9, 1));
test_conversion<idx_convertible && true, std::extents<T1, D, D, 8, 9, D>>(std::extents<T2, D, 7, 8, 9, 1>(5));
test_conversion<idx_convertible && true, std::extents<T1, 5, 7, 8, 9, 1>>(std::extents<T2, 5, 7, 8, 9, 1>());
// clang-format on
}
constexpr void test_no_implicit_conversion() {
constexpr size_t D = std::dynamic_extent;
// Sanity check that one static to dynamic conversion works
static_assert(std::is_constructible_v<std::extents<int, D>, std::extents<int, 5>>, "");
static_assert(std::is_convertible_v<std::extents<int, 5>, std::extents<int, D>>, "");
// Check that dynamic to static conversion only works explicitly only
static_assert(std::is_constructible_v<std::extents<int, 5>, std::extents<int, D>>, "");
static_assert(!std::is_convertible_v<std::extents<int, D>, std::extents<int, 5>>, "");
// Sanity check that one static to dynamic conversion works
static_assert(std::is_constructible_v<std::extents<int, D, 7>, std::extents<int, 5, 7>>, "");
static_assert(std::is_convertible_v<std::extents<int, 5, 7>, std::extents<int, D, 7>>, "");
// Check that dynamic to static conversion only works explicitly only
static_assert(std::is_constructible_v<std::extents<int, 5, 7>, std::extents<int, D, 7>>, "");
static_assert(!std::is_convertible_v<std::extents<int, D, 7>, std::extents<int, 5, 7>>, "");
// Sanity check that smaller index_type to larger index_type conversion works
static_assert(std::is_constructible_v<std::extents<size_t, 5>, std::extents<int, 5>>, "");
static_assert(std::is_convertible_v<std::extents<int, 5>, std::extents<size_t, 5>>, "");
// Check that larger index_type to smaller index_type conversion works explicitly only
static_assert(std::is_constructible_v<std::extents<int, 5>, std::extents<size_t, 5>>, "");
static_assert(!std::is_convertible_v<std::extents<size_t, 5>, std::extents<int, 5>>, "");
}
constexpr void test_rank_mismatch() {
constexpr size_t D = std::dynamic_extent;
static_assert(!std::is_constructible_v<std::extents<int, D>, std::extents<int>>, "");
static_assert(!std::is_constructible_v<std::extents<int>, std::extents<int, D, D>>, "");
static_assert(!std::is_constructible_v<std::extents<int, D>, std::extents<int, D, D>>, "");
static_assert(!std::is_constructible_v<std::extents<int, D, D, D>, std::extents<int, D, D>>, "");
}
constexpr void test_static_extent_mismatch() {
constexpr size_t D = std::dynamic_extent;
static_assert(!std::is_constructible_v<std::extents<int, D, 5>, std::extents<int, D, 4>>, "");
static_assert(!std::is_constructible_v<std::extents<int, 5>, std::extents<int, 4>>, "");
static_assert(!std::is_constructible_v<std::extents<int, 5, D>, std::extents<int, 4, D>>, "");
}
constexpr bool test() {
test_conversion<int, int>();
test_conversion<int, size_t>();
test_conversion<size_t, int>();
test_conversion<size_t, long>();
test_no_implicit_conversion();
test_rank_mismatch();
test_static_extent_mismatch();
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}

View File

@ -0,0 +1,46 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// template <class... Integrals>
// explicit extents(Integrals...) -> see below;
// Constraints: (is_convertible_v<Integrals, size_t> && ...) is true.
//
// Remarks: The deduced type is dextents<size_t, sizeof...(Integrals)>.
#include <mdspan>
#include <cassert>
#include "ConvertibleToIntegral.h"
#include "test_macros.h"
template <class E, class Expected>
constexpr void test(E e, Expected expected) {
ASSERT_SAME_TYPE(E, Expected);
assert(e == expected);
}
constexpr bool test() {
constexpr std::size_t D = std::dynamic_extent;
test(std::extents(), std::extents<size_t>());
test(std::extents(1), std::extents<std::size_t, D>(1));
test(std::extents(1, 2u), std::extents<std::size_t, D, D>(1, 2u));
test(std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9),
std::extents<std::size_t, D, D, D, D, D, D, D, D, D>(1, 2u, 3, 4, 5, 6, 7, 8, 9));
return true;
}
int main(int, char**) {
test();
static_assert(test());
return 0;
}

View File

@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// Test default construction:
//
// constexpr extents() noexcept = default;
//
// Remarks: since the standard uses an exposition only array member, dynamic extents
// need to be zero intialized!
#include <mdspan>
#include <cassert>
#include <array>
#include "ConvertibleToIntegral.h"
#include "CtorTestCombinations.h"
#include "test_macros.h"
struct DefaultCtorTest {
template <class E, class AllExtents, class Extents, size_t... Indices>
static constexpr void test_construction(AllExtents all_ext, Extents, std::index_sequence<Indices...>) {
// This function gets called twice: once with Extents being just the dynamic ones, and once with all the extents specified.
// We only test during the all extent case, since then Indices is the correct number. This allows us to reuse the same
// testing machinery used in other constructor tests.
if constexpr (sizeof...(Indices) == E::rank()) {
ASSERT_NOEXCEPT(E{});
// Need to construct new expected values, replacing dynamic values with 0
std::array<typename AllExtents::value_type, E::rank()> expected_exts{
((E::static_extent(Indices) == std::dynamic_extent)
? typename AllExtents::value_type(0)
: all_ext[Indices])...};
test_runtime_observers(E{}, expected_exts);
}
}
};
int main(int, char**) {
test_index_type_combo<DefaultCtorTest>();
static_assert(test_index_type_combo<DefaultCtorTest>());
return 0;
}

View File

@ -0,0 +1,86 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// Test construction from array:
//
// template<class OtherIndexType, size_t N>
// constexpr explicit(N != rank_dynamic()) extents(const array<OtherIndexType, N>& exts) noexcept;
//
// Constraints:
// * is_convertible_v<const OtherIndexType&, index_type> is true,
// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - N is zero, or
// - exts[r] is nonnegative and is representable as a value of type index_type
// for every rank index r.
//
#include <mdspan>
#include <cassert>
#include <array>
#include <type_traits>
#include "ConvertibleToIntegral.h"
#include "CtorTestCombinations.h"
#include "test_macros.h"
struct ArrayCtorTest {
template <class E, class T, size_t N, class Extents, size_t... Indices>
static constexpr void test_construction(std::array<T, N> all_ext, Extents ext, std::index_sequence<Indices...>) {
ASSERT_NOEXCEPT(E(ext));
if constexpr (N == E::rank_dynamic()) {
test_implicit_construction_call<E>(ext, all_ext);
}
test_runtime_observers(E(ext), all_ext);
}
};
template <class E>
struct implicit_construction {
bool value;
implicit_construction(E) : value(true) {}
template <class T>
implicit_construction(T) : value(false) {}
};
int main(int, char**) {
test_index_type_combo<ArrayCtorTest>();
static_assert(test_index_type_combo<ArrayCtorTest>());
constexpr size_t D = std::dynamic_extent;
using E = std::extents<int, 1, D, 3, D>;
// check can't construct from too few arguments
static_assert(!std::is_constructible_v<E, std::array<int, 1>>, "extents constructible from illegal arguments");
// check can't construct from rank_dynamic < #args < rank
static_assert(!std::is_constructible_v<E, std::array<int, 3>>, "extents constructible from illegal arguments");
// check can't construct from too many arguments
static_assert(!std::is_constructible_v<E, std::array<int, 5>>, "extents constructible from illegal arguments");
// test implicit construction fails from span and array if all extents are given
std::array a5{3, 4, 5, 6, 7};
// check that explicit construction works, i.e. no error
static_assert(std::is_constructible_v< std::extents<int, D, D, 5, D, D>, decltype(a5)>,
"extents unexpectectly not constructible");
// check that implicit construction doesn't work
assert((implicit_construction<std::extents<int, D, D, 5, D, D>>(a5).value == false));
// test construction fails from types not convertible to index_type but convertible to other integer types
static_assert(std::is_convertible_v<IntType, int>, "Test helper IntType unexpectedly not convertible to int");
static_assert(!std::is_constructible_v< std::extents<unsigned long, D>, std::array<IntType, 1>>,
"extents constructible from illegal arguments");
return 0;
}

View File

@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// Test construction from integral:
//
// template<class ... OtherIndexTypes>
// constexpr explicit extents(OtherIndexTypes ... exts) noexcept;
//
// Let N be sizeof...(OtherIndexTypes), and let
// exts_arr be array<index_type, N>{static_cast<index_type>(std::move(exts))...}.
//
// Constraints:
// * (is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
// * (is_nothrow_constructible_v<index_type, OtherIndexType> && ...) is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts_arr[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - sizeof...(exts) == 0 is true, or
// - each element of exts is nonnegative and is representable as a value of type index_type.
//
#include <mdspan>
#include <cassert>
#include <type_traits>
#include "ConvertibleToIntegral.h"
#include "CtorTestCombinations.h"
#include "test_macros.h"
struct IntegralCtorTest {
template <class E, class AllExtents, class Extents, size_t... Indices>
static constexpr void test_construction(AllExtents all_ext, Extents ext, std::index_sequence<Indices...>) {
// construction from indices
ASSERT_NOEXCEPT(E(ext[Indices]...));
test_runtime_observers(E(ext[Indices]...), all_ext);
}
};
int main(int, char**) {
test_index_type_combo<IntegralCtorTest>();
static_assert(test_index_type_combo<IntegralCtorTest>());
constexpr size_t D = std::dynamic_extent;
using E = std::extents<int, 1, D, 3, D>;
// check can't construct from too few arguments
static_assert(!std::is_constructible_v<E, int>, "extents constructible from illegal arguments");
// check can't construct from rank_dynamic < #args < rank
static_assert(!std::is_constructible_v<E, int, int, int>, "extents constructible from illegal arguments");
// check can't construct from too many arguments
static_assert(!std::is_constructible_v<E, int, int, int, int, int>, "extents constructible from illegal arguments");
// test construction fails from types not convertible to index_type but convertible to other integer types
static_assert(std::is_convertible_v<IntType, int>, "Test helper IntType unexpectedly not convertible to int");
static_assert(!std::is_constructible_v< std::extents<unsigned long, D>, IntType>,
"extents constructible from illegal arguments");
return 0;
}

View File

@ -0,0 +1,88 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// Test construction from span:
//
// template<class OtherIndexType, size_t N>
// constexpr explicit(N != rank_dynamic()) extents(span<OtherIndexType, N> exts) noexcept;
//
// Constraints:
// * is_convertible_v<const OtherIndexType&, index_type> is true,
// * is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
// * N == rank_dynamic() || N == rank() is true.
//
// Preconditions:
// * If N != rank_dynamic() is true, exts[r] equals Er for each r for which
// Er is a static extent, and
// * either
// - N is zero, or
// - exts[r] is nonnegative and is representable as a value of type index_type
// for every rank index r.
//
#include <mdspan>
#include <cassert>
#include <array>
#include <span>
#include <type_traits>
#include "ConvertibleToIntegral.h"
#include "CtorTestCombinations.h"
#include "test_macros.h"
struct SpanCtorTest {
template <class E, class T, size_t N, class Extents, size_t... Indices>
static constexpr void test_construction(std::array<T, N> all_ext, Extents ext, std::index_sequence<Indices...>) {
ASSERT_NOEXCEPT(E(ext));
if constexpr (N == E::rank_dynamic()) {
test_implicit_construction_call<E>(std::span(ext), all_ext);
}
test_runtime_observers(E(std::span(ext)), all_ext);
}
};
template <class E>
struct implicit_construction {
bool value;
implicit_construction(E) : value(true) {}
template <class T>
implicit_construction(T) : value(false) {}
};
int main(int, char**) {
test_index_type_combo<SpanCtorTest>();
static_assert(test_index_type_combo<SpanCtorTest>());
constexpr size_t D = std::dynamic_extent;
using E = std::extents<int, 1, D, 3, D>;
// check can't construct from too few arguments
static_assert(!std::is_constructible_v<E, std::span<int, 1>>, "extents constructible from illegal arguments");
// check can't construct from rank_dynamic < #args < rank
static_assert(!std::is_constructible_v<E, std::span<int, 3>>, "extents constructible from illegal arguments");
// check can't construct from too many arguments
static_assert(!std::is_constructible_v<E, std::span<int, 5>>, "extents constructible from illegal arguments");
// test implicit construction fails from span and array if all extents are given
std::array a5{3, 4, 5, 6, 7};
std::span<int, 5> s5(a5.data(), 5);
// check that explicit construction works, i.e. no error
static_assert(std::is_constructible_v< std::extents<int, D, D, 5, D, D>, decltype(s5)>,
"extents unexpectectly not constructible");
// check that implicit construction doesn't work
assert((implicit_construction<std::extents<int, D, D, 5, D, D>>(s5).value == false));
// test construction fails from types not convertible to index_type but convertible to other integer types
static_assert(std::is_convertible_v<IntType, int>, "Test helper IntType unexpectedly not convertible to int");
static_assert(!std::is_constructible_v< std::extents<unsigned long, D>, std::span<IntType, 1>>,
"extents constructible from illegal arguments");
return 0;
}

View File

@ -0,0 +1,39 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// template<class IndexType, size_t Rank>
// using dextents = see below;
//
// Result: A type E that is a specialization of extents such that
// E::rank() == Rank && E::rank() == E::rank_dynamic() is true,
// and E::index_type denotes IndexType.
#include <mdspan>
#include <cstddef>
#include "test_macros.h"
template <class IndexType>
void test_alias_template_dextents() {
constexpr size_t D = std::dynamic_extent;
ASSERT_SAME_TYPE(std::dextents<IndexType, 0>, std::extents<IndexType>);
ASSERT_SAME_TYPE(std::dextents<IndexType, 1>, std::extents<IndexType, D>);
ASSERT_SAME_TYPE(std::dextents<IndexType, 2>, std::extents<IndexType, D, D>);
ASSERT_SAME_TYPE(std::dextents<IndexType, 3>, std::extents<IndexType, D, D, D>);
ASSERT_SAME_TYPE(std::dextents<IndexType, 9>, std::extents<IndexType, D, D, D, D, D, D, D, D, D>);
}
int main(int, char**) {
test_alias_template_dextents<int>();
test_alias_template_dextents<unsigned int>();
test_alias_template_dextents<size_t>();
return 0;
}

View File

@ -0,0 +1,88 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// static constexpr rank_type rank() noexcept;
// static constexpr rank_type rank_dynamic() noexcept;
//
// static constexpr size_t static_extent(rank_type i) noexcept;
//
// Preconditions: i < rank() is true.
//
// Returns: Ei.
//
//
// constexpr index_type extent(rank_type i) const noexcept;
//
// Preconditions: i < rank() is true.
//
// Returns: Di.
//
#include <mdspan>
#include <cassert>
#include <utility>
#include "test_macros.h"
template <class E, size_t rank, size_t rank_dynamic, size_t... StaticExts, size_t... Indices>
void test_static_observers(std::index_sequence<StaticExts...>, std::index_sequence<Indices...>) {
ASSERT_NOEXCEPT(E::rank());
static_assert(E::rank() == rank);
ASSERT_NOEXCEPT(E::rank_dynamic());
static_assert(E::rank_dynamic() == rank_dynamic);
// Let's only test this if the call isn't a precondition violation
if constexpr (rank > 0) {
ASSERT_NOEXCEPT(E::static_extent(0));
ASSERT_SAME_TYPE(decltype(E::static_extent(0)), size_t);
static_assert(((E::static_extent(Indices) == StaticExts) && ...));
}
}
template <class E, size_t rank, size_t rank_dynamic, size_t... StaticExts>
void test_static_observers() {
test_static_observers<E, rank, rank_dynamic>(
std::index_sequence<StaticExts...>(), std::make_index_sequence<sizeof...(StaticExts)>());
}
template <class T>
void test() {
constexpr size_t D = std::dynamic_extent;
constexpr size_t S = 5;
test_static_observers<std::extents<T>, 0, 0>();
test_static_observers<std::extents<T, S>, 1, 0, S>();
test_static_observers<std::extents<T, D>, 1, 1, D>();
test_static_observers<std::extents<T, S, S>, 2, 0, S, S>();
test_static_observers<std::extents<T, S, D>, 2, 1, S, D>();
test_static_observers<std::extents<T, D, S>, 2, 1, D, S>();
test_static_observers<std::extents<T, D, D>, 2, 2, D, D>();
test_static_observers<std::extents<T, S, S, S>, 3, 0, S, S, S>();
test_static_observers<std::extents<T, S, S, D>, 3, 1, S, S, D>();
test_static_observers<std::extents<T, S, D, S>, 3, 1, S, D, S>();
test_static_observers<std::extents<T, D, S, S>, 3, 1, D, S, S>();
test_static_observers<std::extents<T, S, D, D>, 3, 2, S, D, D>();
test_static_observers<std::extents<T, D, S, D>, 3, 2, D, S, D>();
test_static_observers<std::extents<T, D, D, S>, 3, 2, D, D, S>();
test_static_observers<std::extents<T, D, D, D>, 3, 3, D, D, D>();
}
int main(int, char**) {
test<int>();
test<unsigned>();
test<char>();
test<long long>();
test<size_t>();
return 0;
}

View File

@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// 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
// <mdspan>
// template<class IndexType, size_t... Extents>
// class extents {
// public:
// // types
// using index_type = IndexType;
// using size_type = make_unsigned_t<index_type>;
// using rank_type = size_t;
//
// static constexpr rank_type rank() noexcept { return sizeof...(Extents); }
// static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }
// ...
// }
#include <mdspan>
#include <type_traits>
#include <concepts>
#include <cassert>
#include "test_macros.h"
template <class E, class IndexType, size_t... Extents>
void testExtents() {
ASSERT_SAME_TYPE(typename E::index_type, IndexType);
ASSERT_SAME_TYPE(typename E::size_type, std::make_unsigned_t<IndexType>);
ASSERT_SAME_TYPE(typename E::rank_type, size_t);
static_assert(sizeof...(Extents) == E::rank());
static_assert((static_cast<size_t>(Extents == std::dynamic_extent) + ...) == E::rank_dynamic());
static_assert(std::regular<E>);
static_assert(std::is_trivially_copyable_v<E>);
// Did never find a way to make this true on windows
#ifndef _WIN32
LIBCPP_STATIC_ASSERT(std::is_empty_v<E> == (E::rank_dynamic() == 0));
#endif
}
template <class IndexType, size_t... Extents>
void testExtents() {
testExtents<std::extents<IndexType, Extents...>, IndexType, Extents...>();
}
template <class T>
void test() {
constexpr size_t D = std::dynamic_extent;
testExtents<T, D>();
testExtents<T, 3>();
testExtents<T, 3, 3>();
testExtents<T, 3, D>();
testExtents<T, D, 3>();
testExtents<T, D, D>();
testExtents<T, 3, 3, 3>();
testExtents<T, 3, 3, D>();
testExtents<T, 3, D, D>();
testExtents<T, D, 3, D>();
testExtents<T, D, D, D>();
testExtents<T, 3, D, 3>();
testExtents<T, D, 3, 3>();
testExtents<T, D, D, 3>();
testExtents<T, 9, 8, 7, 6, 5, 4, 3, 2, 1>();
testExtents<T, 9, D, 7, 6, D, D, 3, D, D>();
testExtents<T, D, D, D, D, D, D, D, D, D>();
}
int main(int, char**) {
test<int>();
test<unsigned>();
test<char>();
test<long long>();
test<size_t>();
return 0;
}

View File

@ -0,0 +1,65 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// WARNING: This test was generated by generate_feature_test_macro_components.py
// and should not be edited manually.
//
// clang-format off
// <mdspan>
// Test the feature test macros defined by <mdspan>
/* Constant Value
__cpp_lib_mdspan 202207L [C++2b]
*/
#include <mdspan>
#include "test_macros.h"
#if TEST_STD_VER < 14
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
#elif TEST_STD_VER == 14
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
#elif TEST_STD_VER == 17
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
#elif TEST_STD_VER == 20
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
#elif TEST_STD_VER > 20
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should be defined in c++2b"
# endif
# if __cpp_lib_mdspan != 202207L
# error "__cpp_lib_mdspan should have the value 202207L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined because it is unimplemented in libc++!"
# endif
# endif
#endif // TEST_STD_VER > 20

View File

@ -117,6 +117,7 @@
__cpp_lib_map_try_emplace 201411L [C++17]
__cpp_lib_math_constants 201907L [C++20]
__cpp_lib_math_special_functions 201603L [C++17]
__cpp_lib_mdspan 202207L [C++2b]
__cpp_lib_memory_resource 201603L [C++17]
__cpp_lib_move_iterator_concept 202207L [C++20]
__cpp_lib_move_only_function 202110L [C++2b]
@ -585,6 +586,10 @@
# error "__cpp_lib_math_special_functions should not be defined before c++17"
# endif
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
# ifdef __cpp_lib_memory_resource
# error "__cpp_lib_memory_resource should not be defined before c++17"
# endif
@ -1269,6 +1274,10 @@
# error "__cpp_lib_math_special_functions should not be defined before c++17"
# endif
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
# ifdef __cpp_lib_memory_resource
# error "__cpp_lib_memory_resource should not be defined before c++17"
# endif
@ -2100,6 +2109,10 @@
# endif
# endif
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
# ifndef __cpp_lib_memory_resource
# error "__cpp_lib_memory_resource should be defined in c++17"
# endif
@ -3216,6 +3229,10 @@
# endif
# endif
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined before c++2b"
# endif
# ifndef __cpp_lib_memory_resource
# error "__cpp_lib_memory_resource should be defined in c++20"
# endif
@ -4488,6 +4505,19 @@
# endif
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should be defined in c++2b"
# endif
# if __cpp_lib_mdspan != 202207L
# error "__cpp_lib_mdspan should have the value 202207L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_mdspan
# error "__cpp_lib_mdspan should not be defined because it is unimplemented in libc++!"
# endif
# endif
# ifndef __cpp_lib_memory_resource
# error "__cpp_lib_memory_resource should be defined in c++2b"
# endif

View File

@ -494,6 +494,11 @@ feature_test_macros = [ add_version_header(x) for x in [
"values": { "c++17": 201603 },
"headers": ["cmath"],
"unimplemented": True,
}, {
"name": "__cpp_lib_mdspan",
"values": { "c++2b": 202207 },
"headers": ["mdspan"],
"unimplemented": True,
}, {
"name": "__cpp_lib_memory_resource",
"values": { "c++17": 201603 },