Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 15 additions & 1 deletion include/nd_array/nd_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const Ty, MaxRank>& t_span ) { return from_span_impl( t_span ); }

/// \brief Creates an owning array by deep-copying an nd_span
Expand Down Expand Up @@ -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<double> arr(3, 4);
/// arr.fill(1.0);
/// nd_span<double> span = arr.as_span(); // View of entire array
/// \endcode
[[nodiscard]] nd_span<Ty, MaxRank> as_span( ) noexcept { return nd_span<Ty, MaxRank>( 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<const Ty, MaxRank> as_span( ) const noexcept { return nd_span<const Ty, MaxRank>( 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( ); }

Expand Down
51 changes: 51 additions & 0 deletions tests/test_nd_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> arr( 3, 4 );
arr.fill( 5 );
arr( 1, 2 ) = 42;

nd_span<int> 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<int> arr = []( ) {
nd_array<int> temp( 2, 3 );
temp.fill( 10 );
return temp;
}( );

nd_span<const int> 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<double> 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 );
}
}
Loading