mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 11:12:27 +00:00
Release Cosmopolitan v3.6.0
This release is an atomic upgrade to GCC 14.1.0 with C23 and C++23
This commit is contained in:
parent
62ace3623a
commit
5660ec4741
1585 changed files with 117353 additions and 271644 deletions
142
third_party/libcxx/__mdspan/extents.h
vendored
142
third_party/libcxx/__mdspan/extents.h
vendored
|
@ -137,9 +137,9 @@ private:
|
|||
// static mapping of indices to the position in the dynamic values array
|
||||
using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>;
|
||||
|
||||
template <size_t... Indices>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<Indices...>) noexcept {
|
||||
return _DynamicValues{((void)Indices, 0)...};
|
||||
template <size_t... _Indices>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<_Indices...>) noexcept {
|
||||
return _DynamicValues{((void)_Indices, 0)...};
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -165,49 +165,55 @@ public:
|
|||
template <class... _DynVals>
|
||||
requires(sizeof...(_DynVals) != __size_dynamic_)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) {
|
||||
static_assert((sizeof...(_DynVals) == __size_), "Invalid number of values.");
|
||||
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.");
|
||||
} else
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5);
|
||||
// Right-hand-side construction looks ok with allocation and size matching,
|
||||
// but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__values[__i] == static_cast<_TDynamic>(__static_val),
|
||||
"extents construction: mismatch of provided arguments with static extents.");
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Tp, size_t _Size>
|
||||
requires(_Size != __size_dynamic_)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) {
|
||||
static_assert((_Size == __size_) || (__size_ == dynamic_extent));
|
||||
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.");
|
||||
} else
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N));
|
||||
// Right-hand-side construction looks ok with allocation and size matching,
|
||||
// but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
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");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__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");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__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");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank");
|
||||
return __value(__i);
|
||||
}
|
||||
|
||||
|
@ -220,7 +226,7 @@ public:
|
|||
// value must be a positive integer otherwise returns false
|
||||
// if _From is not an integral, we just check positivity
|
||||
template <integral _To, class _From>
|
||||
requires(is_integral_v<_From>)
|
||||
requires(integral<_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>;
|
||||
|
@ -236,7 +242,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
|
|||
}
|
||||
|
||||
template <integral _To, class _From>
|
||||
requires(!is_integral_v<_From>)
|
||||
requires(!integral<_From>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) {
|
||||
if constexpr (is_signed_v<_To>) {
|
||||
if (static_cast<_To>(__value) < 0)
|
||||
|
@ -310,28 +316,37 @@ public:
|
|||
(sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
|
||||
: __vals_(static_cast<index_type>(__dynvals)...) {
|
||||
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
}
|
||||
|
||||
template <class _OtherIndexType, size_t _Size>
|
||||
requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
|
||||
requires(is_convertible_v<const _OtherIndexType&, index_type> &&
|
||||
is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
|
||||
(_Size == __rank_ || _Size == __rank_dynamic_))
|
||||
explicit(_Size != __rank_dynamic_)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
|
||||
: __vals_(span(__exts)) {
|
||||
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
}
|
||||
|
||||
template <class _OtherIndexType, size_t _Size>
|
||||
requires(is_convertible_v<_OtherIndexType, index_type> && is_nothrow_constructible_v<index_type, _OtherIndexType> &&
|
||||
requires(is_convertible_v<const _OtherIndexType&, index_type> &&
|
||||
is_nothrow_constructible_v<index_type, const _OtherIndexType&> &&
|
||||
(_Size == __rank_ || _Size == __rank_dynamic_))
|
||||
explicit(_Size != __rank_dynamic_)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
|
||||
: __vals_(__exts) {
|
||||
_LIBCPP_ASSERT(__mdspan_detail::__are_representable_as<index_type>(__exts),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56
|
||||
// on m
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -380,10 +395,16 @@ public:
|
|||
for (size_t __r = 0; __r < rank(); __r++) {
|
||||
if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
|
||||
static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
|
||||
_LIBCPP_ASSERT(__mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
|
||||
"extents ctor: arguments must be representable as index_type and nonnegative");
|
||||
}
|
||||
_LIBCPP_ASSERT(
|
||||
// Not catching this could lead to out of bounds errors later
|
||||
// e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5);
|
||||
// Right-hand-side construction was ok, but m now thinks its range is 10 not 5
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
(_Values::__static_value(__r) == dynamic_extent) ||
|
||||
(static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
|
||||
"extents construction: mismatch of provided arguments with static extents.");
|
||||
|
@ -433,13 +454,26 @@ struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> {
|
|||
template <class _IndexType, size_t _Rank>
|
||||
using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type;
|
||||
|
||||
// Deduction guide for extents
|
||||
template <class... _IndexTypes>
|
||||
extents(_IndexTypes...) -> extents<size_t, size_t((_IndexTypes(), dynamic_extent))...>;
|
||||
# if _LIBCPP_STD_VER >= 26
|
||||
// [mdspan.extents.dims], alias template `dims`
|
||||
template <size_t _Rank, class _IndexType = size_t>
|
||||
using dims = dextents<_IndexType, _Rank>;
|
||||
# endif
|
||||
|
||||
// Deduction guide for extents
|
||||
# if _LIBCPP_STD_VER >= 26
|
||||
template <class... _IndexTypes>
|
||||
requires(is_convertible_v<_IndexTypes, size_t> && ...)
|
||||
explicit extents(_IndexTypes...) -> extents<size_t, __maybe_static_ext<_IndexTypes>...>;
|
||||
# else
|
||||
template <class... _IndexTypes>
|
||||
requires(is_convertible_v<_IndexTypes, size_t> && ...)
|
||||
explicit extents(_IndexTypes...) -> extents<size_t, size_t(((void)sizeof(_IndexTypes), dynamic_extent))...>;
|
||||
# endif
|
||||
|
||||
// Helper type traits for identifying a class as extents.
|
||||
namespace __mdspan_detail {
|
||||
|
||||
// Helper type traits for identifying a class as extents.
|
||||
template <class _Tp>
|
||||
struct __is_extents : false_type {};
|
||||
|
||||
|
@ -449,6 +483,44 @@ struct __is_extents<extents<_IndexType, _ExtentsPack...>> : true_type {};
|
|||
template <class _Tp>
|
||||
inline constexpr bool __is_extents_v = __is_extents<_Tp>::value;
|
||||
|
||||
// Function to check whether a set of indices are a multidimensional
|
||||
// index into extents. This is a word of power in the C++ standard
|
||||
// requiring that the indices are larger than 0 and smaller than
|
||||
// the respective extents.
|
||||
|
||||
template <integral _IndexType, class _From>
|
||||
requires(integral<_From>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
|
||||
if constexpr (is_signed_v<_From>) {
|
||||
if (__value < 0)
|
||||
return false;
|
||||
}
|
||||
using _Tp = common_type_t<_IndexType, _From>;
|
||||
return static_cast<_Tp>(__value) < static_cast<_Tp>(__extent);
|
||||
}
|
||||
|
||||
template <integral _IndexType, class _From>
|
||||
requires(!integral<_From>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) {
|
||||
if constexpr (is_signed_v<_IndexType>) {
|
||||
if (static_cast<_IndexType>(__value) < 0)
|
||||
return false;
|
||||
}
|
||||
return static_cast<_IndexType>(__value) < __extent;
|
||||
}
|
||||
|
||||
template <size_t... _Idxs, class _Extents, class... _From>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool
|
||||
__is_multidimensional_index_in_impl(index_sequence<_Idxs...>, const _Extents& __ext, _From... __values) {
|
||||
return (__mdspan_detail::__is_index_in_extent(__ext.extent(_Idxs), __values) && ...);
|
||||
}
|
||||
|
||||
template <class _Extents, class... _From>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_multidimensional_index_in(const _Extents& __ext, _From... __values) {
|
||||
return __mdspan_detail::__is_multidimensional_index_in_impl(
|
||||
make_index_sequence<_Extents::rank()>(), __ext, __values...);
|
||||
}
|
||||
|
||||
} // namespace __mdspan_detail
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue