Conversation
… integral_constant_like - Add C++26 CMake standard support and MDSPAN_ENABLE_P3663 option (default ON) - Add utility headers: remove_cvref.hpp, equality_comparable.hpp, integral_constant_like.hpp, constant_wrapper.hpp - Fix strided_slice static_assert to use conforming is_integral_constant_like_v - Fix one_slice_out_of_bounds to handle convertible-to-index-type slices - Add config.hpp default for MDSPAN_ENABLE_P3663 - Add tests: test_strided_slice, test_constant_wrapper, test_convertible_to_index_type Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
strided_slice and integral_constant_like
Remove the extra utility headers (remove_cvref, equality_comparable, integral_constant_like), revert strided_slice.hpp and one_slice_out_of_bounds to original, remove test_strided_slice and test_convertible_to_index_type. Keep only: - CMakeLists.txt: C++26 standard + MDSPAN_ENABLE_P3663 option - config.hpp: MDSPAN_ENABLE_P3663 default - constant_wrapper.hpp: new header - test_constant_wrapper.cpp: test for constant_wrapper Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
strided_slice and integral_constant_like
crtrott
left a comment
There was a problem hiding this comment.
The option should be IMPL only, and constant wrapper can be unconditionally there.
…stant_wrapper unconditional - CMakeLists.txt: option renamed MDSPAN_IMPL_ENABLE_P3663 - tests/CMakeLists.txt: define renamed MDSPAN_IMPL_ENABLE_P3663; test_constant_wrapper registered unconditionally (not under if-guard) - config.hpp: default macro renamed MDSPAN_IMPL_ENABLE_P3663 - test_constant_wrapper.cpp: unconditional include of constant_wrapper.hpp (no #if MDSPAN_ENABLE_P3663 / #error guard) Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
Done in 8cc9103. Renamed to |
crtrott
left a comment
There was a problem hiding this comment.
The test added compile definition and the config change are not technically necessary in this PR but it's fine. Establishes for fellow up work the option. So leave it like it is.
| else() | ||
| message(FATAL_ERROR "Requested MDSPAN_CXX_STANDARD \"23\" not supported by provided C++ compiler") | ||
| endif() | ||
| elseif(MDSPAN_CXX_STANDARD STREQUAL "26") |
There was a problem hiding this comment.
I've tested this with GCC trunk (16.0.1). It emits the warning but accepts the CMake option nevertheless.
Co-authored-by: Mark Hoemmen <mhoemmen@users.noreply.github.com>
crtrott
left a comment
There was a problem hiding this comment.
Move constant_wrapper to detail namespace.
- constant_wrapper.hpp: move constant_wrapper, cw, increment, and is_constant_wrapper all into MDSPAN_IMPL_STANDARD_NAMESPACE::detail (previously constant_wrapper/cw were in the enclosing namespace); in the back-port path, constant_wrapper now aliases integral_constant directly (no full qualification needed inside detail) - test_constant_wrapper.cpp: update all using-declarations to MDSPAN_IMPL_STANDARD_NAMESPACE::detail::cw / ::constant_wrapper Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
Done in 48aa88c. |
…rithmetic test - constant_wrapper.hpp: restructure into #if/__cpp_lib_constant_wrapper sections; fix increment/is_constant_wrapper to use single-NTTP form for std path and correct back-port form; add const-stripping specialization for is_constant_wrapper (constexpr variables are const, so is_constant_wrapper<const T> must work); move generic divide/multiply + std::integral_constant overloads here from submdspan_extents.hpp; add constant_wrapper overloads for both paths - submdspan_extents.hpp: add #include "constant_wrapper.hpp"; remove divide/multiply - test_constant_wrapper.cpp: add TestConstantWrapper.Arithmetic testing increment, divide, and multiply with size_t, including is_constant_wrapper checks Co-authored-by: crtrott <9490481+crtrott@users.noreply.github.com>
constant_wrapper header with divide/multiply/increment and C++26 CMake support (P3663 piece 1 of N)
| template<auto Value> | ||
| MDSPAN_INLINE_FUNCTION | ||
| constexpr auto | ||
| increment([[maybe_unused]] constant_wrapper<Value> x) { | ||
| using value_type = typename decltype(x)::value_type; | ||
| return cw< value_type(Value) + value_type(1) >; | ||
| } |
There was a problem hiding this comment.
We shouldn't need to duplicate the definition, as it's the same on both sides -- unless you want the std::constant_wrapper side to use the overloaded arithmetic operators!
mhoemmen
left a comment
There was a problem hiding this comment.
The point of increment, divide, etc. is that we don't have to implement them twice. If they have exactly the same definitions on both sides, then it's just one definition that we can lift outside the macro branch.
Signed-off-by: Christian Trott <crtrott@sandia.gov>
| template <class IndexT, class T0, class T1> | ||
| MDSPAN_INLINE_FUNCTION | ||
| constexpr auto divide(const T0 &v0, const T1 &v1) { | ||
| return IndexT(v0) / IndexT(v1); |
There was a problem hiding this comment.
I know this is what the current code does, so I'm not complaining : - ) . Let me just think out loud for a bit.
The casting behavior here looks not consistent with the behavior for constant_wrapper or integral_constant, where the cast happens after the division instead of before. I want to reason through whether this should be of concern.
In the P3663 case, v0 and v1 should have already been canonicalized, that is, converted to index_type or constant_wrapper thereof. Thus, T0 (or T0::value_type), T1 (or T1::value_type), and IndexT should all be the same.
In the no-P3663 case, I'm guessing that T0 and T1 are any types convertible to index_type (the current implementation says "convertible to size_t" which isn't quite right). The arithmetic then happens after the conversion. That's needed if the input type isn't integral, but otherwise it's different behavior than the integral_constant overload. I don't think it's worth fixing this because the no-P3663 case is nonconforming anyway.
First reviewable slice of PR #408. Establishes the
constant_wrapperbuilding block and consolidates compile-time arithmetic helpers in preparation for the P3663submdspancanonicalization work.CMake
MDSPAN_CXX_STANDARD=26with manual selection and auto-detection (prefers 26 > 23 > 20 > 17 > 14)MDSPAN_IMPL_ENABLE_P3663option (defaultON); propagated to all tests as a compile definitionconfig.hppdefault-definesMDSPAN_IMPL_ENABLE_P3663=1for header-only / Kokkos-snapshot usageconstant_wrapper.hpp(new)All symbols in
MDSPAN_IMPL_STANDARD_NAMESPACE::detail. Two paths:constant_wrapper/cw__cpp_lib_constant_wrapperusing std::constant_wrapper; using std::cw;detail::integral_constant<T, V>Provides in both paths:
increment(cw<V>)→cw<V+1>(compile-time)is_constant_wrapper<T>trait (handlesconst-qualified types fromconstexpr auto)divide<IndexT>(a, b)/multiply<IndexT>(a, b)— three overload tiers:std::integral_constant×std::integral_constant→detail::integral_constant(preserves compile-time value;divideshort-circuits on zero numerator)constant_wrapper×constant_wrapper→cw<result>(C++26: returnsstd::constant_wrapper; back-port: returnsdetail::integral_constant)submdspan_extents.hppdivideandmultiplydefinitions (now inconstant_wrapper.hpp)#include "constant_wrapper.hpp"Tests
test_constant_wrapper.cpp— registered unconditionally:IntegerPlus: basic construction, value access, and (under__cpp_lib_constant_wrapper) arithmetic withstd::constant_wrapperArithmetic:increment,divide(including zero-numerator), andmultiplywithsize_t; verifiesis_constant_wrapperholds for all results💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.