diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a7b66..86389d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Tooling and docs: unit tests, mkdocs site, Doxygen docs, and version bumping config. - Static analysis: clang-tidy integration with follow-up fixes. - CI workflows for build, test on GitHub +- `as_span()` method for creating full array views (#1) ### Changed diff --git a/include/nd_array/nd_array.hpp b/include/nd_array/nd_array.hpp index a02dbd6..d792297 100644 --- a/include/nd_array/nd_array.hpp +++ b/include/nd_array/nd_array.hpp @@ -825,7 +825,7 @@ namespace cppa /// \brief Creates an owning array by deep-copying an nd_span /// \param t_span Source span to copy /// \return Newly allocated array with the same contents - /// hrows std::invalid_argument if span rank exceeds MaxRank + /// \throws std::invalid_argument if span rank exceeds MaxRank static nd_array from_span( const nd_span& t_span ) { return from_span_impl( t_span ); } /// \brief Creates an owning array by deep-copying an nd_span @@ -1206,6 +1206,20 @@ namespace cppa /// \return Const pointer to the first element [[nodiscard]] const_pointer data( ) const noexcept { return m_data.get( ); } + /// \brief Creates a span view of the entire array + /// \return Non-owning span view of all elements + /// \example + /// \code + /// nd_array arr(3, 4); + /// arr.fill(1.0); + /// nd_span span = arr.as_span(); // View of entire array + /// \endcode + [[nodiscard]] nd_span as_span( ) noexcept { return nd_span( m_data.get( ), m_extents, m_strides, m_rank ); } + + /// \brief Creates a const span view of the entire array + /// \return Non-owning const span view of all elements + [[nodiscard]] nd_span as_span( ) const noexcept { return nd_span( m_data.get( ), m_extents, m_strides, m_rank ); } + /// \brief Returns a pointer to the first element for flat iteration [[nodiscard]] pointer begin( ) noexcept { return m_data.get( ); } diff --git a/tests/test_nd_array.cpp b/tests/test_nd_array.cpp index 376118a..4e7bebc 100644 --- a/tests/test_nd_array.cpp +++ b/tests/test_nd_array.cpp @@ -501,3 +501,54 @@ TEST_CASE( "nd_array - Span to array", "[nd_array][span][copy]" ) REQUIRE( assigned( 0, 1 ) == 7 ); } } + +TEST_CASE( "nd_array - Array to span", "[nd_array][span][view]" ) +{ + SECTION( "Create span from array" ) + { + nd_array arr( 3, 4 ); + arr.fill( 5 ); + arr( 1, 2 ) = 42; + + nd_span span = arr.as_span( ); + + REQUIRE( span.rank( ) == 2 ); + REQUIRE( span.extent( 0 ) == 3 ); + REQUIRE( span.extent( 1 ) == 4 ); + REQUIRE( span.size( ) == 12 ); + REQUIRE( span( 1, 2 ) == 42 ); + + // Modify through span + span( 0, 0 ) = 99; + REQUIRE( arr( 0, 0 ) == 99 ); + } + + SECTION( "Create const span from const array" ) + { + const nd_array arr = []( ) { + nd_array temp( 2, 3 ); + temp.fill( 10 ); + return temp; + }( ); + + nd_span span = arr.as_span( ); + + REQUIRE( span.rank( ) == 2 ); + REQUIRE( span.extent( 0 ) == 2 ); + REQUIRE( span.extent( 1 ) == 3 ); + REQUIRE( span( 0, 0 ) == 10 ); + } + + SECTION( "Span references same data" ) + { + nd_array arr( 5 ); + arr.fill( 3.14 ); + + auto span = arr.as_span( ); + REQUIRE( span.data( ) == arr.data( ) ); + + // Modify array, check span sees changes + arr( 3 ) = 2.71; + REQUIRE( span( 3 ) == 2.71 ); + } +}