Index: libcxx/CREDITS.TXT =================================================================== --- libcxx/CREDITS.TXT +++ libcxx/CREDITS.TXT @@ -184,3 +184,12 @@ N: Zhihao Yuan E: lichray@gmail.com D: Standard compatibility fixes. + +N: Damien Lebrun-Grandie +E: dalg24@gmail.com +E: lebrungrandt@ornl.gov +D: Implementation of mdspan. + +N: Christian Trott +E: crtrott@sandia.gov +D: Implementation of mdspan. Index: libcxx/docs/FeatureTestMacroTable.rst =================================================================== --- libcxx/docs/FeatureTestMacroTable.rst +++ libcxx/docs/FeatureTestMacroTable.rst @@ -332,6 +332,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_is_scoped_enum`` ``202011L`` ------------------------------------------------- ----------------- + ``__cpp_lib_mdspan`` *unimplemented* + ------------------------------------------------- ----------------- ``__cpp_lib_move_only_function`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_optional`` ``202110L`` Index: libcxx/include/CMakeLists.txt =================================================================== --- libcxx/include/CMakeLists.txt +++ libcxx/include/CMakeLists.txt @@ -447,6 +447,7 @@ __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 @@ -864,6 +865,7 @@ locale.h map math.h + mdspan memory memory_resource mutex Index: libcxx/include/__mdspan/extents.h =================================================================== --- /dev/null +++ libcxx/include/__mdspan/extents.h @@ -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 <__fwd/array.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 +#include +#include +#include + +#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 +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 + _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 +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 +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 +_LIBCPP_HIDE_FROM_ABI constexpr __possibly_empty_array __static_partial_sums_impl() { + __possibly_empty_array __values = {_Values...}; + __possibly_empty_array __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; +} + +template +struct __static_partial_sums { + static constexpr __possibly_empty_array __result{ + __static_partial_sums_impl<_Values...>()}; + + _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 +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 + [[no_unique_address]] _DynamicValues __dyn_vals_; + + // static mapping of indices to the position in the dynamic values array + using _DynamicIdxMap = __static_partial_sums(_Values == _DynTag)...>; + + // helper function to get a zero intialized _DynamicValues in default constructor + _LIBCPP_HIDE_FROM_ABI static constexpr _TDynamic __zero(size_t) noexcept { return 0; } + template + _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(std::index_sequence) noexcept { + return _DynamicValues{__zero(Indices)...}; + } + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept + : __dyn_vals_{__zeros(std::make_index_sequence<__size_dynamic_>())} {} + + // constructors from dynamic values only -- this covers the case for rank() == 0 + template + requires(sizeof...(_DynVals) == __size_dynamic_) + _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) + : __dyn_vals_{static_cast<_TDynamic>(__vals)...} {} + + template + 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 + 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 + 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 + 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>(std::numeric_limits<_To>::max()) >= + static_cast<_From_u>(std::numeric_limits<_From_u>::max())) { + return true; + } else { + return static_cast<_To_u>(std::numeric_limits<_To>::max()) >= static_cast<_From_u>(__value); + } +} + +template + 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 +_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(_From... __values) { + return (::std::__mdspan_detail::__is_representable_as<_To>(__values) && ... && true); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(span<_From, _Size> __values) { + for (size_t __i = 0; __i < _Size; __i++) + if (!::std::__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 extents { +public: + // typedefs for integral types used + using index_type = _IndexType; + using size_type = make_unsigned_t; + using rank_type = size_t; + + static_assert(is_integral::value && !is_same::value, + "extents::index_type must be a signed or unsigned integer type"); + static_assert(((__mdspan_detail::__is_representable_as(_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 + requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && + (is_nothrow_constructible_v && ...) && + (sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_)) + _LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept + : __vals_(static_cast(__dynvals)...) { + _LIBCPP_ASSERT(__mdspan_detail::__are_representable_as(__dynvals...), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + + template + requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v && + (_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(span(__exts)), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + + template + requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v && + (_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(__exts), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + +private: + // Function to construct extents storage from other extents. + template + requires(_Idx < __rank_) + _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents( + integral_constant, + integral_constant, + const _OtherExtents& __exts, + _DynamicValues... __dynamic_values) noexcept { + if constexpr (static_extent(_Idx) == dynamic_extent) + return __construct_vals_from_extents( + integral_constant(), + integral_constant(), + __exts, + __dynamic_values..., + __exts.extent(_Idx)); + else + return __construct_vals_from_extents( + integral_constant(), integral_constant(), __exts, __dynamic_values...); + } + + template + requires((_Idx == __rank_) && (_DynCount == __rank_dynamic_)) + _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents( + integral_constant, + integral_constant, + const _OtherExtents&, + _DynamicValues... __dynamic_values) noexcept { + return _Values{static_cast(__dynamic_values)...}; + } + +public: + // Converting constructor from other extents specializations + template + requires((sizeof...(_OtherExtents) == sizeof...(_Extents)) && + ((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...)) + explicit((((_Extents != dynamic_extent) && (_OtherExtents == dynamic_extent)) || ...) || + (static_cast>(numeric_limits::max()) < + static_cast>(numeric_limits<_OtherIndexType>::max()))) + _LIBCPP_HIDE_FROM_ABI constexpr extents(const extents<_OtherIndexType, _OtherExtents...>& __other) noexcept + : __vals_( + __construct_vals_from_extents(integral_constant(), integral_constant(), __other)) { + if constexpr (rank() > 0) { + for (size_t __r = 0; __r < rank(); __r++) { + if constexpr (static_cast>(numeric_limits::max()) < + static_cast>(numeric_limits<_OtherIndexType>::max())) { + _LIBCPP_ASSERT(__mdspan_detail::__is_representable_as(__other.extent(__r)), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + _LIBCPP_ASSERT( + (_Values::__static_value(__r) == dynamic_extent) || + (static_cast(__other.extent(__r)) == static_cast(_Values::__static_value(__r))), + "extents construction: mismatch of provided arguments with static extents."); + } + } + } + + // Comparison operator + template + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const extents& __lhs, const extents<_OtherIndexType, _OtherExtents...>& __rhs) noexcept { + bool __value = true; + if constexpr (rank() != sizeof...(_OtherExtents)) { + __value = false; + } else { + for (rank_type __r = 0; __r < __rank_; __r++) + __value &= static_cast(__rhs.extent(__r)) == __lhs.extent(__r); + } + return __value; + } +}; + +// Recursive helper classes to implement dextents alias for extents +namespace __mdspan_detail { + +template > +struct __make_dextents; + +template +struct __make_dextents< _IndexType, _Rank, extents<_IndexType, _ExtentsPack...>> { + using type = + typename __make_dextents< _IndexType, _Rank - 1, extents<_IndexType, dynamic_extent, _ExtentsPack...>>::type; +}; + +template +struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> { + using type = extents<_IndexType, _ExtentsPack...>; +}; + +} // end namespace __mdspan_detail + +// [mdspan.extents.dextents], alias template +template +using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type; + +// Deduction guide for extents +template +extents(_IndexTypes...) -> extents; + +// Helper type traits for identifying a class as extents. +namespace __mdspan_detail { + +template +struct __is_extents : false_type {}; + +template +struct __is_extents> : true_type {}; + +template +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 Index: libcxx/include/libcxx.imp =================================================================== --- libcxx/include/libcxx.imp +++ libcxx/include/libcxx.imp @@ -33,6 +33,7 @@ { include: [ "@<__ios/.*>", "private", "", "public" ] }, { include: [ "@<__iterator/.*>", "private", "", "public" ] }, { include: [ "@<__locale_dir/.*>", "private", "", "public" ] }, + { include: [ "@<__mdspan/.*>", "private", "", "public" ] }, { include: [ "@<__memory/.*>", "private", "", "public" ] }, { include: [ "@<__memory_resource/.*>", "private", "", "public" ] }, { include: [ "@<__mutex/.*>", "private", "", "public" ] }, Index: libcxx/include/mdspan =================================================================== --- /dev/null +++ libcxx/include/mdspan @@ -0,0 +1,78 @@ +// -*-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 extents { + public: + using index_type = _IndexType; + using size_type = make_unsigned_t; + 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 + constexpr explicit(see below) + extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept; + template + constexpr explicit extents(_OtherIndexTypes...) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(span<_OtherIndexType, N>) noexcept; + template + constexpr explicit(N != rank_dynamic()) + extents(const array<_OtherIndexType, N>&) noexcept; + + // [mdspan.extents.cmp], comparison operators + template + friend constexpr bool operator==(const extents&, + const extents<_OtherIndexType, _OtherExtents...>&) noexcept; + + // [mdspan.extents.expo], exposition-only helpers + constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition only + constexpr size_t __rev-prod-of-extents(rank_type) const noexcept; // exposition only + template + static constexpr auto index-cast(_OtherIndexType&&) noexcept; // exposition only + + private: + static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition only + static constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only + array dynamic-extents{}; // exposition only + }; + + template + explicit extents(Integrals...) + -> see below; +} +*/ + +#ifndef _LIBCPP_MDSPAN +#define _LIBCPP_MDSPAN + +#include <__config> +#include <__mdspan/extents.h> + +#include // for size_t +#include // for dynamic_extent + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#endif // _LIBCPP_MDSPAN Index: libcxx/include/module.modulemap.in =================================================================== --- libcxx/include/module.modulemap.in +++ libcxx/include/module.modulemap.in @@ -1128,6 +1128,15 @@ export initializer_list export * } + module mdspan { + header "mdspan" + export span + export * + + module __mdspan { + module extents { private header "__mdspan/extents.h" } + } + } module memory { header "memory" export * Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -123,6 +123,7 @@ __cpp_lib_map_try_emplace 201411L __cpp_lib_math_constants 201907L __cpp_lib_math_special_functions 201603L +__cpp_lib_mdspan 202207L __cpp_lib_memory_resource 201603L __cpp_lib_move_iterator_concept 202207L __cpp_lib_move_only_function 202110L @@ -408,6 +409,7 @@ # 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 Index: libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp =================================================================== --- libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp +++ libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp @@ -423,342 +423,348 @@ // RUN: %{build} -DTEST_71 #if defined(TEST_71) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_72 #if defined(TEST_72) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_73 -#if defined(TEST_73) && !defined(_LIBCPP_HAS_NO_THREADS) -# include +#if defined(TEST_73) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_74 -#if defined(TEST_74) -# include +#if defined(TEST_74) && !defined(_LIBCPP_HAS_NO_THREADS) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_75 #if defined(TEST_75) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_76 #if defined(TEST_76) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_77 #if defined(TEST_77) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_78 -#if defined(TEST_78) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include +#if defined(TEST_78) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_79 -#if defined(TEST_79) -# include +#if defined(TEST_79) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_80 #if defined(TEST_80) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_81 #if defined(TEST_81) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_82 #if defined(TEST_82) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_83 -#if defined(TEST_83) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include +#if defined(TEST_83) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_84 -#if defined(TEST_84) -# include +#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_85 -#if defined(TEST_85) && !defined(_LIBCPP_HAS_NO_THREADS) -# include +#if defined(TEST_85) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_86 -#if defined(TEST_86) -# include +#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif -// RUN: %{build} -DTEST_88 -#if defined(TEST_88) && !defined(_LIBCPP_HAS_NO_THREADS) -# include +// RUN: %{build} -DTEST_87 +#if defined(TEST_87) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_89 -#if defined(TEST_89) -# include +#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_THREADS) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_90 #if defined(TEST_90) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_91 -#if defined(TEST_91) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include +#if defined(TEST_91) +# include 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 + using HandlerType = decltype(std::__libcpp_verbose_abort); +#endif + +// RUN: %{build} -DTEST_93 +#if defined(TEST_93) # include 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 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 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 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 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 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 using HandlerType = decltype(std::__libcpp_verbose_abort); #endif -// RUN: %{build} -DTEST_107 -#if defined(TEST_107) && !defined(_LIBCPP_HAS_NO_THREADS) -# include - using HandlerType = decltype(std::__libcpp_verbose_abort); -#endif - // RUN: %{build} -DTEST_108 -#if defined(TEST_108) -# include +#if defined(TEST_108) && !defined(_LIBCPP_HAS_NO_THREADS) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_109 #if defined(TEST_109) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_110 #if defined(TEST_110) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_111 #if defined(TEST_111) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif -// RUN: %{build} -DTEST_113 -#if defined(TEST_113) -# include +// RUN: %{build} -DTEST_112 +#if defined(TEST_112) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_114 #if defined(TEST_114) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_115 #if defined(TEST_115) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_116 #if defined(TEST_116) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_117 #if defined(TEST_117) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_118 #if defined(TEST_118) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_119 #if defined(TEST_119) -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif -// RUN: %{build} -DTEST_122 -#if defined(TEST_122) && __cplusplus >= 201103L -# include +// RUN: %{build} -DTEST_120 +#if defined(TEST_120) +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_123 #if defined(TEST_123) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_124 #if defined(TEST_124) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_125 #if defined(TEST_125) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_126 #if defined(TEST_126) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_127 #if defined(TEST_127) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_128 #if defined(TEST_128) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_129 -#if defined(TEST_129) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L -# include +#if defined(TEST_129) && __cplusplus >= 201103L +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_130 -#if defined(TEST_130) && __cplusplus >= 201103L -# include +#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_131 #if defined(TEST_131) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_132 #if defined(TEST_132) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_133 #if defined(TEST_133) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_134 #if defined(TEST_134) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_135 #if defined(TEST_135) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_136 #if defined(TEST_136) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_137 #if defined(TEST_137) && __cplusplus >= 201103L -# include +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_138 -#if defined(TEST_138) -# include +#if defined(TEST_138) && __cplusplus >= 201103L +# include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif // RUN: %{build} -DTEST_139 #if defined(TEST_139) +# include + using HandlerType = decltype(std::__libcpp_verbose_abort); +#endif + +// RUN: %{build} -DTEST_140 +#if defined(TEST_140) # include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif Index: libcxx/test/libcxx/clang_tidy.sh.cpp =================================================================== --- libcxx/test/libcxx/clang_tidy.sh.cpp +++ libcxx/test/libcxx/clang_tidy.sh.cpp @@ -142,6 +142,7 @@ #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) Index: libcxx/test/libcxx/double_include.sh.cpp =================================================================== --- libcxx/test/libcxx/double_include.sh.cpp +++ libcxx/test/libcxx/double_include.sh.cpp @@ -137,6 +137,7 @@ #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) Index: libcxx/test/libcxx/min_max_macros.compile.pass.cpp =================================================================== --- libcxx/test/libcxx/min_max_macros.compile.pass.cpp +++ libcxx/test/libcxx/min_max_macros.compile.pass.cpp @@ -208,6 +208,8 @@ TEST_MACROS(); #include TEST_MACROS(); +#include +TEST_MACROS(); #include TEST_MACROS(); #include Index: libcxx/test/libcxx/modules_include.sh.cpp =================================================================== --- libcxx/test/libcxx/modules_include.sh.cpp +++ libcxx/test/libcxx/modules_include.sh.cpp @@ -470,417 +470,422 @@ // RUN: echo 'TEST_71=$!' >> %t.sh // RUN: echo "wait $TEST_55" >> %t.sh #if defined(TEST_71) -#include +#include #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 +#include #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 +#if defined(TEST_73) +#include #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 +#if defined(TEST_74) && !defined(_LIBCPP_HAS_NO_THREADS) +#include #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 +#include #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 +#include #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 +#include #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 +#if defined(TEST_78) +#include #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 +#if defined(TEST_79) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#include #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 +#include #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 +#include #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 +#include #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 +#if defined(TEST_83) +#include #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 +#if defined(TEST_84) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#include #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 +#if defined(TEST_85) +#include #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 +#if defined(TEST_86) && !defined(_LIBCPP_HAS_NO_THREADS) +#include #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 +#include #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 +#if defined(TEST_88) +#include #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 +#if defined(TEST_89) && !defined(_LIBCPP_HAS_NO_THREADS) +#include #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 +#include #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 +#if defined(TEST_91) +#include #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 +#if defined(TEST_92) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#include #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 +#if defined(TEST_93) +#include #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 +#if defined(TEST_94) && __cplusplus > 202002L && !defined(_LIBCPP_HAS_NO_THREADS) +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#if defined(TEST_100) +#include #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 +#if defined(TEST_101) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#include #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 +#include #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 +#include #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 +#if defined(TEST_104) +#include #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 +#if defined(TEST_105) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +#include #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 +#include #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 +#if defined(TEST_107) +#include #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 +#if defined(TEST_108) && !defined(_LIBCPP_HAS_NO_THREADS) +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#if defined(TEST_120) +#include #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 +#include #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 +#if defined(TEST_122) && !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#if defined(TEST_129) && __cplusplus >= 201103L +#include #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 +#if defined(TEST_130) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) && __cplusplus >= 201103L +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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 +#include #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) -#include +#if defined(TEST_138) && __cplusplus >= 201103L +#include #endif // RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_139 &' >> %t.sh // RUN: echo 'TEST_139=$!' >> %t.sh // RUN: echo "wait $TEST_123" >> %t.sh #if defined(TEST_139) -#include +#include #endif +// RUN: echo '%{cxx} %s %{flags} %{compile_flags} -fmodules -fcxx-modules -fmodules-cache-path=%t -fsyntax-only -DTEST_140 &' >> %t.sh +// RUN: echo 'TEST_140=$!' >> %t.sh // RUN: echo "wait $TEST_124" >> %t.sh +#if defined(TEST_140) +#include +#endif // RUN: echo "wait $TEST_125" >> %t.sh // RUN: echo "wait $TEST_126" >> %t.sh // RUN: echo "wait $TEST_127" >> %t.sh @@ -896,5 +901,6 @@ // RUN: echo "wait $TEST_137" >> %t.sh // RUN: echo "wait $TEST_138" >> %t.sh // RUN: echo "wait $TEST_139" >> %t.sh +// RUN: echo "wait $TEST_140" >> %t.sh // RUN: bash %t.sh // GENERATED-MARKER Index: libcxx/test/libcxx/nasty_macros.compile.pass.cpp =================================================================== --- libcxx/test/libcxx/nasty_macros.compile.pass.cpp +++ libcxx/test/libcxx/nasty_macros.compile.pass.cpp @@ -261,6 +261,7 @@ #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) Index: libcxx/test/libcxx/no_assert_include.compile.pass.cpp =================================================================== --- libcxx/test/libcxx/no_assert_include.compile.pass.cpp +++ libcxx/test/libcxx/no_assert_include.compile.pass.cpp @@ -134,6 +134,7 @@ #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) Index: libcxx/test/libcxx/private_headers.verify.cpp =================================================================== --- libcxx/test/libcxx/private_headers.verify.cpp +++ libcxx/test/libcxx/private_headers.verify.cpp @@ -485,6 +485,7 @@ #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'}} Index: libcxx/test/libcxx/transitive_includes.sh.cpp =================================================================== --- libcxx/test/libcxx/transitive_includes.sh.cpp +++ libcxx/test/libcxx/transitive_includes.sh.cpp @@ -322,232 +322,236 @@ #if defined(TEST_69) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 2> %t/header.memory +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 2> %t/header.mdspan #if defined(TEST_71) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 2> %t/header.memory_resource +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 2> %t/header.memory #if defined(TEST_72) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 2> %t/header.mutex +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 2> %t/header.memory_resource #if defined(TEST_73) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 2> %t/header.new +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 2> %t/header.mutex #if defined(TEST_74) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 2> %t/header.numbers +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 2> %t/header.new #if defined(TEST_75) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 2> %t/header.numeric +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 2> %t/header.numbers #if defined(TEST_76) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 2> %t/header.optional +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 2> %t/header.numeric #if defined(TEST_77) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 2> %t/header.ostream +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 2> %t/header.optional #if defined(TEST_78) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 2> %t/header.queue +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 2> %t/header.ostream #if defined(TEST_79) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 2> %t/header.random +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 2> %t/header.queue #if defined(TEST_80) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 2> %t/header.ranges +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 2> %t/header.random #if defined(TEST_81) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 2> %t/header.ratio +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 2> %t/header.ranges #if defined(TEST_82) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 2> %t/header.regex +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 2> %t/header.ratio #if defined(TEST_83) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 2> %t/header.scoped_allocator +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 2> %t/header.regex #if defined(TEST_84) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 2> %t/header.semaphore +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 2> %t/header.scoped_allocator #if defined(TEST_85) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 2> %t/header.set +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 2> %t/header.semaphore #if defined(TEST_86) +#include +#endif +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_87 2> %t/header.set +#if defined(TEST_87) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_88 2> %t/header.shared_mutex -#if defined(TEST_88) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 2> %t/header.shared_mutex +#if defined(TEST_89) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 2> %t/header.source_location -#if defined(TEST_89) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 2> %t/header.source_location +#if defined(TEST_90) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 2> %t/header.span -#if defined(TEST_90) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 2> %t/header.span +#if defined(TEST_91) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 2> %t/header.sstream -#if defined(TEST_91) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 2> %t/header.sstream +#if defined(TEST_92) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 2> %t/header.stack -#if defined(TEST_92) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_93 2> %t/header.stack +#if defined(TEST_93) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_96 2> %t/header.stdexcept -#if defined(TEST_96) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_97 2> %t/header.stdexcept +#if defined(TEST_97) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_100 2> %t/header.streambuf -#if defined(TEST_100) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 2> %t/header.streambuf +#if defined(TEST_101) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 2> %t/header.string -#if defined(TEST_101) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_102 2> %t/header.string +#if defined(TEST_102) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_103 2> %t/header.string_view -#if defined(TEST_103) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 2> %t/header.string_view +#if defined(TEST_104) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 2> %t/header.strstream -#if defined(TEST_104) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 2> %t/header.strstream +#if defined(TEST_105) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 2> %t/header.system_error -#if defined(TEST_105) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_106 2> %t/header.system_error +#if defined(TEST_106) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_107 2> %t/header.thread -#if defined(TEST_107) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 2> %t/header.thread +#if defined(TEST_108) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 2> %t/header.tuple -#if defined(TEST_108) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 2> %t/header.tuple +#if defined(TEST_109) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 2> %t/header.type_traits -#if defined(TEST_109) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 2> %t/header.type_traits +#if defined(TEST_110) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 2> %t/header.typeindex -#if defined(TEST_110) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 2> %t/header.typeindex +#if defined(TEST_111) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 2> %t/header.typeinfo -#if defined(TEST_111) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_112 2> %t/header.typeinfo +#if defined(TEST_112) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_113 2> %t/header.unordered_map -#if defined(TEST_113) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 2> %t/header.unordered_map +#if defined(TEST_114) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 2> %t/header.unordered_set -#if defined(TEST_114) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 2> %t/header.unordered_set +#if defined(TEST_115) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 2> %t/header.utility -#if defined(TEST_115) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 2> %t/header.utility +#if defined(TEST_116) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 2> %t/header.valarray -#if defined(TEST_116) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 2> %t/header.valarray +#if defined(TEST_117) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 2> %t/header.variant -#if defined(TEST_117) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 2> %t/header.variant +#if defined(TEST_118) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 2> %t/header.vector -#if defined(TEST_118) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 2> %t/header.vector +#if defined(TEST_119) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 2> %t/header.version -#if defined(TEST_119) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_120 2> %t/header.version +#if defined(TEST_120) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_122 2> %t/header.experimental_deque -#if defined(TEST_122) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 2> %t/header.experimental_deque +#if defined(TEST_123) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 2> %t/header.experimental_forward_list -#if defined(TEST_123) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 2> %t/header.experimental_forward_list +#if defined(TEST_124) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 2> %t/header.experimental_iterator -#if defined(TEST_124) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 2> %t/header.experimental_iterator +#if defined(TEST_125) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 2> %t/header.experimental_list -#if defined(TEST_125) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 2> %t/header.experimental_list +#if defined(TEST_126) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 2> %t/header.experimental_map -#if defined(TEST_126) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 2> %t/header.experimental_map +#if defined(TEST_127) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 2> %t/header.experimental_memory_resource -#if defined(TEST_127) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 2> %t/header.experimental_memory_resource +#if defined(TEST_128) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 2> %t/header.experimental_propagate_const -#if defined(TEST_128) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 2> %t/header.experimental_propagate_const +#if defined(TEST_129) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 2> %t/header.experimental_regex -#if defined(TEST_129) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 2> %t/header.experimental_regex +#if defined(TEST_130) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 2> %t/header.experimental_set -#if defined(TEST_130) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 2> %t/header.experimental_set +#if defined(TEST_131) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 2> %t/header.experimental_simd -#if defined(TEST_131) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 2> %t/header.experimental_simd +#if defined(TEST_132) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 2> %t/header.experimental_string -#if defined(TEST_132) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 2> %t/header.experimental_string +#if defined(TEST_133) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 2> %t/header.experimental_type_traits -#if defined(TEST_133) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 2> %t/header.experimental_type_traits +#if defined(TEST_134) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 2> %t/header.experimental_unordered_map -#if defined(TEST_134) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 2> %t/header.experimental_unordered_map +#if defined(TEST_135) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 2> %t/header.experimental_unordered_set -#if defined(TEST_135) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 2> %t/header.experimental_unordered_set +#if defined(TEST_136) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 2> %t/header.experimental_utility -#if defined(TEST_136) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 2> %t/header.experimental_utility +#if defined(TEST_137) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 2> %t/header.experimental_vector -#if defined(TEST_137) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_138 2> %t/header.experimental_vector +#if defined(TEST_138) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_138 2> %t/header.ext_hash_map -#if defined(TEST_138) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_139 2> %t/header.ext_hash_map +#if defined(TEST_139) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_139 2> %t/header.ext_hash_set -#if defined(TEST_139) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_140 2> %t/header.ext_hash_set +#if defined(TEST_140) #include #endif // RUN: %{python} %S/transitive_includes_to_csv.py %t > %t/transitive_includes.csv Index: libcxx/test/libcxx/transitive_includes/cxx03.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx03.csv +++ libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -539,6 +539,10 @@ map type_traits map utility map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts Index: libcxx/test/libcxx/transitive_includes/cxx11.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx11.csv +++ libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -539,6 +539,10 @@ map type_traits map utility map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts Index: libcxx/test/libcxx/transitive_includes/cxx14.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx14.csv +++ libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -541,6 +541,10 @@ map type_traits map utility map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts Index: libcxx/test/libcxx/transitive_includes/cxx17.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx17.csv +++ libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -541,6 +541,10 @@ map type_traits map utility map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts Index: libcxx/test/libcxx/transitive_includes/cxx20.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx20.csv +++ libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -548,6 +548,10 @@ map type_traits map utility map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts Index: libcxx/test/libcxx/transitive_includes/cxx2b.csv =================================================================== --- libcxx/test/libcxx/transitive_includes/cxx2b.csv +++ libcxx/test/libcxx/transitive_includes/cxx2b.csv @@ -369,6 +369,10 @@ map stdexcept map tuple map version +mdspan cinttypes +mdspan cstddef +mdspan limits +mdspan span memory compare memory cstddef memory cstdint Index: libcxx/test/std/containers/views/mdspan/extents/ConvertibleToIntegral.h =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ConvertibleToIntegral.h @@ -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 CONVERTIBLE_TO_INTEGRAL_H +#define 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 Index: libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +#include +#include +#include +#include + +#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 +constexpr bool 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)); + bool is_equal = ext.extent(r) == static_cast(expected[r]); + assert(is_equal); + if (!is_equal) + return false; + } + return true; +} + +template +constexpr bool test_implicit_construction_call(E e, AllExtents all_ext) { + return test_runtime_observers(e, all_ext); +} + +template +constexpr bool test_construction(AllExtents all_ext) { + // test construction from all extents + if (!Test::template test_construction(all_ext, all_ext, std::make_index_sequence())) + return false; + + // test construction from just dynamic extents + // create an array of just the extents corresponding to dynamic values + std::array 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++; + } + } + return Test::template test_construction(all_ext, dyn_ext, std::make_index_sequence()); +} + +template +constexpr bool test() { + constexpr size_t D = std::dynamic_extent; + + bool result = true; + result = result && test_construction, Test>(std::array{}); + + result = result && test_construction, Test>(std::array{3}); + result = result && test_construction, Test>(std::array{3}); + + result = result && test_construction, Test>(std::array{3, 7}); + result = result && test_construction, Test>(std::array{3, 7}); + result = result && test_construction, Test>(std::array{3, 7}); + result = result && test_construction, Test>(std::array{3, 7}); + + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + result = result && test_construction, Test>(std::array{3, 7, 9}); + + result = result && test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + result = result && test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + result = result && test_construction, Test>( + std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + return result; +} + +template +constexpr bool test_index_type_combo() { + bool result = true; + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + result = result && test(); + return result; +} Index: libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp @@ -0,0 +1,56 @@ +// +// 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 + +// + +// template +// constexpr explicit(see below) extents(const extents&) 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::max() < numeric_limits::max()) + +#include +#include + +#include "check_assertion.h" + +int main() { + constexpr size_t D = std::dynamic_extent; + std::extents arg{1000, 5}; + + // working case + { + [[maybe_unused]] std::extents e(arg); // should work + } + // mismatch of static extent + { + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents e(arg); }()), + "extents construction: mismatch of provided arguments with static extents."); + } + // value out of range + { + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents e(arg); }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } +} Index: libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp @@ -0,0 +1,68 @@ +// +// 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 array: +// +// template +// constexpr explicit(N != rank_dynamic()) extents(const array& exts) noexcept; +// +// Constraints: +// * is_convertible_v is true, +// * is_nothrow_constructible_v 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 +#include + +#include "check_assertion.h" + +int main() { + constexpr size_t D = std::dynamic_extent; + // working case + { + [[maybe_unused]] std::extents e1(std::array{1000, 5}); // should work + } + // mismatch of static extent + { + TEST_LIBCPP_ASSERT_FAILURE( + ([] { + std::extents e1(std::array{1000, 3}); + }()), + "extents construction: mismatch of provided arguments with static extents."); + } + // value out of range + { + TEST_LIBCPP_ASSERT_FAILURE( + ([] { + std::extents e1(std::array{1000, 5}); + }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + // negative value + { + TEST_LIBCPP_ASSERT_FAILURE( + ([] { + std::extents e1(std::array{-1, 5}); + }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } +} Index: libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp @@ -0,0 +1,61 @@ +// +// 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 integral: +// +// template +// constexpr explicit extents(OtherIndexTypes ... exts) noexcept; +// +// Let N be sizeof...(OtherIndexTypes), and let +// exts_arr be array{static_cast(std::move(exts))...}. +// +// Constraints: +// * (is_convertible_v && ...) is true, +// * (is_nothrow_constructible_v && ...) 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 +#include + +#include "check_assertion.h" + +int main() { + constexpr size_t D = std::dynamic_extent; + // working case + { + [[maybe_unused]] std::extents e1(1000, 5); // should work + } + // mismatch of static extent + { + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(1000, 3); }()), + "extents construction: mismatch of provided arguments with static extents."); + } + // value out of range + { + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(1000, 5); }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } + // negative value + { + TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents e1(-1, 5); }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } +} Index: libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp @@ -0,0 +1,61 @@ +// +// 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 +// constexpr explicit(N != rank_dynamic()) extents(span exts) noexcept; +// +// Constraints: +// * is_convertible_v is true, +// * is_nothrow_constructible_v 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 +#include + +#include "check_assertion.h" + +int main() { + constexpr size_t D = std::dynamic_extent; + // working case sanity check + { + std::array args{1000, 5}; + [[maybe_unused]] std::extents e1(std::span{args}); + } + // mismatch of static extent + { + std::array args{1000, 3}; + TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents 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 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 e1(std::span{args}); }()), + "extents ctor: arguments must be representable as index_type and nonnegative"); + } +} Index: libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp @@ -0,0 +1,64 @@ +// +// 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 + +// + +// 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 +#include + +#include "check_assertion.h" + +int main() { + constexpr size_t D = std::dynamic_extent; + + // mismatch of static extent + { + std::extents 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 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 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 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 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::static_extent(1) == 5); +} Index: libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// template +// friend constexpr bool operator==(const extents&, +// const extents&) noexcept; +// ` + +#include +#include +#include +#include + +#include "test_macros.h" + +// +// +// template +// friend constexpr bool operator==(const extents& lhs, +// const extents& 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. +// + +template +constexpr void test_comparison(bool equal, To dest, From src) { + ASSERT_NOEXCEPT(dest == src); + assert((dest == src) == equal); + assert((dest != src) != equal); +} + +template +constexpr void test_comparison_different_rank() { + constexpr size_t D = std::dynamic_extent; + + test_comparison(false, std::extents(), std::extents(1)); + test_comparison(false, std::extents(), std::extents()); + + test_comparison(false, std::extents(1), std::extents()); + test_comparison(false, std::extents(), std::extents()); + + test_comparison(false, std::extents(5), std::extents(5, 5)); + test_comparison(false, std::extents(), std::extents(5)); + test_comparison(false, std::extents(), std::extents()); + + test_comparison(false, std::extents(5, 5), std::extents(5)); + test_comparison(false, std::extents(5), std::extents(5)); + test_comparison(false, std::extents(), std::extents()); +} + +template +constexpr void test_comparison_same_rank() { + constexpr size_t D = std::dynamic_extent; + + test_comparison(true, std::extents(), std::extents()); + + test_comparison(true, std::extents(5), std::extents(5)); + test_comparison(true, std::extents(), std::extents(5)); + test_comparison(true, std::extents(5), std::extents()); + test_comparison(true, std::extents(), std::extents< T2, 5>()); + test_comparison(false, std::extents(5), std::extents(7)); + test_comparison(false, std::extents(), std::extents(7)); + test_comparison(false, std::extents(5), std::extents()); + test_comparison(false, std::extents(), std::extents()); + + test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 7, 8, 9)); + test_comparison(true, std::extents(5, 7, 9), std::extents(6, 7)); + test_comparison(true, std::extents(5, 6, 7, 8, 9), std::extents()); + test_comparison( + false, std::extents(5, 6, 7, 8, 9), std::extents(5, 6, 3, 8, 9)); + test_comparison(false, std::extents(5, 7, 9), std::extents(6, 7)); + test_comparison(false, std::extents(5, 6, 7, 8, 9), std::extents()); +} + +template +constexpr void test_comparison() { + test_comparison_same_rank(); + test_comparison_different_rank(); +} + +constexpr bool test() { + test_comparison(); + test_comparison(); + test_comparison(); + test_comparison(); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} Index: libcxx/test/std/containers/views/mdspan/extents/conversion.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/conversion.pass.cpp @@ -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 + +// + +// template +// constexpr explicit(see below) extents(const extents&) 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::max() < numeric_limits::max()) + +#include +#include +#include +#include +#include + +#include "test_macros.h" + +template +constexpr void test_implicit_conversion(To dest, From src) { + assert(dest == src); +} + +template +constexpr void test_conversion(From src) { + To dest(src); + assert(dest == src); + if constexpr (implicit) { + dest = src; + assert(dest == src); + test_implicit_conversion(src, src); + } +} + +template +constexpr void test_conversion() { + constexpr size_t D = std::dynamic_extent; + constexpr bool idx_convertible = + static_cast(std::numeric_limits::max()) >= static_cast(std::numeric_limits::max()); + + // clang-format off + test_conversion>(std::extents()); + test_conversion>(std::extents(5)); + test_conversion>(std::extents(5)); + test_conversion>(std::extents()); + test_conversion>(std::extents(5, 5)); + test_conversion>(std::extents(5, 5)); + test_conversion>(std::extents(5)); + test_conversion>(std::extents()); + test_conversion>(std::extents(5, 7)); + test_conversion>( + std::extents(5, 7, 8, 9, 1)); + test_conversion>(std::extents(5)); + test_conversion>(std::extents()); + // 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>, ""); + static_assert(std::is_convertible_v, std::extents>, ""); + + // Check that dynamic to static conversion only works explicitly only + static_assert(std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_convertible_v, std::extents>, ""); + + // Sanity check that one static to dynamic conversion works + static_assert(std::is_constructible_v, std::extents>, ""); + static_assert(std::is_convertible_v, std::extents>, ""); + + // Check that dynamic to static conversion only works explicitly only + static_assert(std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_convertible_v, std::extents>, ""); + + // Sanity check that smaller index_type to larger index_type conversion works + static_assert(std::is_constructible_v, std::extents>, ""); + static_assert(std::is_convertible_v, std::extents>, ""); + + // Check that larger index_type to smaller index_type conversion works explicitly only + static_assert(std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_convertible_v, std::extents>, ""); +} + +constexpr void test_rank_mismatch() { + constexpr size_t D = std::dynamic_extent; + + static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, std::extents>, ""); +} + +constexpr void test_static_extent_mismatch() { + constexpr size_t D = std::dynamic_extent; + + static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, std::extents>, ""); + static_assert(!std::is_constructible_v, std::extents>, ""); +} + +constexpr bool test() { + test_conversion(); + test_conversion(); + test_conversion(); + test_conversion(); + test_no_implicit_conversion(); + test_rank_mismatch(); + test_static_extent_mismatch(); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} Index: libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp @@ -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 + +// + +// template +// explicit extents(Integrals...) -> see below; +// Constraints: (is_convertible_v && ...) is true. +// +// Remarks: The deduced type is dextents. + +#include +#include + +#include "ConvertibleToIntegral.h" +#include "test_macros.h" + +template +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()); + test(std::extents(1), std::extents(1)); + test(std::extents(1, 2u), std::extents(1, 2u)); + test(std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9), + std::extents(1, 2u, 3, 4, 5, 6, 7, 8, 9)); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} Index: libcxx/test/std/containers/views/mdspan/extents/ctor_default.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctor_default.pass.cpp @@ -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 + +// + +// 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 +#include +#include +#include + +#include "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct IntegralCtorTest { + template + static constexpr bool test_construction(AllExtents all_ext, Extents, std::index_sequence) { + // this function gets called twice: once with Extents being just dynamic ones, and once with all + // we only test during the all extent case, since then Indices is correct number + if constexpr (sizeof...(Indices) == E::rank()) { + ASSERT_NOEXCEPT(E{}); + // Need to construct new exepcted values, replacing dynamic values with 0 + std::array expected_exts{ + ((E::static_extent(Indices) == std::dynamic_extent) + ? typename AllExtents::value_type(0) + : all_ext[Indices])...}; + return test_runtime_observers(E{}, expected_exts); + } else + return true; + } +}; + +int main() { + test_index_type_combo(); + static_assert(test_index_type_combo()); +} Index: libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Test construction from array: +// +// template +// constexpr explicit(N != rank_dynamic()) extents(const array& exts) noexcept; +// +// Constraints: +// * is_convertible_v is true, +// * is_nothrow_constructible_v 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 +#include +#include +#include + +#include "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct IntegralCtorTest { + template + static constexpr bool test_construction(std::array all_ext, Extents ext, std::index_sequence) { + ASSERT_NOEXCEPT(E(ext)); + if constexpr (N == E::rank_dynamic()) { + if (!test_implicit_construction_call(ext, all_ext)) + return false; + } + return test_runtime_observers(E(ext), all_ext); + } +}; + +int main() { + test_index_type_combo(); + static_assert(test_index_type_combo()); +} Index: libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Test construction from integral: +// +// template +// constexpr explicit extents(OtherIndexTypes ... exts) noexcept; +// +// Let N be sizeof...(OtherIndexTypes), and let +// exts_arr be array{static_cast(std::move(exts))...}. +// +// Constraints: +// * (is_convertible_v && ...) is true, +// * (is_nothrow_constructible_v && ...) 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 +#include +#include +#include + +#include "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct IntegralCtorTest { + template + static constexpr bool test_construction(AllExtents all_ext, Extents ext, std::index_sequence) { + // default construction + ASSERT_NOEXCEPT(E{}); + // construction from indices + ASSERT_NOEXCEPT(E(ext[Indices]...)); + return test_runtime_observers(E(ext[Indices]...), all_ext); + } +}; + +int main() { + test_index_type_combo(); + static_assert(test_index_type_combo()); +} Index: libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// Test construction from span: +// +// template +// constexpr explicit(N != rank_dynamic()) extents(span exts) noexcept; +// +// Constraints: +// * is_convertible_v is true, +// * is_nothrow_constructible_v 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 +#include +#include +#include + +#include "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct IntegralCtorTest { + template + static constexpr bool test_construction(std::array all_ext, Extents ext, std::index_sequence) { + ASSERT_NOEXCEPT(E(ext)); + if constexpr (N == E::rank_dynamic()) { + if (!test_implicit_construction_call(std::span(ext), all_ext)) + return false; + } + return test_runtime_observers(E(std::span(ext)), all_ext); + } +}; + +int main() { + test_index_type_combo(); + static_assert(test_index_type_combo()); +} Index: libcxx/test/std/containers/views/mdspan/extents/ctor_non_constructible.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/ctor_non_constructible.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// constexpr extents() noexcept; +// +// +// template +// constexpr explicit extents(OtherIndexTypes...) noexcept; +// +// Remarks: These constructors shall not participate in overload resolution unless: +// - (is_convertible_v && ...) is true, +// - (is_nothrow_constructible_v && ...) is true, and +// - N == rank_dynamic() || N == rank() is true. +// +// +// template +// constexpr explicit(N != rank_dynamic()) extents(span) noexcept; +// template +// constexpr explicit(N != rank_dynamic()) extents(const array&) noexcept; +// +// Remarks: These constructors shall not participate in overload resolution unless: +// - is_convertible_v is true, +// - is_nothrow_constructible_v is true, and +// - N == rank_dynamic() || N == rank() is true. +// + +#include +#include +#include +#include +#include + +#include "ConvertibleToIntegral.h" +#include "test_macros.h" + +template +struct implicit_construction { + bool value; + implicit_construction(E) : value(true) {} + template + implicit_construction(T) : value(false) {} +}; + +int main() { + constexpr size_t D = std::dynamic_extent; + using E = std::extents; + + // check can't construct from too few arguments + static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + // check can't construct from rank_dynamic < #args < rank + static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + // check can't construct from too many arguments + static_assert(!std::is_constructible_v, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v>, "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 s5(a5.data(), 5); + // check that explicit construction works, i.e. no error + static_assert(std::is_constructible_v< std::extents, decltype(a5)>, + "extents unexpectectly not constructible"); + static_assert(std::is_constructible_v< std::extents, decltype(s5)>, + "extents unexpectectly not constructible"); + // check that implicit construction doesn't work + LIBCPP_ASSERT((implicit_construction>(a5).value == false)); + LIBCPP_ASSERT((implicit_construction>(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, "Test helper IntType unexpectedly not convertible to int"); + static_assert(!std::is_constructible_v< std::extents, IntType>, + "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v< std::extents, std::array>, + "extents constructible from illegal arguments"); + static_assert(!std::is_constructible_v< std::extents, std::span>, + "extents constructible from illegal arguments"); +} Index: libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// template +// 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 +#include + +#include "test_macros.h" + +template +void test_alias_template_dextents() { + constexpr size_t D = std::dynamic_extent; + ASSERT_SAME_TYPE(std::dextents, std::extents); + ASSERT_SAME_TYPE(std::dextents, std::extents); + ASSERT_SAME_TYPE(std::dextents, std::extents); + ASSERT_SAME_TYPE(std::dextents, std::extents); + ASSERT_SAME_TYPE(std::dextents, std::extents); +} + +int main() { + test_alias_template_dextents(); + test_alias_template_dextents(); + test_alias_template_dextents(); +} Index: libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +// 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 +#include +#include + +#include "test_macros.h" + +template +void test_static_observers(std::index_sequence, std::index_sequence) { + 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 +void test_static_observers() { + test_static_observers( + std::index_sequence(), std::make_index_sequence()); +} + +template +void test() { + constexpr size_t D = std::dynamic_extent; + constexpr size_t S = 5; + + test_static_observers, 0, 0>(); + + test_static_observers, 1, 0, S>(); + test_static_observers, 1, 1, D>(); + + test_static_observers, 2, 0, S, S>(); + test_static_observers, 2, 1, S, D>(); + test_static_observers, 2, 1, D, S>(); + test_static_observers, 2, 2, D, D>(); + + test_static_observers, 3, 0, S, S, S>(); + test_static_observers, 3, 1, S, S, D>(); + test_static_observers, 3, 1, S, D, S>(); + test_static_observers, 3, 1, D, S, S>(); + test_static_observers, 3, 2, S, D, D>(); + test_static_observers, 3, 2, D, S, D>(); + test_static_observers, 3, 2, D, D, S>(); + test_static_observers, 3, 3, D, D, D>(); +} + +int main() { + test(); + test(); + test(); + test(); + test(); +} Index: libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// template +// class extents { +// public: +// // types +// using index_type = IndexType; +// using size_type = make_unsigned_t; +// 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 +#include +#include +#include + +#include "test_macros.h" + +template +void testExtents() { + ASSERT_SAME_TYPE(typename E::index_type, IndexType); + ASSERT_SAME_TYPE(typename E::size_type, std::make_unsigned_t); + ASSERT_SAME_TYPE(typename E::rank_type, size_t); + + static_assert(sizeof...(Extents) == E::rank()); + static_assert((static_cast(Extents == std::dynamic_extent) + ...) == E::rank_dynamic()); + + static_assert(std::regular); + static_assert(std::is_trivially_copyable_v); + static_assert(std::is_empty_v == (E::rank_dynamic() == 0)); +} + +template +void testExtents() { + testExtents, IndexType, Extents...>(); +} + +template +void test() { + constexpr size_t D = std::dynamic_extent; + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + testExtents(); + + testExtents(); + testExtents(); + testExtents(); +} + +int main() { + test(); + test(); + test(); + test(); + test(); +} Index: libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp @@ -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 + +// + +// Test the feature test macros defined by + +/* Constant Value + __cpp_lib_mdspan 202207L [C++2b] +*/ + +#include +#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 + Index: libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -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 Index: libcxx/utils/generate_feature_test_macro_components.py =================================================================== --- libcxx/utils/generate_feature_test_macro_components.py +++ libcxx/utils/generate_feature_test_macro_components.py @@ -494,6 +494,11 @@ "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 },