-
Notifications
You must be signed in to change notification settings - Fork 234
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support for std::span for winrt::array_view and winrt::com_array (#1343)
* Implicit conversion between std::span and winrt::array_view * Add testing and additional ctad for spans * PR FB - yes, yes it does! * PR FB --------- Co-authored-by: Jaiganésh Kumaran <[email protected]> Co-authored-by: Jon Wiswall <[email protected]> Co-authored-by: Kenny Kerr <[email protected]>
- Loading branch information
1 parent
de6ca88
commit 691f6f8
Showing
5 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
#include "pch.h" | ||
#include "catch.hpp" | ||
#include <array> | ||
|
||
using namespace winrt; | ||
using namespace Windows::Foundation; | ||
using namespace Windows::Storage::Streams; | ||
using namespace Windows::Data::Json; | ||
|
||
// | ||
// This is a helper to create a data reader for use in testing arrays. | ||
// | ||
static IAsyncOperation<IDataReader> CreateDataReader(std::initializer_list<byte> values) | ||
{ | ||
InMemoryRandomAccessStream stream; | ||
DataWriter writer(stream); | ||
writer.WriteByte(1); | ||
writer.WriteByte(2); | ||
writer.WriteByte(3); | ||
co_await writer.StoreAsync(); | ||
|
||
stream.Seek(0); | ||
DataReader reader(stream); | ||
co_await reader.LoadAsync(3); | ||
co_return reader; | ||
} | ||
|
||
// | ||
// This test illustrates an array_view<T> (non-const) bound to a std::span<T> on a std::array | ||
// | ||
TEST_CASE("array,DataReader,std::span") | ||
{ | ||
auto reader = CreateDataReader({ 1, 2, 3 }).get(); | ||
|
||
std::array<byte, 3> a{}; | ||
std::span<byte> sp(a); | ||
reader.ReadBytes(sp); // FillArray pattern | ||
|
||
REQUIRE(a.size() == 3); | ||
REQUIRE(a[0] == 1); | ||
REQUIRE(a[1] == 2); | ||
REQUIRE(a[2] == 3); | ||
} | ||
|
||
// | ||
// This test illustrates passing a std::array to a method that takes array_view<T> | ||
// | ||
TEST_CASE("array,DataReader,std::span,direct") | ||
{ | ||
auto reader = CreateDataReader({ 1, 2, 3 }).get(); | ||
|
||
std::array<byte, 3> a{}; | ||
reader.ReadBytes(a); // FillArray pattern | ||
|
||
REQUIRE(a.size() == 3); | ||
REQUIRE(a[0] == 1); | ||
REQUIRE(a[1] == 2); | ||
REQUIRE(a[2] == 3); | ||
} | ||
|
||
|
||
TEST_CASE("array_view,span") | ||
{ | ||
{ | ||
int v[] = { 1, 2, 3 }; | ||
std::span<int> s(v); | ||
array_view<int> a = s; | ||
REQUIRE(a.data() == v); | ||
REQUIRE(a.size() == 3); | ||
} | ||
|
||
{ | ||
int v[] = { 1, 2, 3 }; | ||
std::span<int const> s(v); | ||
array_view<int const> a = s; | ||
REQUIRE(a.data() == v); | ||
REQUIRE(a.size() == 3); | ||
} | ||
|
||
{ | ||
int const v[] = { 1, 2, 3 }; | ||
std::span<int const> s(v); | ||
array_view<int const> a = s; | ||
REQUIRE(a.data() == v); | ||
REQUIRE(a.size() == 3); | ||
} | ||
} | ||
|
||
// | ||
// Tests com_array support for span construction. | ||
// | ||
TEST_CASE("com_array,span") | ||
{ | ||
{ | ||
int v[] = { 1, 2, 3 }; | ||
std::span<int> s(v); | ||
com_array<int> a(s); | ||
REQUIRE(a.size() == 3); | ||
REQUIRE(a[0] == 1); | ||
REQUIRE(a[1] == 2); | ||
REQUIRE(a[2] == 3); | ||
} | ||
} | ||
|
||
// | ||
// Tests array_view support for conversion to span | ||
// | ||
TEST_CASE("array_view,span,as") | ||
{ | ||
{ | ||
int v[] = { 1, 2, 3 }; | ||
array_view<int> a = v; | ||
std::span<int> s(a); | ||
REQUIRE(s.data() == v); | ||
REQUIRE(s.size() == 3); | ||
} | ||
|
||
{ | ||
int v[] = { 1, 2, 3 }; | ||
array_view<int const> a = v; | ||
std::span<int const> s(a); | ||
REQUIRE(s.data() == v); | ||
REQUIRE(s.size() == 3); | ||
} | ||
|
||
{ | ||
int const v[] = { 1, 2, 3 }; | ||
array_view<int const> a = v; | ||
std::span<int const> s(a); | ||
REQUIRE(s.data() == v); | ||
REQUIRE(s.size() == 3); | ||
} | ||
} | ||
|
||
// | ||
// Tests com_array support for conversion to span | ||
// | ||
TEST_CASE("com_array,span,as") | ||
{ | ||
{ | ||
int v[] = { 1, 2, 3 }; | ||
com_array<int> a(v); | ||
std::span<int> s(a); | ||
REQUIRE(s.size() == 3); | ||
REQUIRE(s[0] == 1); | ||
REQUIRE(s[1] == 2); | ||
REQUIRE(s[2] == 3); | ||
} | ||
} | ||
|
||
// Verify that class template argument deduction works for array_view. | ||
TEST_CASE("array_view,span,ctad") | ||
{ | ||
#define REQUIRE_DEDUCED_AS(T, ...) \ | ||
static_assert(std::is_same_v<array_view<T>, decltype(array_view(__VA_ARGS__))>) | ||
|
||
uint8_t a[] = {1, 2, 3}; | ||
std::span<uint8_t, 3> sp{ a }; | ||
|
||
REQUIRE_DEDUCED_AS(uint8_t, sp); | ||
|
||
std::span<uint8_t const, 3> csp{ a }; | ||
REQUIRE_DEDUCED_AS(uint8_t const, csp); | ||
|
||
std::span<uint8_t, 3> const cs{ a }; | ||
REQUIRE_DEDUCED_AS(uint8_t const, cs); | ||
|
||
#undef REQUIRE_DEDUCED_AS | ||
} | ||
|
||
// Verify that class template argument deduction works for com_array. | ||
TEST_CASE("com_array,span,ctad") | ||
{ | ||
#define REQUIRE_DEDUCED_AS(T, ...) \ | ||
static_assert(std::is_same_v<com_array<T>, decltype(com_array(__VA_ARGS__))>) | ||
|
||
uint8_t a[] = { 1, 2, 3 }; | ||
|
||
std::span<uint8_t, 3> sp{ a }; | ||
REQUIRE_DEDUCED_AS(uint8_t, sp); | ||
|
||
std::span<uint8_t const, 3> csp{ a }; | ||
REQUIRE_DEDUCED_AS(uint8_t, csp); | ||
|
||
std::span<uint8_t, 3> const cs{ a }; | ||
REQUIRE_DEDUCED_AS(uint8_t, cs); | ||
|
||
#undef REQUIRE_DEDUCED_AS | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters