-
Notifications
You must be signed in to change notification settings - Fork 0
[Mirror] Implement canonicalize slices for mdspan (P3663) #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,10 @@ | |
| #include "compressed_pair.hpp" | ||
| #include "utility.hpp" | ||
|
|
||
| #if MDSPAN_HAS_CXX_17 | ||
| #include "../__p2642_bits/layout_padded_fwd.hpp" | ||
| #endif | ||
|
|
||
| #if !defined(MDSPAN_IMPL_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) | ||
| # include "no_unique_address.hpp" | ||
| #endif | ||
|
|
@@ -441,6 +445,8 @@ struct layout_stride { | |
| !(std::is_convertible<typename StridedLayoutMapping::extents_type, extents_type>::value && | ||
| (detail::is_mapping_of<layout_left, StridedLayoutMapping> || | ||
| detail::is_mapping_of<layout_right, StridedLayoutMapping> || | ||
| detail::is_layout_left_padded_mapping<StridedLayoutMapping>::value || // Don't need to guard for C++14 as this isn't compiled in < C++20 | ||
| detail::is_layout_right_padded_mapping<StridedLayoutMapping>::value || | ||
|
Comment on lines
+448
to
+449
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| detail::is_mapping_of<layout_stride, StridedLayoutMapping>)) | ||
| ) // needs two () due to comma | ||
| MDSPAN_INLINE_FUNCTION MDSPAN_IMPL_CONSTEXPR_14 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,14 @@ | |
| namespace MDSPAN_IMPL_STANDARD_NAMESPACE { | ||
| namespace detail { | ||
|
|
||
| // Backport of std::remove_cvref / std::remove_cvref_t (C++20) | ||
| #if (__cplusplus >= 202002L) | ||
| using std::remove_cvref_t; | ||
| #else | ||
| template<class T> | ||
| using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>; | ||
| #endif // __cplusplus >= 202002L | ||
|
|
||
| // type alias used for rank-based tag dispatch | ||
| // | ||
| // this is used to enable alternatives to constexpr if when building for C++14 | ||
|
|
@@ -203,6 +211,8 @@ MDSPAN_INLINE_FUNCTION constexpr bool cmp_greater_equal(T t, U u) noexcept { | |
|
|
||
| template <class R, class T> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool in_range(T t) noexcept { | ||
| static_assert(std::is_integral_v<R> && std::is_integral_v<T>); | ||
|
|
||
| #if defined(MDSPAN_IMPL_HAS_CUDA) && defined(__NVCC__) && (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10 >= 1260) | ||
| using cuda::std::numeric_limits; | ||
| #else | ||
|
|
@@ -212,6 +222,65 @@ MDSPAN_INLINE_FUNCTION constexpr bool in_range(T t) noexcept { | |
| cmp_less_equal(t, numeric_limits<R>::max()); | ||
| } | ||
|
|
||
| template <class R, class T> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool is_nonnegative_and_representable(T t) noexcept { | ||
| // T might not be integral and thus invalid to pass to in_range | ||
| // Only check this if we can actually call in_range | ||
| if constexpr (std::is_integral_v<T>) | ||
| { | ||
| if constexpr (std::is_signed_v<T>) { | ||
| if (t < 0) | ||
| return false; | ||
| } | ||
|
|
||
| return in_range<R>(t); | ||
| } else | ||
| { | ||
| if constexpr (std::is_signed_v<R>) { | ||
| if (static_cast<R>(t) < 0) | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| } | ||
|
Comment on lines
+225
to
+246
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In To fix this, we can define a helper to extract the underlying value of integral-constant-like types before performing the checks. template <class T, class = void>
struct has_value_member : std::false_type {};
template <class T>
struct has_value_member<T, decltype((void)T::value, void())> : std::true_type {};
template <class T>
constexpr auto get_absolute_value(T t) {
if constexpr (has_value_member<T>::value) {
return T::value;
} else {
return t;
}
}
template <class R, class T>
MDSPAN_INLINE_FUNCTION constexpr bool is_nonnegative_and_representable(T t) noexcept {
auto val = get_absolute_value(t);
using V = decltype(val);
if constexpr (std::is_integral_v<V>)
{
if constexpr (std::is_signed_v<V>) {
if (val < 0)
return false;
}
return in_range<R>(val);
} else
{
if constexpr (std::is_signed_v<R>) {
if (static_cast<R>(val) < 0)
return false;
}
return true;
}
} |
||
|
|
||
| template<class R, class... Values> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool | ||
| all_values_are_representable(Values... values) noexcept { | ||
| return ( in_range<R>( values ) && ... ); | ||
| } | ||
|
|
||
| template<class R, class... Values> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool | ||
| all_values_are_nonnegative_and_representable(Values... values) noexcept { | ||
| return ( is_nonnegative_and_representable<R>( values ) && ... ); | ||
| } | ||
|
|
||
| template<class R, class ContiguousIterator> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool | ||
| range_is_nonnegative_and_representable(ContiguousIterator begin, ContiguousIterator end) noexcept { | ||
| for ( auto it = begin; it < end; ++it ) | ||
| { | ||
| if ( !is_nonnegative_and_representable<R>( *it ) ) | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| template<class R, class Extents> | ||
| MDSPAN_INLINE_FUNCTION constexpr bool | ||
| extent_is_representable(const Extents &exts) noexcept { | ||
| for ( std::size_t r = 0; r < Extents::rank(); ++r ) | ||
| { | ||
| if ( !is_nonnegative_and_representable<R>( exts.extent(r) ) ) | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| template <typename T > | ||
| MDSPAN_INLINE_FUNCTION constexpr bool | ||
| check_mul_result_is_nonnegative_and_representable(T a, T b) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In C++14,
layout_padded_fwd.hppis not included becauseMDSPAN_HAS_CXX_17is false. However,detail::is_layout_left_padded_mappinganddetail::is_layout_right_padded_mappingare still referenced inMDSPAN_CONDITIONAL_EXPLICIT(which is compiled in C++14), leading to compilation failures. We can define helper traits that fall back tostd::false_typein C++14 to maintain compatibility.