From fcaccf817d31d39096f7d0e7014cd6fe2fa3a683 Mon Sep 17 00:00:00 2001 From: Christian Trott Date: Tue, 16 May 2023 12:38:11 -0700 Subject: [libcxx] Add mdspan/extents This patch adds std::extents. extents is one of the core classes used by std::mdspan. It describes a multi-dimensional index space with a mix of compile time and runtime sizes. Furthermore, it is templated on the index type used to describe the multi-dimensional index space. The class is designed to be highly optimizable in performance critical code sections, and is fully useable in constant expressions contexts. Testing of this class tends to be somewhat combinatorical, due to the large number of possible corner cases involved in situations where we have both runtime and compile time extents. To add to this, the class is designed to be interoperable (in particular constructible) from arguments which only need to be convertible to the index_type, but are otherwise arbitrary user types. For a larger discussion on the design of this class refer to: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0009r18.html Co-authored-by: Damien L-G Reviewed By: ldionne, #libc Spies: libcxx-commits, H-G-Hristov, tschuett, philnik, arichardson, Mordante, crtrott Differential Revision: https://reviews.llvm.org/D148067 --- libcxx/CREDITS.TXT | 9 + libcxx/docs/FeatureTestMacroTable.rst | 2 + libcxx/docs/Status/Cxx2bPapers.csv | 2 +- libcxx/include/CMakeLists.txt | 2 + libcxx/include/__mdspan/extents.h | 460 +++++++++++++++++++++ libcxx/include/libcxx.imp | 1 + libcxx/include/mdspan | 69 ++++ libcxx/include/module.modulemap.in | 10 + libcxx/include/version | 2 + .../headers_declare_verbose_abort.sh.cpp | 174 ++++---- libcxx/test/libcxx/clang_tidy.sh.cpp | 1 + libcxx/test/libcxx/double_include.sh.cpp | 1 + libcxx/test/libcxx/min_max_macros.compile.pass.cpp | 2 + libcxx/test/libcxx/modules_include.sh.cpp | 188 +++++---- libcxx/test/libcxx/nasty_macros.compile.pass.cpp | 1 + .../test/libcxx/no_assert_include.compile.pass.cpp | 1 + libcxx/test/libcxx/private_headers.verify.cpp | 1 + libcxx/test/libcxx/transitive_includes.sh.cpp | 222 +++++----- libcxx/test/libcxx/transitive_includes/cxx03.csv | 6 + libcxx/test/libcxx/transitive_includes/cxx11.csv | 6 + libcxx/test/libcxx/transitive_includes/cxx14.csv | 6 + libcxx/test/libcxx/transitive_includes/cxx17.csv | 6 + libcxx/test/libcxx/transitive_includes/cxx20.csv | 6 + libcxx/test/libcxx/transitive_includes/cxx2b.csv | 6 + .../views/mdspan/extents/ConvertibleToIntegral.h | 22 + .../views/mdspan/extents/CtorTestCombinations.h | 99 +++++ .../mdspan/extents/assert.conversion.pass.cpp | 57 +++ .../mdspan/extents/assert.ctor_from_array.pass.cpp | 69 ++++ .../extents/assert.ctor_from_integral.pass.cpp | 62 +++ .../mdspan/extents/assert.ctor_from_span.pass.cpp | 62 +++ .../views/mdspan/extents/assert.obs.pass.cpp | 65 +++ .../views/mdspan/extents/comparison.pass.cpp | 95 +++++ .../views/mdspan/extents/conversion.pass.cpp | 138 +++++++ .../containers/views/mdspan/extents/ctad.pass.cpp | 46 +++ .../views/mdspan/extents/ctor_default.pass.cpp | 49 +++ .../views/mdspan/extents/ctor_from_array.pass.cpp | 86 ++++ .../mdspan/extents/ctor_from_integral.pass.cpp | 69 ++++ .../views/mdspan/extents/ctor_from_span.pass.cpp | 88 ++++ .../views/mdspan/extents/dextents.pass.cpp | 39 ++ .../views/mdspan/extents/obs_static.pass.cpp | 88 ++++ .../containers/views/mdspan/extents/types.pass.cpp | 85 ++++ .../mdspan.version.compile.pass.cpp | 65 +++ .../version.version.compile.pass.cpp | 30 ++ .../generate_feature_test_macro_components.py | 5 + 44 files changed, 2218 insertions(+), 285 deletions(-) create mode 100644 libcxx/include/__mdspan/extents.h create mode 100644 libcxx/include/mdspan create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ConvertibleToIntegral.h create mode 100644 libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h create mode 100644 libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/conversion.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ctor_default.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp create mode 100644 libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp create mode 100644 libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp (limited to 'libcxx') diff --git a/libcxx/CREDITS.TXT b/libcxx/CREDITS.TXT index cd5bc08a60fc..aa3c8cf1a8c6 100644 --- a/libcxx/CREDITS.TXT +++ b/libcxx/CREDITS.TXT @@ -92,6 +92,11 @@ E: stl@microsoft.com E: stl@nuwen.net D: Implemented floating-point to_chars. +N: Damien Lebrun-Grandie +E: dalg24@gmail.com +E: lebrungrandt@ornl.gov +D: Implementation of mdspan. + N: Microsoft Corporation D: Contributed floating-point to_chars. @@ -149,6 +154,10 @@ N: Stephan Tolksdorf E: st@quanttec.com D: Minor fix +N: Christian Trott +E: crtrott@sandia.gov +D: Implementation of mdspan. + N: Ruben Van Boxem E: vanboxem dot ruben at gmail dot com D: Initial Windows patches. diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 677a71922bd0..0f5ee6c24485 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -332,6 +332,8 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_is_scoped_enum`` ``202011L`` ------------------------------------------------- ----------------- + ``__cpp_lib_mdspan`` *unimplemented* + ------------------------------------------------- ----------------- ``__cpp_lib_move_only_function`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_optional`` ``202110L`` diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv index a310cfc5ff16..550fb34d4b34 100644 --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -51,7 +51,7 @@ "`P2442R1 `__","LWG","Windowing range adaptors: ``views::chunk`` and ``views::slide``","February 2022","","","|ranges|" "`P2443R1 `__","LWG","``views::chunk_by``","February 2022","","","|ranges|" "","","","","","","" -"`P0009R18 `__","LWG","mdspan: A Non-Owning Multidimensional Array Reference","July 2022","","" +"`P0009R18 `__","LWG","mdspan: A Non-Owning Multidimensional Array Reference","July 2022","|In progress|","" "`P0429R9 `__","LWG","A Standard ``flat_map``","July 2022","","" "`P1169R4 `__","LWG","``static operator()``","July 2022","|Complete|","16.0" "`P1222R4 `__","LWG","A Standard ``flat_set``","July 2022","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 04293ba4bad6..190616aaa55c 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -463,6 +463,7 @@ set(files __locale_dir/locale_base_api/bsd_locale_fallbacks.h __locale_dir/locale_base_api/locale_guard.h __mbstate_t.h + __mdspan/extents.h __memory/addressof.h __memory/align.h __memory/aligned_alloc.h @@ -913,6 +914,7 @@ set(files locale.h map math.h + mdspan memory memory_resource mutex diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h new file mode 100644 index 000000000000..e31e43493f46 --- /dev/null +++ b/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 <__type_traits/common_type.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_same.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/integer_sequence.h> +#include <__utility/unreachable.h> +#include +#include +#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 +struct __static_partial_sums { + _LIBCPP_HIDE_FROM_ABI static constexpr array __static_partial_sums_impl() { + array __values{_Values...}; + 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; + } + static constexpr array __result{__static_partial_sums_impl()}; + + _LIBCPP_HIDE_FROM_ABI static constexpr size_t __get(size_t __index) { return __result[__index]; } +}; + +// ------------------------------------------------------------------ +// ------------ __maybe_static_array -------------------------------- +// ------------------------------------------------------------------ + +// array like class which has a mix of static and runtime values but +// only stores the runtime values. +// The type of the static and the runtime values can be different. +// The position of a dynamic value is indicated through a tag value. +template +struct __maybe_static_array { + static_assert(is_convertible<_TStatic, _TDynamic>::value, + "__maybe_static_array: _TStatic must be convertible to _TDynamic"); + static_assert(is_convertible<_TDynamic, _TStatic>::value, + "__maybe_static_array: _TDynamic must be convertible to _TStatic"); + +private: + // Static values member + static constexpr size_t __size_ = sizeof...(_Values); + static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0); + using _StaticValues = __static_array<_TStatic, _Values...>; + using _DynamicValues = __possibly_empty_array<_TDynamic, __size_dynamic_>; + + // Dynamic values member + _LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_; + + // static mapping of indices to the position in the dynamic values array + using _DynamicIdxMap = __static_partial_sums(_Values == _DynTag)...>; + + template + _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence) noexcept { + return _DynamicValues{((void)Indices, 0)...}; + } + +public: + _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept + : __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {} + + // constructors from dynamic values only -- this covers the case for rank() == 0 + template + 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>(numeric_limits<_To>::max()) >= static_cast<_From_u>(numeric_limits<_From>::max())) { + return true; + } else { + return static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(__value); + } +} + +template + 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 (__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 (!__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 { + if constexpr (rank() != sizeof...(_OtherExtents)) { + return false; + } else { + for (rank_type __r = 0; __r < __rank_; __r++) { + // avoid warning when comparing signed and unsigner integers and pick the wider of two types + using _CommonType = common_type_t; + if (static_cast<_CommonType>(__lhs.extent(__r)) != static_cast<_CommonType>(__rhs.extent(__r))) { + return false; + } + } + } + return true; + } +}; + +// Recursive helper classes to implement dextents alias for extents +namespace __mdspan_detail { + +template > +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 diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp index 271812e9eb9d..8414773228bb 100644 --- a/libcxx/include/libcxx.imp +++ b/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" ] }, diff --git a/libcxx/include/mdspan b/libcxx/include/mdspan new file mode 100644 index 000000000000..16b4e3e1641a --- /dev/null +++ b/libcxx/include/mdspan @@ -0,0 +1,69 @@ +// -*-C++ - *- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +/* + extents synopsis + +namespace std { + template + class 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; + + private: + // libcxx note: we do not use an array here, but we need to preserve the as-if behavior + // for example the default constructor must zero initialize dynamic extents + array dynamic-extents{}; // exposition only + }; + + template + explicit extents(Integrals...) + -> see below; +} +*/ + +#ifndef _LIBCPP_MDSPAN +#define _LIBCPP_MDSPAN + +#include <__config> +#include <__mdspan/extents.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#endif // _LIBCPP_MDSPAN diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index af65d60227af..7bde1becba5d 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1162,6 +1162,16 @@ module std [system] { export initializer_list export * } + module mdspan { + header "mdspan" + export array + export span + export * + + module __mdspan { + module extents { private header "__mdspan/extents.h" } + } + } module memory { header "memory" export * diff --git a/libcxx/include/version b/libcxx/include/version index f58b51e49fee..b87abdfce522 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -123,6 +123,7 @@ __cpp_lib_make_unique 201304L __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 @@ __cpp_lib_void_t 201411L # 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 diff --git a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp index 1f2a4650c9d5..5587e21a131a 100644 --- a/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp +++ b/libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp @@ -418,330 +418,336 @@ int main(int, char**) { return 0; } // 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 + using HandlerType = decltype(std::__libcpp_verbose_abort); +#endif + +// RUN: %{build} -DTEST_138 +#if defined(TEST_138) && __cplusplus >= 201103L # include using HandlerType = decltype(std::__libcpp_verbose_abort); #endif diff --git a/libcxx/test/libcxx/clang_tidy.sh.cpp b/libcxx/test/libcxx/clang_tidy.sh.cpp index ab9bbc6c3914..c4bce6b155f3 100644 --- a/libcxx/test/libcxx/clang_tidy.sh.cpp +++ b/libcxx/test/libcxx/clang_tidy.sh.cpp @@ -134,6 +134,7 @@ END-SCRIPT #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) diff --git a/libcxx/test/libcxx/double_include.sh.cpp b/libcxx/test/libcxx/double_include.sh.cpp index 292f53a0d077..7f61fef65662 100644 --- a/libcxx/test/libcxx/double_include.sh.cpp +++ b/libcxx/test/libcxx/double_include.sh.cpp @@ -132,6 +132,7 @@ END-SCRIPT #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) diff --git a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp index d032e97f1ddc..0bd4c4791b29 100644 --- a/libcxx/test/libcxx/min_max_macros.compile.pass.cpp +++ b/libcxx/test/libcxx/min_max_macros.compile.pass.cpp @@ -203,6 +203,8 @@ TEST_MACROS(); TEST_MACROS(); #include TEST_MACROS(); +#include +TEST_MACROS(); #include TEST_MACROS(); #include diff --git a/libcxx/test/libcxx/modules_include.sh.cpp b/libcxx/test/libcxx/modules_include.sh.cpp index 3f3967aa418b..8a625890f760 100644 --- a/libcxx/test/libcxx/modules_include.sh.cpp +++ b/libcxx/test/libcxx/modules_include.sh.cpp @@ -465,405 +465,410 @@ END-SCRIPT // 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) && __cplusplus >= 201103L +#include +#endif // RUN: echo "wait $TEST_123" >> %t.sh // RUN: echo "wait $TEST_124" >> %t.sh // RUN: echo "wait $TEST_125" >> %t.sh @@ -879,5 +884,6 @@ END-SCRIPT // RUN: echo "wait $TEST_135" >> %t.sh // RUN: echo "wait $TEST_136" >> %t.sh // RUN: echo "wait $TEST_137" >> %t.sh +// RUN: echo "wait $TEST_138" >> %t.sh // RUN: bash %t.sh // GENERATED-MARKER diff --git a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp index 5254e0d78e88..49ab781e8771 100644 --- a/libcxx/test/libcxx/nasty_macros.compile.pass.cpp +++ b/libcxx/test/libcxx/nasty_macros.compile.pass.cpp @@ -257,6 +257,7 @@ END-SCRIPT #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) diff --git a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp index 779a21a02dd5..b5ac8519320c 100644 --- a/libcxx/test/libcxx/no_assert_include.compile.pass.cpp +++ b/libcxx/test/libcxx/no_assert_include.compile.pass.cpp @@ -129,6 +129,7 @@ END-SCRIPT #endif #include #include +#include #include #include #if !defined(_LIBCPP_HAS_NO_THREADS) diff --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp index 6762913512c7..3ff91e1de143 100644 --- a/libcxx/test/libcxx/private_headers.verify.cpp +++ b/libcxx/test/libcxx/private_headers.verify.cpp @@ -493,6 +493,7 @@ END-SCRIPT #include <__iterator/wrap_iter.h> // expected-error@*:* {{use of private header from outside its module: '__iterator/wrap_iter.h'}} #include <__locale> // expected-error@*:* {{use of private header from outside its module: '__locale'}} #include <__mbstate_t.h> // expected-error@*:* {{use of private header from outside its module: '__mbstate_t.h'}} +#include <__mdspan/extents.h> // expected-error@*:* {{use of private header from outside its module: '__mdspan/extents.h'}} #include <__memory/addressof.h> // expected-error@*:* {{use of private header from outside its module: '__memory/addressof.h'}} #include <__memory/align.h> // expected-error@*:* {{use of private header from outside its module: '__memory/align.h'}} #include <__memory/aligned_alloc.h> // expected-error@*:* {{use of private header from outside its module: '__memory/aligned_alloc.h'}} diff --git a/libcxx/test/libcxx/transitive_includes.sh.cpp b/libcxx/test/libcxx/transitive_includes.sh.cpp index 1bbc906bb507..db462025bb1c 100644 --- a/libcxx/test/libcxx/transitive_includes.sh.cpp +++ b/libcxx/test/libcxx/transitive_includes.sh.cpp @@ -317,224 +317,228 @@ END-SCRIPT #if defined(TEST_69) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 > /dev/null 2> %t/header.memory +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_71 > /dev/null 2> %t/header.mdspan #if defined(TEST_71) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 > /dev/null 2> %t/header.memory_resource +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_72 > /dev/null 2> %t/header.memory #if defined(TEST_72) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 > /dev/null 2> %t/header.mutex +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_73 > /dev/null 2> %t/header.memory_resource #if defined(TEST_73) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 > /dev/null 2> %t/header.new +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_74 > /dev/null 2> %t/header.mutex #if defined(TEST_74) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 > /dev/null 2> %t/header.numbers +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_75 > /dev/null 2> %t/header.new #if defined(TEST_75) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 > /dev/null 2> %t/header.numeric +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_76 > /dev/null 2> %t/header.numbers #if defined(TEST_76) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 > /dev/null 2> %t/header.optional +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_77 > /dev/null 2> %t/header.numeric #if defined(TEST_77) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 > /dev/null 2> %t/header.ostream +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_78 > /dev/null 2> %t/header.optional #if defined(TEST_78) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 > /dev/null 2> %t/header.queue +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_79 > /dev/null 2> %t/header.ostream #if defined(TEST_79) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 > /dev/null 2> %t/header.random +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_80 > /dev/null 2> %t/header.queue #if defined(TEST_80) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 > /dev/null 2> %t/header.ranges +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_81 > /dev/null 2> %t/header.random #if defined(TEST_81) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 > /dev/null 2> %t/header.ratio +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_82 > /dev/null 2> %t/header.ranges #if defined(TEST_82) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 > /dev/null 2> %t/header.regex +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_83 > /dev/null 2> %t/header.ratio #if defined(TEST_83) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 > /dev/null 2> %t/header.scoped_allocator +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_84 > /dev/null 2> %t/header.regex #if defined(TEST_84) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 > /dev/null 2> %t/header.semaphore +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_85 > /dev/null 2> %t/header.scoped_allocator #if defined(TEST_85) -#include +#include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 > /dev/null 2> %t/header.set +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_86 > /dev/null 2> %t/header.semaphore #if defined(TEST_86) +#include +#endif +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_87 > /dev/null 2> %t/header.set +#if defined(TEST_87) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_88 > /dev/null 2> %t/header.shared_mutex -#if defined(TEST_88) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 > /dev/null 2> %t/header.shared_mutex +#if defined(TEST_89) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_89 > /dev/null 2> %t/header.source_location -#if defined(TEST_89) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 > /dev/null 2> %t/header.source_location +#if defined(TEST_90) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_90 > /dev/null 2> %t/header.span -#if defined(TEST_90) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 > /dev/null 2> %t/header.span +#if defined(TEST_91) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_91 > /dev/null 2> %t/header.sstream -#if defined(TEST_91) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 > /dev/null 2> %t/header.sstream +#if defined(TEST_92) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_92 > /dev/null 2> %t/header.stack -#if defined(TEST_92) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_93 > /dev/null 2> %t/header.stack +#if defined(TEST_93) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_96 > /dev/null 2> %t/header.stdexcept -#if defined(TEST_96) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_97 > /dev/null 2> %t/header.stdexcept +#if defined(TEST_97) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_100 > /dev/null 2> %t/header.streambuf -#if defined(TEST_100) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 > /dev/null 2> %t/header.streambuf +#if defined(TEST_101) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_101 > /dev/null 2> %t/header.string -#if defined(TEST_101) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_102 > /dev/null 2> %t/header.string +#if defined(TEST_102) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_103 > /dev/null 2> %t/header.string_view -#if defined(TEST_103) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 > /dev/null 2> %t/header.string_view +#if defined(TEST_104) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_104 > /dev/null 2> %t/header.strstream -#if defined(TEST_104) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 > /dev/null 2> %t/header.strstream +#if defined(TEST_105) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_105 > /dev/null 2> %t/header.system_error -#if defined(TEST_105) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_106 > /dev/null 2> %t/header.system_error +#if defined(TEST_106) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_107 > /dev/null 2> %t/header.thread -#if defined(TEST_107) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 > /dev/null 2> %t/header.thread +#if defined(TEST_108) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_108 > /dev/null 2> %t/header.tuple -#if defined(TEST_108) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 > /dev/null 2> %t/header.tuple +#if defined(TEST_109) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_109 > /dev/null 2> %t/header.type_traits -#if defined(TEST_109) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 > /dev/null 2> %t/header.type_traits +#if defined(TEST_110) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_110 > /dev/null 2> %t/header.typeindex -#if defined(TEST_110) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 > /dev/null 2> %t/header.typeindex +#if defined(TEST_111) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_111 > /dev/null 2> %t/header.typeinfo -#if defined(TEST_111) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_112 > /dev/null 2> %t/header.typeinfo +#if defined(TEST_112) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_113 > /dev/null 2> %t/header.unordered_map -#if defined(TEST_113) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 > /dev/null 2> %t/header.unordered_map +#if defined(TEST_114) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_114 > /dev/null 2> %t/header.unordered_set -#if defined(TEST_114) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 > /dev/null 2> %t/header.unordered_set +#if defined(TEST_115) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_115 > /dev/null 2> %t/header.utility -#if defined(TEST_115) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 > /dev/null 2> %t/header.utility +#if defined(TEST_116) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_116 > /dev/null 2> %t/header.valarray -#if defined(TEST_116) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 > /dev/null 2> %t/header.valarray +#if defined(TEST_117) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_117 > /dev/null 2> %t/header.variant -#if defined(TEST_117) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 > /dev/null 2> %t/header.variant +#if defined(TEST_118) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_118 > /dev/null 2> %t/header.vector -#if defined(TEST_118) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 > /dev/null 2> %t/header.vector +#if defined(TEST_119) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_119 > /dev/null 2> %t/header.version -#if defined(TEST_119) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_120 > /dev/null 2> %t/header.version +#if defined(TEST_120) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_122 > /dev/null 2> %t/header.experimental_deque -#if defined(TEST_122) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 > /dev/null 2> %t/header.experimental_deque +#if defined(TEST_123) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_123 > /dev/null 2> %t/header.experimental_forward_list -#if defined(TEST_123) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 > /dev/null 2> %t/header.experimental_forward_list +#if defined(TEST_124) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_124 > /dev/null 2> %t/header.experimental_iterator -#if defined(TEST_124) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 > /dev/null 2> %t/header.experimental_iterator +#if defined(TEST_125) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_125 > /dev/null 2> %t/header.experimental_list -#if defined(TEST_125) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 > /dev/null 2> %t/header.experimental_list +#if defined(TEST_126) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_126 > /dev/null 2> %t/header.experimental_map -#if defined(TEST_126) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 > /dev/null 2> %t/header.experimental_map +#if defined(TEST_127) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_127 > /dev/null 2> %t/header.experimental_memory_resource -#if defined(TEST_127) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 > /dev/null 2> %t/header.experimental_memory_resource +#if defined(TEST_128) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_128 > /dev/null 2> %t/header.experimental_propagate_const -#if defined(TEST_128) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 > /dev/null 2> %t/header.experimental_propagate_const +#if defined(TEST_129) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_129 > /dev/null 2> %t/header.experimental_regex -#if defined(TEST_129) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 > /dev/null 2> %t/header.experimental_regex +#if defined(TEST_130) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_130 > /dev/null 2> %t/header.experimental_set -#if defined(TEST_130) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 > /dev/null 2> %t/header.experimental_set +#if defined(TEST_131) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_131 > /dev/null 2> %t/header.experimental_simd -#if defined(TEST_131) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 > /dev/null 2> %t/header.experimental_simd +#if defined(TEST_132) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_132 > /dev/null 2> %t/header.experimental_string -#if defined(TEST_132) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 > /dev/null 2> %t/header.experimental_string +#if defined(TEST_133) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_133 > /dev/null 2> %t/header.experimental_type_traits -#if defined(TEST_133) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 > /dev/null 2> %t/header.experimental_type_traits +#if defined(TEST_134) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_134 > /dev/null 2> %t/header.experimental_unordered_map -#if defined(TEST_134) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 > /dev/null 2> %t/header.experimental_unordered_map +#if defined(TEST_135) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_135 > /dev/null 2> %t/header.experimental_unordered_set -#if defined(TEST_135) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 > /dev/null 2> %t/header.experimental_unordered_set +#if defined(TEST_136) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_136 > /dev/null 2> %t/header.experimental_utility -#if defined(TEST_136) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 > /dev/null 2> %t/header.experimental_utility +#if defined(TEST_137) #include #endif -// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_137 > /dev/null 2> %t/header.experimental_vector -#if defined(TEST_137) +// RUN: %{cxx} %s %{flags} %{compile_flags} --trace-includes -fshow-skipped-includes --preprocess -DTEST_138 > /dev/null 2> %t/header.experimental_vector +#if defined(TEST_138) #include #endif // RUN: %{python} %S/transitive_includes_to_csv.py %t > %t/transitive_includes.csv diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index 172f222d18cb..0770eaaed821 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -515,6 +515,12 @@ map tuple map type_traits map utility map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index f75a9987622e..f60756138b55 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -515,6 +515,12 @@ map tuple map type_traits map utility map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index f402f3e2e66d..2fe6248ae667 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -517,6 +517,12 @@ map tuple map type_traits map utility map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv index f402f3e2e66d..2fe6248ae667 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -517,6 +517,12 @@ map tuple map type_traits map utility map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv index 79ad40506851..2c743b9672f2 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -523,6 +523,12 @@ map tuple map type_traits map utility map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory atomic memory compare memory concepts diff --git a/libcxx/test/libcxx/transitive_includes/cxx2b.csv b/libcxx/test/libcxx/transitive_includes/cxx2b.csv index 833df27c70f5..0a386315e72a 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx2b.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx2b.csv @@ -351,6 +351,12 @@ map optional map stdexcept map tuple map version +mdspan array +mdspan cinttypes +mdspan concepts +mdspan cstddef +mdspan limits +mdspan span memory compare memory cstddef memory cstdint diff --git a/libcxx/test/std/containers/views/mdspan/extents/ConvertibleToIntegral.h b/libcxx/test/std/containers/views/mdspan/extents/ConvertibleToIntegral.h new file mode 100644 index 000000000000..1cdb198739ec --- /dev/null +++ b/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 TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H +#define TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H + +struct IntType { + int val; + constexpr IntType() = default; + constexpr IntType(int v) noexcept : val(v){}; + + constexpr bool operator==(const IntType& rhs) const { return val == rhs.val; } + constexpr operator int() const noexcept { return val; } + constexpr operator unsigned char() const noexcept { return val; } +}; + +#endif // TEST_STD_CONTAINERS_CONVERTIBLE_TO_INTEGRAL_H diff --git a/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h b/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h new file mode 100644 index 000000000000..4914b5c1d874 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h @@ -0,0 +1,99 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +#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 void test_runtime_observers(E ext, AllExtents expected) { + for (typename E::rank_type r = 0; r < ext.rank(); r++) { + ASSERT_SAME_TYPE(decltype(ext.extent(0)), typename E::index_type); + ASSERT_NOEXCEPT(ext.extent(0)); + assert(ext.extent(r) == static_cast(expected[r])); + } +} + +template +constexpr void test_implicit_construction_call(E e, AllExtents all_ext) { + test_runtime_observers(e, all_ext); +} + +template +constexpr void test_construction(AllExtents all_ext) { + // test construction from all extents + Test::template test_construction(all_ext, all_ext, std::make_index_sequence()); + + // 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++; + } + } + Test::template test_construction(all_ext, dyn_ext, std::make_index_sequence()); +} + +template +constexpr void test() { + constexpr size_t D = std::dynamic_extent; + + test_construction, Test>(std::array{}); + + test_construction, Test>(std::array{3}); + test_construction, Test>(std::array{3}); + + test_construction, Test>(std::array{3, 7}); + test_construction, Test>(std::array{3, 7}); + test_construction, Test>(std::array{3, 7}); + test_construction, Test>(std::array{3, 7}); + + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + test_construction, Test>(std::array{3, 7, 9}); + + test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); + test_construction, Test>(std::array{1, 2, 3, 4, 5, 6, 7, 8, 9}); +} + +template +constexpr bool test_index_type_combo() { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + return true; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp new file mode 100644 index 000000000000..1ca4e2ec178a --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp @@ -0,0 +1,57 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// XFAIL: availability-verbose_abort-missing +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// + +// 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(int, char**) { + 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"); + } + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp new file mode 100644 index 000000000000..b5e74df97ca2 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp @@ -0,0 +1,69 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// XFAIL: availability-verbose_abort-missing +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// + +// 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(int, char**) { + 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"); + } + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp new file mode 100644 index 000000000000..69f8436f5653 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp @@ -0,0 +1,62 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// XFAIL: availability-verbose_abort-missing +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// + +// Test construction from 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(int, char**) { + 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"); + } + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp new file mode 100644 index 000000000000..0375ca43054a --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp @@ -0,0 +1,62 @@ +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// REQUIRES: has-unix-headers +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// XFAIL: availability-verbose_abort-missing +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1 + +// Test construction from span: +// +// template +// 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(int, char**) { + 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"); + } + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp new file mode 100644 index 000000000000..acf09bdc0c5a --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/assert.obs.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 +// +//===----------------------------------------------------------------------===// +// 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(int, char**) { + 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); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp new file mode 100644 index 000000000000..77fbd46fb7ca --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/comparison.pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// +// +// 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. +// + +#include +#include +#include +#include + +#include "test_macros.h" + +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; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/conversion.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/conversion.pass.cpp new file mode 100644 index 000000000000..6b0ecff02baa --- /dev/null +++ b/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; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctad.pass.cpp new file mode 100644 index 000000000000..81d85c1faf0f --- /dev/null +++ b/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; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctor_default.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctor_default.pass.cpp new file mode 100644 index 000000000000..b2de473f8e8c --- /dev/null +++ b/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 "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct DefaultCtorTest { + template + static constexpr void test_construction(AllExtents all_ext, Extents, std::index_sequence) { + // This function gets called twice: once with Extents being just the dynamic ones, and once with all the extents specified. + // We only test during the all extent case, since then Indices is the correct number. This allows us to reuse the same + // testing machinery used in other constructor tests. + if constexpr (sizeof...(Indices) == E::rank()) { + ASSERT_NOEXCEPT(E{}); + // Need to construct new expected values, replacing dynamic values with 0 + std::array expected_exts{ + ((E::static_extent(Indices) == std::dynamic_extent) + ? typename AllExtents::value_type(0) + : all_ext[Indices])...}; + test_runtime_observers(E{}, expected_exts); + } + } +}; + +int main(int, char**) { + test_index_type_combo(); + static_assert(test_index_type_combo()); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp new file mode 100644 index 000000000000..48286e112849 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_array.pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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 ArrayCtorTest { + template + static constexpr void test_construction(std::array all_ext, Extents ext, std::index_sequence) { + ASSERT_NOEXCEPT(E(ext)); + if constexpr (N == E::rank_dynamic()) { + test_implicit_construction_call(ext, all_ext); + } + test_runtime_observers(E(ext), all_ext); + } +}; + +template +struct implicit_construction { + bool value; + implicit_construction(E) : value(true) {} + template + implicit_construction(T) : value(false) {} +}; + +int main(int, char**) { + test_index_type_combo(); + static_assert(test_index_type_combo()); + + 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"); + // check can't construct from rank_dynamic < #args < rank + 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"); + + // test implicit construction fails from span and array if all extents are given + std::array a5{3, 4, 5, 6, 7}; + // check that explicit construction works, i.e. no error + static_assert(std::is_constructible_v< std::extents, decltype(a5)>, + "extents unexpectectly not constructible"); + // check that implicit construction doesn't work + assert((implicit_construction>(a5).value == false)); + + // test construction fails from types not convertible to index_type but convertible to other integer types + static_assert(std::is_convertible_v, "Test helper IntType unexpectedly not convertible to int"); + static_assert(!std::is_constructible_v< std::extents, std::array>, + "extents constructible from illegal arguments"); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp new file mode 100644 index 000000000000..fd3624e74a3d --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_integral.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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 "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct IntegralCtorTest { + template + static constexpr void test_construction(AllExtents all_ext, Extents ext, std::index_sequence) { + // construction from indices + ASSERT_NOEXCEPT(E(ext[Indices]...)); + test_runtime_observers(E(ext[Indices]...), all_ext); + } +}; + +int main(int, char**) { + test_index_type_combo(); + static_assert(test_index_type_combo()); + + 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"); + // check can't construct from rank_dynamic < #args < rank + 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"); + + // 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"); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp new file mode 100644 index 000000000000..2e69bab1461c --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/ctor_from_span.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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 + +#include "ConvertibleToIntegral.h" +#include "CtorTestCombinations.h" +#include "test_macros.h" + +struct SpanCtorTest { + template + static constexpr void test_construction(std::array all_ext, Extents ext, std::index_sequence) { + ASSERT_NOEXCEPT(E(ext)); + if constexpr (N == E::rank_dynamic()) { + test_implicit_construction_call(std::span(ext), all_ext); + } + test_runtime_observers(E(std::span(ext)), all_ext); + } +}; + +template +struct implicit_construction { + bool value; + implicit_construction(E) : value(true) {} + template + implicit_construction(T) : value(false) {} +}; + +int main(int, char**) { + test_index_type_combo(); + static_assert(test_index_type_combo()); + + 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"); + // check can't construct from rank_dynamic < #args < rank + 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"); + + // 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(s5)>, + "extents unexpectectly not constructible"); + // check that implicit construction doesn't work + 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, std::span>, + "extents constructible from illegal arguments"); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp new file mode 100644 index 000000000000..a9fc8f3bed07 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/dextents.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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(int, char**) { + test_alias_template_dextents(); + test_alias_template_dextents(); + test_alias_template_dextents(); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp new file mode 100644 index 000000000000..90b482b3bc06 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/obs_static.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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(int, char**) { + test(); + test(); + test(); + test(); + test(); + return 0; +} diff --git a/libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp b/libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp new file mode 100644 index 000000000000..228194533399 --- /dev/null +++ b/libcxx/test/std/containers/views/mdspan/extents/types.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 + +// + +// 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); + +// Did never find a way to make this true on windows +#ifndef _WIN32 + LIBCPP_STATIC_ASSERT(std::is_empty_v == (E::rank_dynamic() == 0)); +#endif +} + +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(int, char**) { + test(); + test(); + test(); + test(); + test(); + return 0; +} diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp new file mode 100644 index 000000000000..26c2600f14e6 --- /dev/null +++ b/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 + diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index a289eebb4309..e1bdde4551a7 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/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 diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index fb59395115e3..5ace82348dcb 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -494,6 +494,11 @@ feature_test_macros = [ add_version_header(x) for x in [ "values": { "c++17": 201603 }, "headers": ["cmath"], "unimplemented": True, + }, { + "name": "__cpp_lib_mdspan", + "values": { "c++2b": 202207 }, + "headers": ["mdspan"], + "unimplemented": True, }, { "name": "__cpp_lib_memory_resource", "values": { "c++17": 201603 }, -- cgit v1.2.1